Show group invitations and responses in private conversation

This commit is contained in:
Torsten Grote
2016-10-18 10:22:33 -02:00
parent 5ffcdc4e46
commit 42175dca7a
12 changed files with 139 additions and 51 deletions

View File

@@ -169,12 +169,18 @@
<!-- Private Group Invitations --> <!-- Private Group Invitations -->
<string name="groups_invitations_title">Group Invitations</string> <string name="groups_invitations_title">Group Invitations</string>
<string name="groups_invitations_invitation_sent">You have invited %1$s to your group "%2$s".</string>
<string name="groups_invitations_invitation_received">%1$s has invited you to join the group "%2$s".</string>
<string name="groups_invitations_joined">Joined Group</string> <string name="groups_invitations_joined">Joined Group</string>
<string name="groups_invitations_declined">Group Invitation Declined</string> <string name="groups_invitations_declined">Group Invitation Declined</string>
<plurals name="groups_invitations_open"> <plurals name="groups_invitations_open">
<item quantity="one">%d open group invitation</item> <item quantity="one">%d open group invitation</item>
<item quantity="other">%d open group invitations</item> <item quantity="other">%d open group invitations</item>
</plurals> </plurals>
<string name="groups_invitations_response_accepted_sent">You accepted the group invitation from %s.</string>
<string name="groups_invitations_response_declined_sent">You declined the group invitation from %s.</string>
<string name="groups_invitations_response_accepted_received">%s accepted your group invitation.</string>
<string name="groups_invitations_response_declined_received">%s declined your group invitation.</string>
<!-- Forums --> <!-- Forums -->
<string name="no_forums">You don\'t have any forums yet.\n\nWhy don\'t you create a new one yourself by tapping the + icon at the top?\n\nYou can also ask your contacts to share forums with you.</string> <string name="no_forums">You don\'t have any forums yet.\n\nWhy don\'t you create a new one yourself by tapping the + icon at the top?\n\nYou can also ask your contacts to share forums with you.</string>

View File

@@ -286,8 +286,9 @@ public class ContactListFragment extends BaseFragment implements EventListener {
updateItem(m.getContactId(), updateItem(m.getContactId(),
ConversationItem.from(getContext(), "", ir)); ConversationItem.from(getContext(), "", ir));
} else if (e instanceof InvitationRequestReceivedEvent) { } else if (e instanceof InvitationRequestReceivedEvent) {
LOG.info("Invitation request received, updating item"); LOG.info("Invitation Request received, update item");
InvitationRequestReceivedEvent m = (InvitationRequestReceivedEvent) e; InvitationRequestReceivedEvent m =
(InvitationRequestReceivedEvent) e;
InvitationRequest ir = m.getRequest(); InvitationRequest ir = m.getRequest();
updateItem(m.getContactId(), updateItem(m.getContactId(),
ConversationItem.from(getContext(), "", ir)); ConversationItem.from(getContext(), "", ir));

View File

@@ -67,6 +67,7 @@ import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.privategroup.invitation.GroupInvitationManager;
import org.briarproject.api.settings.Settings; import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.settings.SettingsManager;
import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sharing.InvitationMessage;
@@ -146,6 +147,8 @@ public class ConversationActivity extends BriarActivity
volatile ForumSharingManager forumSharingManager; volatile ForumSharingManager forumSharingManager;
@Inject @Inject
volatile BlogSharingManager blogSharingManager; volatile BlogSharingManager blogSharingManager;
@Inject
volatile GroupInvitationManager groupInvitationManager;
private volatile GroupId groupId = null; private volatile GroupId groupId = null;
private volatile ContactId contactId = null; private volatile ContactId contactId = null;
@@ -351,10 +354,14 @@ public class ConversationActivity extends BriarActivity
Collection<InvitationMessage> blogInvitations = Collection<InvitationMessage> blogInvitations =
blogSharingManager blogSharingManager
.getInvitationMessages(contactId); .getInvitationMessages(contactId);
Collection<InvitationMessage> groupInvitations =
groupInvitationManager
.getInvitationMessages(contactId);
List<InvitationMessage> invitations = new ArrayList<>( List<InvitationMessage> invitations = new ArrayList<>(
forumInvitations.size() + blogInvitations.size()); forumInvitations.size() + blogInvitations.size());
invitations.addAll(forumInvitations); invitations.addAll(forumInvitations);
invitations.addAll(blogInvitations); invitations.addAll(blogInvitations);
invitations.addAll(groupInvitations);
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Loading messages took " + duration + " ms"); LOG.info("Loading messages took " + duration + " ms");
@@ -398,44 +405,46 @@ public class ConversationActivity extends BriarActivity
Collection<PrivateMessageHeader> headers, Collection<PrivateMessageHeader> headers,
Collection<IntroductionMessage> introductions, Collection<IntroductionMessage> introductions,
Collection<InvitationMessage> invitations) { Collection<InvitationMessage> invitations) {
int size = headers.size() + introductions.size() + invitations.size(); int size =
headers.size() + introductions.size() + invitations.size();
List<ConversationItem> items = new ArrayList<>(size); List<ConversationItem> items = new ArrayList<>(size);
for (PrivateMessageHeader h : headers) {
for (PrivateMessageHeader h : headers) { ConversationItem item = ConversationItem.from(h);
ConversationItem item = ConversationItem.from(h); String body = bodyCache.get(h.getId());
String body = bodyCache.get(h.getId()); if (body == null) loadMessageBody(h.getId());
if (body == null) loadMessageBody(h.getId()); else ((PartialItem) item).setText(body);
else ((PartialItem) item).setText(body); items.add(item);
items.add(item); }
for (IntroductionMessage m : introductions) {
ConversationItem item;
if (m instanceof IntroductionRequest) {
item = ConversationItem
.from(ConversationActivity.this,
contactName,
(IntroductionRequest) m);
} else {
item = ConversationItem
.from(ConversationActivity.this,
contactName,
(IntroductionResponse) m);
} }
for (IntroductionMessage m : introductions) { items.add(item);
ConversationItem item; }
if (m instanceof IntroductionRequest) { for (InvitationMessage i : invitations) {
item = ConversationItem ConversationItem item;
.from(ConversationActivity.this, if (i instanceof InvitationRequest) {
contactName, InvitationRequest r = (InvitationRequest) i;
(IntroductionRequest) m); item = ConversationItem
} else { .from(ConversationActivity.this,
item = ConversationItem contactName, r);
.from(ConversationActivity.this, } else {
contactName, InvitationResponse r = (InvitationResponse) i;
(IntroductionResponse) m); item = ConversationItem
} .from(ConversationActivity.this,
items.add(item); contactName, r);
}
for (InvitationMessage i : invitations) {
if (i instanceof InvitationRequest) {
InvitationRequest r = (InvitationRequest) i;
items.add(ConversationItem
.from(ConversationActivity.this,
contactName, r));
} else if (i instanceof InvitationResponse) {
InvitationResponse r = (InvitationResponse) i;
items.add(ConversationItem
.from(ConversationActivity.this,
contactName, r));
}
} }
items.add(item);
}
return items; return items;
} }
@@ -850,6 +859,9 @@ public class ConversationActivity extends BriarActivity
case BLOG: case BLOG:
respondToBlogRequest(item.getSessionId(), accept); respondToBlogRequest(item.getSessionId(), accept);
break; break;
case GROUP:
respondToGroupRequest(item.getSessionId(), accept);
break;
default: default:
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Unknown Request Type"); "Unknown Request Type");
@@ -889,6 +901,13 @@ public class ConversationActivity extends BriarActivity
loadMessages(); loadMessages();
} }
@DatabaseExecutor
private void respondToGroupRequest(SessionId id, boolean accept)
throws DbException {
groupInvitationManager.respondToInvitation(id, accept);
loadMessages();
}
private void introductionResponseError() { private void introductionResponseError() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(new Runnable() {
@Override @Override

View File

@@ -6,12 +6,15 @@ import android.support.annotation.StringRes;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.contact.ConversationRequestItem.RequestType; import org.briarproject.android.contact.ConversationRequestItem.RequestType;
import org.briarproject.api.blogs.BlogInvitationRequest; import org.briarproject.api.blogs.BlogInvitationRequest;
import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.forum.ForumInvitationRequest; import org.briarproject.api.forum.ForumInvitationRequest;
import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumInvitationResponse;
import org.briarproject.api.introduction.IntroductionRequest; import org.briarproject.api.introduction.IntroductionRequest;
import org.briarproject.api.introduction.IntroductionResponse; import org.briarproject.api.introduction.IntroductionResponse;
import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.privategroup.invitation.GroupInvitationRequest;
import org.briarproject.api.privategroup.invitation.GroupInvitationResponse;
import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sharing.InvitationRequest;
import org.briarproject.api.sharing.InvitationResponse; import org.briarproject.api.sharing.InvitationResponse;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
@@ -22,6 +25,7 @@ import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.BLOG; import static org.briarproject.android.contact.ConversationRequestItem.RequestType.BLOG;
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.FORUM; import static org.briarproject.android.contact.ConversationRequestItem.RequestType.FORUM;
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.GROUP;
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.INTRODUCTION; import static org.briarproject.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
@NotThreadSafe @NotThreadSafe
@@ -145,10 +149,17 @@ abstract class ConversationItem {
text = ctx.getString(R.string.forum_invitation_sent, text = ctx.getString(R.string.forum_invitation_sent,
((ForumInvitationRequest) ir).getForumName(), ((ForumInvitationRequest) ir).getForumName(),
contactName); contactName);
} else { } else if (ir instanceof BlogInvitationRequest) {
text = ctx.getString(R.string.blogs_sharing_invitation_sent, text = ctx.getString(R.string.blogs_sharing_invitation_sent,
((BlogInvitationRequest) ir).getBlogAuthorName(), ((BlogInvitationRequest) ir).getBlogAuthorName(),
contactName); contactName);
} else if (ir instanceof GroupInvitationRequest) {
text = ctx.getString(
R.string.groups_invitations_invitation_sent,
contactName,
((GroupInvitationRequest) ir).getGroupName());
} else {
throw new IllegalArgumentException("Unknown InvitationRequest");
} }
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(), return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
text, ir.getMessage(), ir.getTimestamp(), ir.isSent(), text, ir.getMessage(), ir.getTimestamp(), ir.isSent(),
@@ -161,11 +172,19 @@ abstract class ConversationItem {
contactName, contactName,
((ForumInvitationRequest) ir).getForumName()); ((ForumInvitationRequest) ir).getForumName());
type = FORUM; type = FORUM;
} else { } else if (ir instanceof BlogInvitationRequest) {
text = ctx.getString(R.string.blogs_sharing_invitation_received, text = ctx.getString(R.string.blogs_sharing_invitation_received,
contactName, contactName,
((BlogInvitationRequest) ir).getBlogAuthorName()); ((BlogInvitationRequest) ir).getBlogAuthorName());
type = BLOG; type = BLOG;
} else if (ir instanceof GroupInvitationRequest) {
text = ctx.getString(
R.string.groups_invitations_invitation_received,
contactName,
((GroupInvitationRequest) ir).getGroupName());
type = GROUP;
} else {
throw new IllegalArgumentException("Unknown InvitationRequest");
} }
if (!ir.isAvailable()) { if (!ir.isAvailable()) {
return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(), return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(),
@@ -185,14 +204,24 @@ abstract class ConversationItem {
if (ir.wasAccepted()) { if (ir.wasAccepted()) {
if (ir instanceof ForumInvitationResponse) { if (ir instanceof ForumInvitationResponse) {
res = R.string.forum_invitation_response_accepted_sent; res = R.string.forum_invitation_response_accepted_sent;
} else { } else if (ir instanceof BlogInvitationResponse) {
res = R.string.blogs_sharing_response_accepted_sent; res = R.string.blogs_sharing_response_accepted_sent;
} else if (ir instanceof GroupInvitationResponse) {
res = R.string.groups_invitations_response_accepted_sent;
} else {
throw new IllegalArgumentException(
"Unknown InvitationResponse");
} }
} else { } else {
if (ir instanceof ForumInvitationResponse) { if (ir instanceof ForumInvitationResponse) {
res = R.string.forum_invitation_response_declined_sent; res = R.string.forum_invitation_response_declined_sent;
} else { } else if (ir instanceof BlogInvitationResponse) {
res = R.string.blogs_sharing_response_declined_sent; res = R.string.blogs_sharing_response_declined_sent;
} else if (ir instanceof GroupInvitationResponse) {
res = R.string.groups_invitations_response_declined_sent;
} else {
throw new IllegalArgumentException(
"Unknown InvitationResponse");
} }
} }
String text = ctx.getString(res, contactName); String text = ctx.getString(res, contactName);
@@ -202,14 +231,24 @@ abstract class ConversationItem {
if (ir.wasAccepted()) { if (ir.wasAccepted()) {
if (ir instanceof ForumInvitationResponse) { if (ir instanceof ForumInvitationResponse) {
res = R.string.forum_invitation_response_accepted_received; res = R.string.forum_invitation_response_accepted_received;
} else { } else if (ir instanceof BlogInvitationResponse) {
res = R.string.blogs_sharing_response_accepted_received; res = R.string.blogs_sharing_response_accepted_received;
} else if (ir instanceof GroupInvitationResponse) {
res = R.string.groups_invitations_response_accepted_received;
} else {
throw new IllegalArgumentException(
"Unknown InvitationResponse");
} }
} else { } else {
if (ir instanceof ForumInvitationResponse) { if (ir instanceof ForumInvitationResponse) {
res = R.string.forum_invitation_response_declined_received; res = R.string.forum_invitation_response_declined_received;
} else { } else if (ir instanceof BlogInvitationResponse) {
res = R.string.blogs_sharing_response_declined_received; res = R.string.blogs_sharing_response_declined_received;
} else if (ir instanceof GroupInvitationResponse) {
res = R.string.groups_invitations_response_declined_received;
} else {
throw new IllegalArgumentException(
"Unknown InvitationResponse");
} }
} }
String text = ctx.getString(res, contactName); String text = ctx.getString(res, contactName);

View File

@@ -12,7 +12,7 @@ import javax.annotation.concurrent.NotThreadSafe;
@NotNullByDefault @NotNullByDefault
class ConversationRequestItem extends ConversationNoticeInItem { class ConversationRequestItem extends ConversationNoticeInItem {
enum RequestType { INTRODUCTION, FORUM, BLOG }; enum RequestType { INTRODUCTION, FORUM, BLOG, GROUP };
private final RequestType requestType; private final RequestType requestType;
private final SessionId sessionId; private final SessionId sessionId;
private boolean answered; private boolean answered;

View File

@@ -1,21 +1,26 @@
package org.briarproject.api.clients; package org.briarproject.api.clients;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public abstract class BaseMessage { public abstract class BaseMessage {
private final Message message; private final Message message;
@Nullable
private final MessageId parent; private final MessageId parent;
public BaseMessage(@NotNull Message message, @Nullable MessageId parent) { public BaseMessage(Message message, @Nullable MessageId parent) {
this.message = message; this.message = message;
this.parent = parent; this.parent = parent;
} }
@NotNull
public Message getMessage() { public Message getMessage() {
return message; return message;
} }

View File

@@ -2,17 +2,22 @@ package org.briarproject.api.privategroup;
import org.briarproject.api.clients.BaseMessage; import org.briarproject.api.clients.BaseMessage;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class GroupMessage extends BaseMessage { public class GroupMessage extends BaseMessage {
private final Author author; private final Author author;
public GroupMessage(@NotNull Message message, @Nullable MessageId parent, public GroupMessage(Message message, @Nullable MessageId parent,
@NotNull Author author) { Author author) {
super(message, parent); super(message, parent);
this.author = author; this.author = author;
} }

View File

@@ -1,9 +1,14 @@
package org.briarproject.api.privategroup.invitation; package org.briarproject.api.privategroup.invitation;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sharing.InvitationItem; import org.briarproject.api.sharing.InvitationItem;
import org.briarproject.api.sharing.Shareable; import org.briarproject.api.sharing.Shareable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class GroupInvitationItem extends InvitationItem { public class GroupInvitationItem extends InvitationItem {
private final Contact creator; private final Contact creator;

View File

@@ -8,9 +8,10 @@ import org.briarproject.api.sharing.InvitationRequest;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe @Immutable
@NotNullByDefault @NotNullByDefault
public class GroupInvitationRequest extends InvitationRequest { public class GroupInvitationRequest extends InvitationRequest {

View File

@@ -9,9 +9,10 @@ import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe @Immutable
@NotNullByDefault @NotNullByDefault
public class GroupInvitationResponse extends InvitationResponse { public class GroupInvitationResponse extends InvitationResponse {

View File

@@ -3,9 +3,10 @@ package org.briarproject.api.sharing;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe @Immutable
@NotNullByDefault @NotNullByDefault
public abstract class InvitationItem { public abstract class InvitationItem {

View File

@@ -1,9 +1,14 @@
package org.briarproject.api.sharing; package org.briarproject.api.sharing;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.nullsafety.NotNullByDefault;
import java.util.Collection; import java.util.Collection;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class SharingInvitationItem extends InvitationItem { public class SharingInvitationItem extends InvitationItem {
private final Collection<Contact> newSharers; private final Collection<Contact> newSharers;