From a33d7d1663da9ae3c30a75e79611873ffb3bcc63 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 17 Oct 2016 10:35:29 -0200 Subject: [PATCH 01/10] Add a stub for a GroupInvitationManager --- .../ForumSharingIntegrationTest.java | 6 +- .../api/privategroup/PrivateGroup.java | 3 +- .../invitation/GroupInvitationConstants.java | 8 + .../invitation/GroupInvitationItem.java | 22 +++ .../invitation/GroupInvitationManager.java | 48 ++++++ .../invitation/GroupInvitationRequest.java | 38 +++++ .../invitation/GroupInvitationResponse.java | 39 +++++ .../api/sharing/InvitationItem.java | 26 ++-- .../briarproject/api/sharing/Shareable.java | 3 + .../api/sharing/SharingInvitationItem.java | 22 +++ .../api/sharing/SharingManager.java | 2 +- .../privategroup/PrivateGroupModule.java | 28 +++- .../GroupInvitationManagerImpl.java | 141 ++++++++++++++++++ .../sharing/SharingManagerImpl.java | 10 +- 14 files changed, 372 insertions(+), 24 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java create mode 100644 briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java create mode 100644 briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java index ae3e770a4..306cc25dc 100644 --- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java +++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java @@ -34,7 +34,7 @@ import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.lifecycle.LifecycleManager; -import org.briarproject.api.sharing.InvitationItem; +import org.briarproject.api.sharing.SharingInvitationItem; import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.SyncSession; @@ -762,7 +762,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase { "Sharer2 to Invitee"); // make sure we now have two invitations to the same forum available - Collection forums = + Collection forums = forumSharingManager1.getInvitations(); assertEquals(1, forums.size()); assertEquals(2, forums.iterator().next().getNewSharers().size()); @@ -986,7 +986,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase { try { eventWaiter.assertEquals(1, forumSharingManager1.getInvitations().size()); - InvitationItem invitation = + SharingInvitationItem invitation = forumSharingManager1.getInvitations().iterator() .next(); eventWaiter.assertEquals(f, invitation.getShareable()); diff --git a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java index 310611361..9b57d9991 100644 --- a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java +++ b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java @@ -3,6 +3,7 @@ package org.briarproject.api.privategroup; import org.briarproject.api.clients.NamedGroup; import org.briarproject.api.identity.Author; import org.briarproject.api.nullsafety.NotNullByDefault; +import org.briarproject.api.sharing.Shareable; import org.briarproject.api.sync.Group; import org.jetbrains.annotations.NotNull; @@ -10,7 +11,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class PrivateGroup extends NamedGroup { +public class PrivateGroup extends NamedGroup implements Shareable { private final Author author; diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java new file mode 100644 index 000000000..a22272b22 --- /dev/null +++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java @@ -0,0 +1,8 @@ +package org.briarproject.api.privategroup.invitation; + +public interface GroupInvitationConstants { + + // Group Metadata Keys + String CONTACT_ID = "contactId"; + +} diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java new file mode 100644 index 000000000..c7f350be4 --- /dev/null +++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java @@ -0,0 +1,22 @@ +package org.briarproject.api.privategroup.invitation; + +import org.briarproject.api.contact.Contact; +import org.briarproject.api.sharing.InvitationItem; +import org.briarproject.api.sharing.Shareable; + +public class GroupInvitationItem extends InvitationItem { + + private final Contact creator; + + public GroupInvitationItem(Shareable shareable, boolean subscribed, + Contact creator) { + super(shareable, subscribed); + + this.creator = creator; + } + + public Contact getCreator() { + return creator; + } + +} diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java new file mode 100644 index 000000000..a5ca33dae --- /dev/null +++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java @@ -0,0 +1,48 @@ +package org.briarproject.api.privategroup.invitation; + +import org.briarproject.api.clients.MessageTracker; +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.privategroup.PrivateGroup; +import org.briarproject.api.sharing.InvitationMessage; +import org.briarproject.api.sync.ClientId; +import org.briarproject.api.sync.GroupId; + +import java.util.Collection; + +public interface GroupInvitationManager extends MessageTracker { + + /** Returns the unique ID of the private group invitation client. */ + ClientId getClientId(); + + /** + * Sends an invitation to share the given forum with the given contact + * and sends an optional message along with it. + */ + void sendInvitation(GroupId groupId, ContactId contactId, + String message) throws DbException; + + /** + * Responds to a pending private group invitation + */ + void respondToInvitation(PrivateGroup g, Contact c, boolean accept) + throws DbException; + + /** + * Responds to a pending private group invitation + */ + void respondToInvitation(SessionId id, boolean accept) throws DbException; + + /** + * Returns all private group invitation messages related to the contact + * identified by contactId. + */ + Collection getInvitationMessages( + ContactId contactId) throws DbException; + + /** Returns all private groups to which the user has been invited. */ + Collection getInvitations() throws DbException; + +} diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java new file mode 100644 index 000000000..3c9b25760 --- /dev/null +++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java @@ -0,0 +1,38 @@ +package org.briarproject.api.privategroup.invitation; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.identity.Author; +import org.briarproject.api.nullsafety.NotNullByDefault; +import org.briarproject.api.sharing.InvitationRequest; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; + +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +@NotNullByDefault +public class GroupInvitationRequest extends InvitationRequest { + + private final String groupName; + private final Author creator; + + public GroupInvitationRequest(MessageId id, SessionId sessionId, + GroupId groupId, Author creator, ContactId contactId, + String groupName, String message, boolean available, long time, + boolean local, boolean sent, boolean seen, boolean read) { + super(id, sessionId, groupId, contactId, message, available, time, + local, sent, seen, read); + this.groupName = groupName; + this.creator = creator; + } + + public String getGroupName() { + return groupName; + } + + public Author getCreator() { + return creator; + } + +} diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java new file mode 100644 index 000000000..554e731bc --- /dev/null +++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java @@ -0,0 +1,39 @@ +package org.briarproject.api.privategroup.invitation; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.identity.Author; +import org.briarproject.api.nullsafety.NotNullByDefault; +import org.briarproject.api.sharing.InvitationResponse; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +@NotNullByDefault +public class GroupInvitationResponse extends InvitationResponse { + + private final String groupName; + private final Author creator; + + public GroupInvitationResponse(MessageId id, SessionId sessionId, + GroupId groupId, String groupName, Author creator, + ContactId contactId, boolean accept, long time, boolean local, + boolean sent, boolean seen, boolean read) { + super(id, sessionId, groupId, contactId, accept, time, local, sent, + seen, read); + this.groupName = groupName; + this.creator = creator; + } + + public String getGroupName() { + return groupName; + } + + public Author getCreator() { + return creator; + } + +} diff --git a/briar-api/src/org/briarproject/api/sharing/InvitationItem.java b/briar-api/src/org/briarproject/api/sharing/InvitationItem.java index bc180ea13..a813982b1 100644 --- a/briar-api/src/org/briarproject/api/sharing/InvitationItem.java +++ b/briar-api/src/org/briarproject/api/sharing/InvitationItem.java @@ -1,32 +1,36 @@ package org.briarproject.api.sharing; -import org.briarproject.api.contact.Contact; +import org.briarproject.api.nullsafety.NotNullByDefault; +import org.briarproject.api.sync.GroupId; -import java.util.Collection; +import javax.annotation.concurrent.ThreadSafe; -public class InvitationItem { +@ThreadSafe +@NotNullByDefault +public abstract class InvitationItem { private final Shareable shareable; private final boolean subscribed; - private final Collection newSharers; - - public InvitationItem(Shareable shareable, boolean subscribed, - Collection newSharers) { + public InvitationItem(Shareable shareable, boolean subscribed) { this.shareable = shareable; this.subscribed = subscribed; - this.newSharers = newSharers; } public Shareable getShareable() { return shareable; } + public GroupId getId() { + return shareable.getId(); + } + + public String getName() { + return shareable.getName(); + } + public boolean isSubscribed() { return subscribed; } - public Collection getNewSharers() { - return newSharers; - } } diff --git a/briar-api/src/org/briarproject/api/sharing/Shareable.java b/briar-api/src/org/briarproject/api/sharing/Shareable.java index 13c11fdee..144b06dde 100644 --- a/briar-api/src/org/briarproject/api/sharing/Shareable.java +++ b/briar-api/src/org/briarproject/api/sharing/Shareable.java @@ -8,4 +8,7 @@ public interface Shareable { GroupId getId(); Group getGroup(); + + String getName(); + } diff --git a/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java b/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java new file mode 100644 index 000000000..8993f2320 --- /dev/null +++ b/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java @@ -0,0 +1,22 @@ +package org.briarproject.api.sharing; + +import org.briarproject.api.contact.Contact; + +import java.util.Collection; + +public class SharingInvitationItem extends InvitationItem { + + private final Collection newSharers; + + public SharingInvitationItem(Shareable shareable, boolean subscribed, + Collection newSharers) { + super(shareable, subscribed); + + this.newSharers = newSharers; + } + + public Collection getNewSharers() { + return newSharers; + } + +} diff --git a/briar-api/src/org/briarproject/api/sharing/SharingManager.java b/briar-api/src/org/briarproject/api/sharing/SharingManager.java index b4613cd94..3e37191dd 100644 --- a/briar-api/src/org/briarproject/api/sharing/SharingManager.java +++ b/briar-api/src/org/briarproject/api/sharing/SharingManager.java @@ -38,7 +38,7 @@ public interface SharingManager extends MessageTracker { /** * Returns all invitations to groups. */ - Collection getInvitations() throws DbException; + Collection getInvitations() throws DbException; /** * Returns all contacts who are sharing the given group with us. diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java index 562b95c30..570f697a6 100644 --- a/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java +++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java @@ -1,17 +1,19 @@ package org.briarproject.privategroup; import org.briarproject.api.clients.ClientHelper; +import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.data.MetadataEncoder; import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.ConversationManager; import org.briarproject.api.privategroup.GroupMessageFactory; import org.briarproject.api.privategroup.PrivateGroupFactory; import org.briarproject.api.privategroup.PrivateGroupManager; -import org.briarproject.api.sync.GroupFactory; +import org.briarproject.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.api.sync.ValidationManager; import org.briarproject.api.system.Clock; - -import java.security.SecureRandom; +import org.briarproject.privategroup.invitation.GroupInvitationManagerImpl; import javax.inject.Inject; import javax.inject.Singleton; @@ -25,6 +27,8 @@ public class PrivateGroupModule { public static class EagerSingletons { @Inject GroupMessageValidator groupMessageValidator; + @Inject + GroupInvitationManager groupInvitationManager; } @Provides @@ -65,4 +69,22 @@ public class PrivateGroupModule { return validator; } + @Provides + @Singleton + GroupInvitationManager provideGroupInvitationManager( + LifecycleManager lifecycleManager, ContactManager contactManager, + GroupInvitationManagerImpl groupInvitationManager, + ConversationManager conversationManager, + ValidationManager validationManager) { + + validationManager.registerIncomingMessageHook( + groupInvitationManager.getClientId(), groupInvitationManager); + lifecycleManager.registerClient(groupInvitationManager); + contactManager.registerAddContactHook(groupInvitationManager); + contactManager.registerRemoveContactHook(groupInvitationManager); + conversationManager.registerConversationClient(groupInvitationManager); + + return groupInvitationManager; + } + } diff --git a/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java new file mode 100644 index 000000000..12477ab20 --- /dev/null +++ b/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java @@ -0,0 +1,141 @@ +package org.briarproject.privategroup.invitation; + +import org.briarproject.api.FormatException; +import org.briarproject.api.clients.Client; +import org.briarproject.api.clients.ClientHelper; +import org.briarproject.api.clients.ContactGroupFactory; +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.data.BdfList; +import org.briarproject.api.data.MetadataParser; +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.Transaction; +import org.briarproject.api.messaging.ConversationManager; +import org.briarproject.api.privategroup.PrivateGroup; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; +import org.briarproject.api.privategroup.invitation.GroupInvitationManager; +import org.briarproject.api.sharing.InvitationMessage; +import org.briarproject.api.sync.ClientId; +import org.briarproject.api.sync.Group; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.Message; +import org.briarproject.clients.ConversationClientImpl; +import org.briarproject.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.inject.Inject; + +import static org.briarproject.api.privategroup.invitation.GroupInvitationConstants.CONTACT_ID; + +public class GroupInvitationManagerImpl extends ConversationClientImpl + implements GroupInvitationManager, Client, + ContactManager.AddContactHook, ContactManager.RemoveContactHook, + ConversationManager.ConversationClient { + + private static final ClientId CLIENT_ID = + new ClientId(StringUtils.fromHexString( + "B55231ABFC4A10666CD93D649B1D7F4F" + + "016E65B87BB4C04F4E35613713DBCD13")); + + private final ContactGroupFactory contactGroupFactory; + private final Group localGroup; + + @Inject + protected GroupInvitationManagerImpl(DatabaseComponent db, + ClientHelper clientHelper, MetadataParser metadataParser, + ContactGroupFactory contactGroupFactory) { + super(db, clientHelper, metadataParser); + this.contactGroupFactory = contactGroupFactory; + localGroup = contactGroupFactory.createLocalGroup(getClientId()); + } + + @Override + public ClientId getClientId() { + return CLIENT_ID; + } + + @Override + public void createLocalState(Transaction txn) throws DbException { + db.addGroup(txn, localGroup); + // Ensure we've set things up for any pre-existing contacts + for (Contact c : db.getContacts(txn)) addingContact(txn, c); + } + + @Override + public void addingContact(Transaction txn, Contact c) throws DbException { + try { + // Create a group to share with the contact + Group g = getContactGroup(c); + // Return if we've already set things up for this contact + if (db.containsGroup(txn, g.getId())) return; + // Store the group and share it with the contact + db.addGroup(txn, g); + db.setVisibleToContact(txn, c.getId(), g.getId(), true); + // Attach the contact ID to the group + BdfDictionary meta = new BdfDictionary(); + meta.put(CONTACT_ID, c.getId().getInt()); + clientHelper.mergeGroupMetadata(txn, g.getId(), meta); + } catch (FormatException e) { + throw new DbException(e); + } + } + + @Override + public void removingContact(Transaction txn, Contact c) throws DbException { + // remove the contact group (all messages will be removed with it) + db.removeGroup(txn, getContactGroup(c)); + } + + @Override + protected Group getContactGroup(Contact c) { + return contactGroupFactory.createContactGroup(getClientId(), c); + } + + @Override + protected boolean incomingMessage(Transaction txn, Message m, BdfList body, + BdfDictionary meta) throws DbException, FormatException { + return false; + } + + @Override + public void sendInvitation(GroupId groupId, ContactId contactId, + String message) throws DbException { + + } + + @Override + public void respondToInvitation(PrivateGroup g, Contact c, boolean accept) + throws DbException { + + } + + @Override + public void respondToInvitation(SessionId id, boolean accept) + throws DbException { + + } + + @Override + public Collection getInvitationMessages( + ContactId contactId) throws DbException { + Collection invitations = + new ArrayList(); + + return invitations; + } + + @Override + public Collection getInvitations() throws DbException { + Collection invitations = + new ArrayList(); + + return invitations; + } + +} diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java index a7c90d0a7..dd06fc2c4 100644 --- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java @@ -25,7 +25,7 @@ import org.briarproject.api.event.Event; import org.briarproject.api.event.InvitationRequestReceivedEvent; import org.briarproject.api.event.InvitationResponseReceivedEvent; import org.briarproject.api.identity.LocalAuthor; -import org.briarproject.api.sharing.InvitationItem; +import org.briarproject.api.sharing.SharingInvitationItem; import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sharing.Shareable; import org.briarproject.api.sharing.SharingManager; @@ -418,8 +418,8 @@ abstract class SharingManagerImpl getInvitations() throws DbException { - List invitations = new ArrayList(); + public Collection getInvitations() throws DbException { + List invitations = new ArrayList(); Transaction txn = db.startTransaction(true); try { Set shareables = new HashSet(); @@ -445,8 +445,8 @@ abstract class SharingManagerImpl newS = newSharers.get(s.getId()); boolean subscribed = db.containsGroup(txn, s.getId()); - InvitationItem invitation = - new InvitationItem(s, subscribed, newS); + SharingInvitationItem invitation = + new SharingInvitationItem(s, subscribed, newS); invitations.add(invitation); } txn.setComplete(); From 02a39f5694669f5da1ea0a38dbe74e8802d601eb Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 17 Oct 2016 13:47:30 -0200 Subject: [PATCH 02/10] Refactor events based on InvitationRequestReceivedEvent --- .../briarproject/BlogSharingIntegrationTest.java | 4 ++-- .../briarproject/ForumSharingIntegrationTest.java | 4 ++-- .../api/event/BlogInvitationReceivedEvent.java | 10 ++-------- .../api/event/ForumInvitationReceivedEvent.java | 11 ++--------- .../api/event/GroupInvitationReceivedEvent.java | 15 +++++++++++++++ .../api/event/InvitationRequestReceivedEvent.java | 12 ++++++++++-- 6 files changed, 33 insertions(+), 23 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/event/GroupInvitationReceivedEvent.java diff --git a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java index bca45b25f..2cc0340bc 100644 --- a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java +++ b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java @@ -547,7 +547,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest { BlogInvitationReceivedEvent event = (BlogInvitationReceivedEvent) e; eventWaiter.assertEquals(contactId1, event.getContactId()); - Blog b = event.getBlog(); + Blog b = event.getShareable(); try { Contact c = contactManager0.getContact(contactId1); blogSharingManager0.respondToInvitation(b, c, true); @@ -589,7 +589,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest { (BlogInvitationReceivedEvent) e; requestReceived = true; if (!answer) return; - Blog b = event.getBlog(); + Blog b = event.getShareable(); try { eventWaiter.assertEquals(1, blogSharingManager1.getInvitations().size()); diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java index 306cc25dc..6d2184a6a 100644 --- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java +++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java @@ -939,7 +939,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase { (ForumInvitationReceivedEvent) e; eventWaiter.assertEquals(contactId1, event.getContactId()); requestReceived = true; - Forum f = event.getForum(); + Forum f = event.getShareable(); try { Contact c = contactManager0.getContact(contactId1); forumSharingManager0.respondToInvitation(f, c, true); @@ -982,7 +982,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase { (ForumInvitationReceivedEvent) e; requestReceived = true; if (!answer) return; - Forum f = event.getForum(); + Forum f = event.getShareable(); try { eventWaiter.assertEquals(1, forumSharingManager1.getInvitations().size()); diff --git a/briar-api/src/org/briarproject/api/event/BlogInvitationReceivedEvent.java b/briar-api/src/org/briarproject/api/event/BlogInvitationReceivedEvent.java index 26a2ae097..2089e6c5d 100644 --- a/briar-api/src/org/briarproject/api/event/BlogInvitationReceivedEvent.java +++ b/briar-api/src/org/briarproject/api/event/BlogInvitationReceivedEvent.java @@ -5,17 +5,11 @@ import org.briarproject.api.contact.ContactId; import org.briarproject.api.sharing.InvitationRequest; public class BlogInvitationReceivedEvent extends - InvitationRequestReceivedEvent { - - private final Blog blog; + InvitationRequestReceivedEvent { public BlogInvitationReceivedEvent(Blog blog, ContactId contactId, InvitationRequest request) { - super(contactId, request); - this.blog = blog; + super(blog, contactId, request); } - public Blog getBlog() { - return blog; - } } diff --git a/briar-api/src/org/briarproject/api/event/ForumInvitationReceivedEvent.java b/briar-api/src/org/briarproject/api/event/ForumInvitationReceivedEvent.java index 3077f9160..416979d2e 100644 --- a/briar-api/src/org/briarproject/api/event/ForumInvitationReceivedEvent.java +++ b/briar-api/src/org/briarproject/api/event/ForumInvitationReceivedEvent.java @@ -5,18 +5,11 @@ import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.ForumInvitationRequest; public class ForumInvitationReceivedEvent extends - InvitationRequestReceivedEvent { - - private final Forum forum; + InvitationRequestReceivedEvent { public ForumInvitationReceivedEvent(Forum forum, ContactId contactId, ForumInvitationRequest request) { - super(contactId, request); - this.forum = forum; - } - - public Forum getForum() { - return forum; + super(forum, contactId, request); } } diff --git a/briar-api/src/org/briarproject/api/event/GroupInvitationReceivedEvent.java b/briar-api/src/org/briarproject/api/event/GroupInvitationReceivedEvent.java new file mode 100644 index 000000000..f42b8886f --- /dev/null +++ b/briar-api/src/org/briarproject/api/event/GroupInvitationReceivedEvent.java @@ -0,0 +1,15 @@ +package org.briarproject.api.event; + +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.privategroup.PrivateGroup; + +public class GroupInvitationReceivedEvent extends + InvitationRequestReceivedEvent { + + public GroupInvitationReceivedEvent(PrivateGroup group, ContactId contactId, + ForumInvitationRequest request) { + super(group, contactId, request); + } + +} diff --git a/briar-api/src/org/briarproject/api/event/InvitationRequestReceivedEvent.java b/briar-api/src/org/briarproject/api/event/InvitationRequestReceivedEvent.java index 184a88f53..f9bcfe1a5 100644 --- a/briar-api/src/org/briarproject/api/event/InvitationRequestReceivedEvent.java +++ b/briar-api/src/org/briarproject/api/event/InvitationRequestReceivedEvent.java @@ -2,14 +2,18 @@ package org.briarproject.api.event; import org.briarproject.api.contact.ContactId; import org.briarproject.api.sharing.InvitationRequest; +import org.briarproject.api.sharing.Shareable; -public abstract class InvitationRequestReceivedEvent extends Event { +public abstract class InvitationRequestReceivedEvent + extends Event { + private final S shareable; private final ContactId contactId; private final InvitationRequest request; - InvitationRequestReceivedEvent(ContactId contactId, + InvitationRequestReceivedEvent(S shareable, ContactId contactId, InvitationRequest request) { + this.shareable = shareable; this.contactId = contactId; this.request = request; } @@ -21,4 +25,8 @@ public abstract class InvitationRequestReceivedEvent extends Event { public InvitationRequest getRequest() { return request; } + + public S getShareable() { + return shareable; + } } From a92f7e1c9f97ffca4f105fae2a50a67faace6860 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 14 Oct 2016 17:29:46 -0300 Subject: [PATCH 03/10] Controllerize invitation activities --- .../briarproject/android/ActivityModule.java | 20 +++ .../sharing/BlogInvitationAdapter.java | 40 ------ .../sharing/ForumInvitationAdapter.java | 35 ------ .../android/sharing/InvitationAdapter.java | 102 ++++----------- .../android/sharing/InvitationViewHolder.java | 69 +++++++++++ .../android/sharing/InvitationsActivity.java | 86 ++++++++----- .../sharing/InvitationsBlogActivity.java | 99 ++------------- .../sharing/InvitationsBlogController.java | 7 ++ .../InvitationsBlogControllerImpl.java | 82 +++++++++++++ .../sharing/InvitationsController.java | 25 ++++ .../sharing/InvitationsControllerImpl.java | 116 ++++++++++++++++++ .../sharing/InvitationsForumActivity.java | 99 ++------------- .../sharing/InvitationsForumController.java | 7 ++ .../InvitationsForumControllerImpl.java | 83 +++++++++++++ .../sharing/SharingInvitationAdapter.java | 29 +++++ .../sharing/SharingInvitationViewHolder.java | 35 ++++++ 16 files changed, 568 insertions(+), 366 deletions(-) delete mode 100644 briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java delete mode 100644 briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationViewHolder.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsBlogController.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsBlogControllerImpl.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsController.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsControllerImpl.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsForumController.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsForumControllerImpl.java create mode 100644 briar-android/src/org/briarproject/android/sharing/SharingInvitationAdapter.java create mode 100644 briar-android/src/org/briarproject/android/sharing/SharingInvitationViewHolder.java diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 69505d32f..c5a1b275d 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -27,6 +27,10 @@ import org.briarproject.android.privategroup.creation.CreateGroupController; import org.briarproject.android.privategroup.creation.CreateGroupControllerImpl; import org.briarproject.android.privategroup.list.GroupListController; import org.briarproject.android.privategroup.list.GroupListControllerImpl; +import org.briarproject.android.sharing.InvitationsBlogController; +import org.briarproject.android.sharing.InvitationsBlogControllerImpl; +import org.briarproject.android.sharing.InvitationsForumController; +import org.briarproject.android.sharing.InvitationsForumControllerImpl; import dagger.Module; import dagger.Provides; @@ -125,6 +129,22 @@ public class ActivityModule { return forumController; } + @ActivityScope + @Provides + protected InvitationsForumController provideInvitationsForumController( + InvitationsForumControllerImpl invitationsForumController) { + activity.addLifecycleController(invitationsForumController); + return invitationsForumController; + } + + @ActivityScope + @Provides + protected InvitationsBlogController provideInvitationsBlogController( + InvitationsBlogControllerImpl invitationsBlogController) { + activity.addLifecycleController(invitationsBlogController); + return invitationsBlogController; + } + @ActivityScope @Provides BlogController provideBlogController(BlogControllerImpl blogController) { diff --git a/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java deleted file mode 100644 index 7b0e7dfa6..000000000 --- a/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.briarproject.android.sharing; - -import android.content.Context; - -import org.briarproject.R; -import org.briarproject.api.blogs.Blog; -import org.briarproject.api.sharing.InvitationItem; - -class BlogInvitationAdapter extends InvitationAdapter { - - BlogInvitationAdapter(Context ctx, AvailableForumClickListener listener) { - super(ctx, listener); - } - - @Override - public void onBindViewHolder(InvitationsViewHolder ui, int position) { - super.onBindViewHolder(ui, position); - InvitationItem item = getItemAt(position); - if (item == null) return; - - Blog blog = (Blog) item.getShareable(); - - ui.avatar.setAuthorAvatar(blog.getAuthor()); - - ui.name.setText(ctx.getString(R.string.blogs_personal_blog, - blog.getAuthor().getName())); - - if (item.isSubscribed()) { - ui.subscribed.setText(ctx.getString(R.string.blogs_sharing_exists)); - } - } - - @Override - public int compare(InvitationItem o1, InvitationItem o2) { - return String.CASE_INSENSITIVE_ORDER - .compare(((Blog) o1.getShareable()).getAuthor().getName(), - ((Blog) o2.getShareable()).getAuthor().getName()); - } - -} diff --git a/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java deleted file mode 100644 index cfe914a9c..000000000 --- a/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.briarproject.android.sharing; - -import android.content.Context; - -import org.briarproject.api.forum.Forum; -import org.briarproject.api.sharing.InvitationItem; - -class ForumInvitationAdapter extends InvitationAdapter { - - ForumInvitationAdapter(Context ctx, AvailableForumClickListener listener) { - super(ctx, listener); - } - - @Override - public void onBindViewHolder(InvitationsViewHolder ui, int position) { - super.onBindViewHolder(ui, position); - InvitationItem item = getItemAt(position); - if (item == null) return; - - Forum forum = (Forum) item.getShareable(); - - ui.avatar.setText(forum.getName().substring(0, 1)); - ui.avatar.setBackgroundBytes(item.getShareable().getId().getBytes()); - - ui.name.setText(forum.getName()); - } - - @Override - public int compare(InvitationItem o1, InvitationItem o2) { - return String.CASE_INSENSITIVE_ORDER - .compare(((Forum) o1.getShareable()).getName(), - ((Forum) o2.getShareable()).getName()); - } - -} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java index db35fd55b..5afd24c07 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java @@ -1,111 +1,51 @@ package org.briarproject.android.sharing; import android.content.Context; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.util.BriarAdapter; -import org.briarproject.android.view.TextAvatarView; -import org.briarproject.api.contact.Contact; import org.briarproject.api.sharing.InvitationItem; -import org.briarproject.util.StringUtils; -import java.util.ArrayList; -import java.util.Collection; +public abstract class InvitationAdapter> + extends BriarAdapter { -import static android.view.View.GONE; -import static android.view.View.VISIBLE; + private final InvitationClickListener listener; -abstract class InvitationAdapter extends - BriarAdapter { - - private final AvailableForumClickListener listener; - - InvitationAdapter(Context ctx, AvailableForumClickListener listener) { - super(ctx, InvitationItem.class); + public InvitationAdapter(Context ctx, Class c, + InvitationClickListener listener) { + super(ctx, c); this.listener = listener; } - @Override - public InvitationsViewHolder onCreateViewHolder(ViewGroup parent, - int viewType) { - - View v = LayoutInflater.from(ctx) - .inflate(R.layout.list_item_invitations, parent, false); - return new InvitationsViewHolder(v); + protected View getView(ViewGroup parent) { + return LayoutInflater.from(ctx) + .inflate(R.layout.list_item_invitations, parent, false); } @Override - public void onBindViewHolder(InvitationsViewHolder ui, int position) { - final InvitationItem item = getItemAt(position); + public void onBindViewHolder(VH ui, int position) { + final I item = getItemAt(position); if (item == null) return; - - Collection names = new ArrayList<>(); - for (Contact c : item.getNewSharers()) - names.add(c.getAuthor().getName()); - ui.sharedBy.setText(ctx.getString(R.string.shared_by_format, - StringUtils.join(names, ", "))); - - if (item.isSubscribed()) { - ui.subscribed.setVisibility(VISIBLE); - } else { - ui.subscribed.setVisibility(GONE); - } - - ui.accept.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onItemClick(item, true); - } - }); - ui.decline.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onItemClick(item, false); - } - }); + ui.onBind(item, listener); } @Override - public boolean areContentsTheSame(InvitationItem oldItem, - InvitationItem newItem) { - return oldItem.isSubscribed() == newItem.isSubscribed() && - oldItem.getNewSharers().equals(newItem.getNewSharers()); - } - - @Override - public boolean areItemsTheSame(InvitationItem oldItem, - InvitationItem newItem) { + public boolean areItemsTheSame(I oldItem, I newItem) { return oldItem.getShareable().equals(newItem.getShareable()); } - static class InvitationsViewHolder extends RecyclerView.ViewHolder { - - final TextAvatarView avatar; - final TextView name; - private final TextView sharedBy; - final TextView subscribed; - private final Button accept; - private final Button decline; - - private InvitationsViewHolder(View v) { - super(v); - - avatar = (TextAvatarView) v.findViewById(R.id.avatarView); - name = (TextView) v.findViewById(R.id.forumNameView); - sharedBy = (TextView) v.findViewById(R.id.sharedByView); - subscribed = (TextView) v.findViewById(R.id.forumSubscribedView); - accept = (Button) v.findViewById(R.id.acceptButton); - decline = (Button) v.findViewById(R.id.declineButton); - } + @Override + public int compare(I o1, I o2) { + return String.CASE_INSENSITIVE_ORDER + .compare((o1.getShareable()).getName(), + (o2.getShareable()).getName()); } - interface AvailableForumClickListener { - void onItemClick(InvitationItem item, boolean accept); + public interface InvitationClickListener { + void onItemClick(I item, boolean accept); } + } diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationViewHolder.java b/briar-android/src/org/briarproject/android/sharing/InvitationViewHolder.java new file mode 100644 index 000000000..2c8337c13 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationViewHolder.java @@ -0,0 +1,69 @@ +package org.briarproject.android.sharing; + +import android.support.annotation.CallSuper; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import org.briarproject.R; +import org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; +import org.briarproject.android.view.TextAvatarView; +import org.briarproject.api.sharing.InvitationItem; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +public class InvitationViewHolder + extends RecyclerView.ViewHolder { + + private final TextAvatarView avatar; + private final TextView name; + protected final TextView sharedBy; + private final TextView subscribed; + private final Button accept; + private final Button decline; + + public InvitationViewHolder(View v) { + super(v); + + avatar = (TextAvatarView) v.findViewById(R.id.avatarView); + name = (TextView) v.findViewById(R.id.forumNameView); + sharedBy = (TextView) v.findViewById(R.id.sharedByView); + subscribed = (TextView) v.findViewById(R.id.forumSubscribedView); + accept = (Button) v.findViewById(R.id.acceptButton); + decline = (Button) v.findViewById(R.id.declineButton); + } + + @CallSuper + public void onBind(@Nullable final I item, + final InvitationClickListener listener) { + if (item == null) return; + + avatar.setText(item.getShareable().getName().substring(0, 1)); + avatar.setBackgroundBytes(item.getShareable().getId().getBytes()); + + name.setText(item.getShareable().getName()); + + if (item.isSubscribed()) { + subscribed.setVisibility(VISIBLE); + } else { + subscribed.setVisibility(GONE); + } + + accept.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(item, true); + } + }); + decline.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(item, false); + } + }); + } + +} \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java index 772be9bf6..a8313f56d 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java @@ -2,39 +2,34 @@ package org.briarproject.android.sharing; import android.content.Context; import android.os.Bundle; -import android.support.annotation.CallSuper; +import android.support.annotation.StringRes; import android.support.v7.widget.LinearLayoutManager; import android.widget.Toast; import org.briarproject.R; import org.briarproject.android.BriarActivity; +import org.briarproject.android.controller.handler.UiResultExceptionHandler; +import org.briarproject.android.sharing.InvitationsController.InvitationListener; import org.briarproject.android.view.BriarRecyclerView; -import org.briarproject.api.event.ContactRemovedEvent; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.event.EventListener; +import org.briarproject.api.db.DbException; import org.briarproject.api.sharing.InvitationItem; import java.util.Collection; import java.util.logging.Logger; -import javax.inject.Inject; - import static android.widget.Toast.LENGTH_SHORT; -import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; +import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; -abstract class InvitationsActivity extends BriarActivity - implements EventListener, AvailableForumClickListener { +public abstract class InvitationsActivity + extends BriarActivity + implements InvitationListener, InvitationClickListener { protected static final Logger LOG = Logger.getLogger(InvitationsActivity.class.getName()); - protected InvitationAdapter adapter; + private InvitationAdapter adapter; private BriarRecyclerView list; - @Inject - EventBus eventBus; - @Override public void onCreate(Bundle state) { super.onCreate(state); @@ -42,7 +37,6 @@ abstract class InvitationsActivity extends BriarActivity setContentView(R.layout.list); adapter = getAdapter(this, this); - list = (BriarRecyclerView) findViewById(R.id.list); if (list != null) { list.setLayoutManager(new LinearLayoutManager(this)); @@ -50,32 +44,24 @@ abstract class InvitationsActivity extends BriarActivity } } + abstract protected InvitationAdapter getAdapter(Context ctx, + InvitationClickListener listener); + @Override public void onStart() { super.onStart(); - eventBus.addListener(this); loadInvitations(false); } @Override public void onStop() { super.onStop(); - eventBus.removeListener(this); adapter.clear(); list.showProgressBar(); } @Override - @CallSuper - public void eventOccurred(Event e) { - if (e instanceof ContactRemovedEvent) { - LOG.info("Contact removed, reloading..."); - loadInvitations(true); - } - } - - @Override - public void onItemClick(InvitationItem item, boolean accept) { + public void onItemClick(I item, boolean accept) { respondToInvitation(item, accept); // show toast @@ -91,26 +77,58 @@ abstract class InvitationsActivity extends BriarActivity } } - abstract protected InvitationAdapter getAdapter(Context ctx, - AvailableForumClickListener listener); + @Override + public void loadInvitations(final boolean clear) { + final int revision = adapter.getRevision(); + getController().loadInvitations(clear, + new UiResultExceptionHandler, DbException>( + this) { + @Override + public void onResultUi(Collection items) { + displayInvitations(revision, items, clear); + } - abstract protected void loadInvitations(boolean clear); + @Override + public void onExceptionUi(DbException exception) { + // TODO proper error handling + finish(); + } + }); + } - abstract protected void respondToInvitation(final InvitationItem item, - final boolean accept); + abstract protected InvitationsController getController(); + protected void respondToInvitation(final I item, + final boolean accept) { + getController().respondToInvitation(item, accept, + new UiResultExceptionHandler(this) { + @Override + public void onResultUi(Void result) { + + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO proper error handling + finish(); + } + }); + } + + @StringRes abstract protected int getAcceptRes(); + @StringRes abstract protected int getDeclineRes(); protected void displayInvitations(final int revision, - final Collection invitations, final boolean clear) { + final Collection invitations, final boolean clear) { runOnUiThreadUnlessDestroyed(new Runnable() { @Override public void run() { if (invitations.isEmpty()) { LOG.info("No more invitations available, finishing"); - finish(); + supportFinishAfterTransition(); } else if (revision == adapter.getRevision()) { adapter.incrementRevision(); if (clear) adapter.setItems(invitations); diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java index 1b0e5f3bd..da7d014e0 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java @@ -4,34 +4,17 @@ import android.content.Context; import org.briarproject.R; import org.briarproject.android.ActivityComponent; -import org.briarproject.api.blogs.Blog; -import org.briarproject.api.blogs.BlogManager; -import org.briarproject.api.blogs.BlogSharingManager; -import org.briarproject.api.contact.Contact; -import org.briarproject.api.db.DbException; -import org.briarproject.api.event.BlogInvitationReceivedEvent; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.GroupAddedEvent; -import org.briarproject.api.event.GroupRemovedEvent; -import org.briarproject.api.sharing.InvitationItem; -import org.briarproject.api.sync.ClientId; - -import java.util.ArrayList; -import java.util.Collection; +import org.briarproject.api.sharing.SharingInvitationItem; import javax.inject.Inject; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; +import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; -public class InvitationsBlogActivity extends InvitationsActivity { +public class InvitationsBlogActivity + extends InvitationsActivity { - // Fields that are accessed from background threads must be volatile @Inject - volatile BlogManager blogManager; - @Inject - volatile BlogSharingManager blogSharingManager; + InvitationsBlogController controller; @Override public void injectActivity(ActivityComponent component) { @@ -39,75 +22,14 @@ public class InvitationsBlogActivity extends InvitationsActivity { } @Override - public void eventOccurred(Event e) { - super.eventOccurred(e); - - if (e instanceof GroupAddedEvent) { - GroupAddedEvent g = (GroupAddedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(blogManager.getClientId())) { - LOG.info("Blog added, reloading"); - loadInvitations(false); - } - } else if (e instanceof GroupRemovedEvent) { - GroupRemovedEvent g = (GroupRemovedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(blogManager.getClientId())) { - LOG.info("Blog removed, reloading"); - loadInvitations(false); - } - } else if (e instanceof BlogInvitationReceivedEvent) { - LOG.info("Blog invitation received, reloading"); - loadInvitations(false); - } + protected InvitationsController getController() { + return controller; } @Override - protected InvitationAdapter getAdapter(Context ctx, - AvailableForumClickListener listener) { - return new BlogInvitationAdapter(ctx, listener); - } - - @Override - protected void loadInvitations(final boolean clear) { - final int revision = adapter.getRevision(); - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Collection invitations = new ArrayList<>(); - long now = System.currentTimeMillis(); - invitations.addAll(blogSharingManager.getInvitations()); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayInvitations(revision, invitations, clear); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - @Override - protected void respondToInvitation(final InvitationItem item, - final boolean accept) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Blog b = (Blog) item.getShareable(); - for (Contact c : item.getNewSharers()) { - // TODO: What happens if a contact has been removed? - blogSharingManager.respondToInvitation(b, c, accept); - } - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); + protected InvitationAdapter getAdapter( + Context ctx, InvitationClickListener listener) { + return new SharingInvitationAdapter(ctx, listener); } @Override @@ -119,4 +41,5 @@ public class InvitationsBlogActivity extends InvitationsActivity { protected int getDeclineRes() { return R.string.blogs_sharing_declined_toast; } + } diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsBlogController.java b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogController.java new file mode 100644 index 000000000..4efcff5cf --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogController.java @@ -0,0 +1,7 @@ +package org.briarproject.android.sharing; + +import org.briarproject.api.sharing.SharingInvitationItem; + +public interface InvitationsBlogController + extends InvitationsController { +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsBlogControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogControllerImpl.java new file mode 100644 index 000000000..024109f7e --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogControllerImpl.java @@ -0,0 +1,82 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.api.blogs.Blog; +import org.briarproject.api.blogs.BlogManager; +import org.briarproject.api.blogs.BlogSharingManager; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.BlogInvitationReceivedEvent; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.sharing.SharingInvitationItem; +import org.briarproject.api.sync.ClientId; + +import java.util.Collection; +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +import static java.util.logging.Level.WARNING; + +public class InvitationsBlogControllerImpl + extends InvitationsControllerImpl + implements InvitationsBlogController { + + private final BlogManager blogManager; + private final BlogSharingManager blogSharingManager; + + @Inject + InvitationsBlogControllerImpl(@DatabaseExecutor Executor dbExecutor, + LifecycleManager lifecycleManager, EventBus eventBus, + BlogManager blogManager, BlogSharingManager blogSharingManager) { + super(dbExecutor, lifecycleManager, eventBus); + this.blogManager = blogManager; + this.blogSharingManager = blogSharingManager; + } + + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + + if (e instanceof BlogInvitationReceivedEvent) { + LOG.info("Blog invitation received, reloading"); + listener.loadInvitations(false); + } + } + + @Override + protected ClientId getClientId() { + return blogManager.getClientId(); + } + + @Override + protected Collection getInvitations() throws DbException { + return blogSharingManager.getInvitations(); + } + + @Override + public void respondToInvitation(final SharingInvitationItem item, + final boolean accept, + final ResultExceptionHandler handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Blog f = (Blog) item.getShareable(); + for (Contact c : item.getNewSharers()) { + // TODO: What happens if a contact has been removed? + blogSharingManager.respondToInvitation(f, c, accept); + } + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsController.java b/briar-android/src/org/briarproject/android/sharing/InvitationsController.java new file mode 100644 index 000000000..91576dfdf --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsController.java @@ -0,0 +1,25 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.controller.ActivityLifecycleController; +import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.api.db.DbException; +import org.briarproject.api.sharing.InvitationItem; + +import java.util.Collection; + +public interface InvitationsController + extends ActivityLifecycleController { + + void loadInvitations(boolean clear, + ResultExceptionHandler, DbException> handler); + + void respondToInvitation(I item, boolean accept, + ResultExceptionHandler handler); + + interface InvitationListener { + + void loadInvitations(boolean clear); + + } + +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/InvitationsControllerImpl.java new file mode 100644 index 000000000..5fcace519 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsControllerImpl.java @@ -0,0 +1,116 @@ +package org.briarproject.android.sharing; + +import android.app.Activity; +import android.support.annotation.CallSuper; + +import org.briarproject.android.controller.DbControllerImpl; +import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.ContactRemovedEvent; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.GroupAddedEvent; +import org.briarproject.api.event.GroupRemovedEvent; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.sharing.InvitationItem; +import org.briarproject.api.sync.ClientId; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + +public abstract class InvitationsControllerImpl + extends DbControllerImpl + implements InvitationsController, EventListener { + + protected static final Logger LOG = + Logger.getLogger(InvitationsControllerImpl.class.getName()); + + private final EventBus eventBus; + protected InvitationListener listener; + + public InvitationsControllerImpl(@DatabaseExecutor Executor dbExecutor, + LifecycleManager lifecycleManager, EventBus eventBus) { + super(dbExecutor, lifecycleManager); + this.eventBus = eventBus; + } + + @Override + public void onActivityCreate(Activity activity) { + listener = (InvitationListener) activity; + } + + @Override + public void onActivityStart() { + eventBus.addListener(this); + } + + @Override + public void onActivityStop() { + eventBus.removeListener(this); + } + + @Override + public void onActivityDestroy() { + + } + + @CallSuper + @Override + public void eventOccurred(Event e) { + if (e instanceof ContactRemovedEvent) { + LOG.info("Contact removed, reloading..."); + listener.loadInvitations(true); + } else if (e instanceof GroupAddedEvent) { + GroupAddedEvent g = (GroupAddedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(getClientId())) { + LOG.info("Group added, reloading"); + listener.loadInvitations(false); + } + } else if (e instanceof GroupRemovedEvent) { + GroupRemovedEvent g = (GroupRemovedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(getClientId())) { + LOG.info("Group removed, reloading"); + listener.loadInvitations(true); + } + } + } + + protected abstract ClientId getClientId(); + + @Override + public void loadInvitations(final boolean clear, + final ResultExceptionHandler, DbException> handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + Collection invitations = new ArrayList<>(); + try { + long now = System.currentTimeMillis(); + invitations.addAll(getInvitations()); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info( + "Loading invitations took " + duration + " ms"); + handler.onResult(invitations); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + + @DatabaseExecutor + protected abstract Collection getInvitations() throws DbException; + +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java index d64dab69f..1c32ee112 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java @@ -4,34 +4,17 @@ import android.content.Context; import org.briarproject.R; import org.briarproject.android.ActivityComponent; -import org.briarproject.api.contact.Contact; -import org.briarproject.api.db.DbException; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.ForumInvitationReceivedEvent; -import org.briarproject.api.event.GroupAddedEvent; -import org.briarproject.api.event.GroupRemovedEvent; -import org.briarproject.api.forum.Forum; -import org.briarproject.api.forum.ForumManager; -import org.briarproject.api.forum.ForumSharingManager; -import org.briarproject.api.sharing.InvitationItem; -import org.briarproject.api.sync.ClientId; - -import java.util.ArrayList; -import java.util.Collection; +import org.briarproject.api.sharing.SharingInvitationItem; import javax.inject.Inject; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; +import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; -public class InvitationsForumActivity extends InvitationsActivity { +public class InvitationsForumActivity + extends InvitationsActivity { - // Fields that are accessed from background threads must be volatile @Inject - volatile ForumManager forumManager; - @Inject - volatile ForumSharingManager forumSharingManager; + InvitationsForumController controller; @Override public void injectActivity(ActivityComponent component) { @@ -39,75 +22,14 @@ public class InvitationsForumActivity extends InvitationsActivity { } @Override - public void eventOccurred(Event e) { - super.eventOccurred(e); - - if (e instanceof GroupAddedEvent) { - GroupAddedEvent g = (GroupAddedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(forumManager.getClientId())) { - LOG.info("Forum added, reloading"); - loadInvitations(false); - } - } else if (e instanceof GroupRemovedEvent) { - GroupRemovedEvent g = (GroupRemovedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(forumManager.getClientId())) { - LOG.info("Forum removed, reloading"); - loadInvitations(false); - } - } else if (e instanceof ForumInvitationReceivedEvent) { - LOG.info("Forum invitation received, reloading"); - loadInvitations(false); - } + protected InvitationsController getController() { + return controller; } @Override - protected InvitationAdapter getAdapter(Context ctx, - AvailableForumClickListener listener) { - return new ForumInvitationAdapter(ctx, listener); - } - - @Override - protected void loadInvitations(final boolean clear) { - final int revision = adapter.getRevision(); - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Collection invitations = new ArrayList<>(); - long now = System.currentTimeMillis(); - invitations.addAll(forumSharingManager.getInvitations()); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayInvitations(revision, invitations, clear); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - @Override - protected void respondToInvitation(final InvitationItem item, - final boolean accept) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Forum f = (Forum) item.getShareable(); - for (Contact c : item.getNewSharers()) { - // TODO: What happens if a contact has been removed? - forumSharingManager.respondToInvitation(f, c, accept); - } - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); + protected InvitationAdapter getAdapter( + Context ctx, InvitationClickListener listener) { + return new SharingInvitationAdapter(ctx, listener); } @Override @@ -119,4 +41,5 @@ public class InvitationsForumActivity extends InvitationsActivity { protected int getDeclineRes() { return R.string.forum_declined_toast; } + } diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsForumController.java b/briar-android/src/org/briarproject/android/sharing/InvitationsForumController.java new file mode 100644 index 000000000..e58c4a41c --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsForumController.java @@ -0,0 +1,7 @@ +package org.briarproject.android.sharing; + +import org.briarproject.api.sharing.SharingInvitationItem; + +public interface InvitationsForumController + extends InvitationsController { +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsForumControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/InvitationsForumControllerImpl.java new file mode 100644 index 000000000..25f672460 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsForumControllerImpl.java @@ -0,0 +1,83 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.ForumInvitationReceivedEvent; +import org.briarproject.api.forum.Forum; +import org.briarproject.api.forum.ForumManager; +import org.briarproject.api.forum.ForumSharingManager; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.sharing.SharingInvitationItem; +import org.briarproject.api.sync.ClientId; + +import java.util.Collection; +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +import static java.util.logging.Level.WARNING; + +public class InvitationsForumControllerImpl + extends InvitationsControllerImpl + implements InvitationsForumController { + + private final ForumManager forumManager; + private final ForumSharingManager forumSharingManager; + + @Inject + InvitationsForumControllerImpl(@DatabaseExecutor Executor dbExecutor, + LifecycleManager lifecycleManager, EventBus eventBus, + ForumManager forumManager, + ForumSharingManager forumSharingManager) { + super(dbExecutor, lifecycleManager, eventBus); + this.forumManager = forumManager; + this.forumSharingManager = forumSharingManager; + } + + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + + if (e instanceof ForumInvitationReceivedEvent) { + LOG.info("Forum invitation received, reloading"); + listener.loadInvitations(false); + } + } + + @Override + protected ClientId getClientId() { + return forumManager.getClientId(); + } + + @Override + protected Collection getInvitations() throws DbException { + return forumSharingManager.getInvitations(); + } + + @Override + public void respondToInvitation(final SharingInvitationItem item, + final boolean accept, + final ResultExceptionHandler handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Forum f = (Forum) item.getShareable(); + for (Contact c : item.getNewSharers()) { + // TODO: What happens if a contact has been removed? + forumSharingManager.respondToInvitation(f, c, accept); + } + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + +} diff --git a/briar-android/src/org/briarproject/android/sharing/SharingInvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/SharingInvitationAdapter.java new file mode 100644 index 000000000..2964c9b93 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/SharingInvitationAdapter.java @@ -0,0 +1,29 @@ +package org.briarproject.android.sharing; + +import android.content.Context; +import android.view.ViewGroup; + +import org.briarproject.api.sharing.SharingInvitationItem; + +class SharingInvitationAdapter extends + InvitationAdapter { + + SharingInvitationAdapter(Context ctx, InvitationClickListener listener) { + super(ctx, SharingInvitationItem.class, listener); + } + + @Override + public SharingInvitationViewHolder onCreateViewHolder( + ViewGroup parent, + int viewType) { + return new SharingInvitationViewHolder(getView(parent)); + } + + @Override + public boolean areContentsTheSame(SharingInvitationItem oldItem, + SharingInvitationItem newItem) { + return oldItem.isSubscribed() == newItem.isSubscribed() && + oldItem.getNewSharers().equals(newItem.getNewSharers()); + } + +} diff --git a/briar-android/src/org/briarproject/android/sharing/SharingInvitationViewHolder.java b/briar-android/src/org/briarproject/android/sharing/SharingInvitationViewHolder.java new file mode 100644 index 000000000..b10672468 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/SharingInvitationViewHolder.java @@ -0,0 +1,35 @@ +package org.briarproject.android.sharing; + +import android.support.annotation.Nullable; +import android.view.View; + +import org.briarproject.R; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.sharing.SharingInvitationItem; +import org.briarproject.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; + +public class SharingInvitationViewHolder + extends InvitationViewHolder { + + public SharingInvitationViewHolder(View v) { + super(v); + } + + @Override + public void onBind(@Nullable final SharingInvitationItem item, + final InvitationAdapter.InvitationClickListener listener) { + super.onBind(item, listener); + if (item == null) return; + + Collection names = new ArrayList<>(); + for (Contact c : item.getNewSharers()) + names.add(c.getAuthor().getName()); + sharedBy.setText( + sharedBy.getContext().getString(R.string.shared_by_format, + StringUtils.join(names, ", "))); + } + +} From 96666273d3e41633f4100173cd53acfa0bc412ca Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 17 Oct 2016 13:49:04 -0200 Subject: [PATCH 04/10] Show group invitations in group list --- briar-android/AndroidManifest.xml | 10 +++ briar-android/res/values/strings.xml | 9 ++ .../android/ActivityComponent.java | 3 +- .../briarproject/android/ActivityModule.java | 9 ++ .../android/AndroidComponent.java | 3 + .../android/forum/ForumListFragment.java | 2 +- .../invitation/GroupInvitationViewHolder.java | 28 +++++++ .../invitation/InvitationGroupAdapter.java | 28 +++++++ .../invitation/InvitationsGroupActivity.java | 47 +++++++++++ .../InvitationsGroupController.java | 8 ++ .../InvitationsGroupControllerImpl.java | 83 +++++++++++++++++++ .../list/GroupListController.java | 3 + .../list/GroupListControllerImpl.java | 24 +++++- .../privategroup/list/GroupListFragment.java | 51 +++++++++++- 14 files changed, 304 insertions(+), 4 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/privategroup/invitation/GroupInvitationViewHolder.java create mode 100644 briar-android/src/org/briarproject/android/privategroup/invitation/InvitationGroupAdapter.java create mode 100644 briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupActivity.java create mode 100644 briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupController.java create mode 100644 briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupControllerImpl.java diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index aad00c6d9..19b30172c 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -122,6 +122,16 @@ /> + + + + Leave Group Dissolve Group + + Group Invitations + Joined Group + Group Invitation Declined + + %d open group invitation + %d open group invitations + + 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. New Forum diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index 1179905b6..61889b113 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -33,6 +33,7 @@ import org.briarproject.android.privategroup.creation.CreateGroupFragment; import org.briarproject.android.privategroup.conversation.GroupActivity; import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment; import org.briarproject.android.privategroup.list.GroupListFragment; +import org.briarproject.android.privategroup.invitation.InvitationsGroupActivity; import org.briarproject.android.sharing.ContactSelectorFragment; import org.briarproject.android.sharing.InvitationsBlogActivity; import org.briarproject.android.sharing.InvitationsForumActivity; @@ -77,8 +78,8 @@ public interface ActivityComponent { void inject(InvitationsBlogActivity activity); void inject(CreateGroupActivity activity); - void inject(GroupActivity activity); + void inject(InvitationsGroupActivity activity); void inject(CreateForumActivity activity); diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index c5a1b275d..39d460151 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -25,6 +25,8 @@ import org.briarproject.android.privategroup.conversation.GroupController; import org.briarproject.android.privategroup.conversation.GroupControllerImpl; import org.briarproject.android.privategroup.creation.CreateGroupController; import org.briarproject.android.privategroup.creation.CreateGroupControllerImpl; +import org.briarproject.android.privategroup.invitation.InvitationsGroupController; +import org.briarproject.android.privategroup.invitation.InvitationsGroupControllerImpl; import org.briarproject.android.privategroup.list.GroupListController; import org.briarproject.android.privategroup.list.GroupListControllerImpl; import org.briarproject.android.sharing.InvitationsBlogController; @@ -121,6 +123,13 @@ public class ActivityModule { return groupController; } + @ActivityScope + @Provides + protected InvitationsGroupController provideInvitationsGroupController( + InvitationsGroupControllerImpl invitationsGroupController) { + return invitationsGroupController; + } + @ActivityScope @Provides protected ForumController provideForumController( diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index ceb3cd9e0..6081f1da9 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -35,6 +35,7 @@ import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.privategroup.PrivateGroupManager; +import org.briarproject.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.system.Clock; import org.briarproject.plugins.AndroidPluginsModule; @@ -96,6 +97,8 @@ public interface AndroidComponent extends CoreEagerSingletons { PrivateGroupManager privateGroupManager(); + GroupInvitationManager groupInvitationManager(); + ForumManager forumManager(); ForumSharingManager forumSharingManager(); diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index f1faecd46..779fac49b 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -220,10 +220,10 @@ public class ForumListFragment extends BaseEventFragment implements if (availableCount == 0) { snackbar.dismiss(); } else { - snackbar.show(); snackbar.setText(getResources().getQuantityString( R.plurals.forums_shared, availableCount, availableCount)); + if (!snackbar.isShownOrQueued()) snackbar.show(); } } }); diff --git a/briar-android/src/org/briarproject/android/privategroup/invitation/GroupInvitationViewHolder.java b/briar-android/src/org/briarproject/android/privategroup/invitation/GroupInvitationViewHolder.java new file mode 100644 index 000000000..25aef8ce8 --- /dev/null +++ b/briar-android/src/org/briarproject/android/privategroup/invitation/GroupInvitationViewHolder.java @@ -0,0 +1,28 @@ +package org.briarproject.android.privategroup.invitation; + +import android.support.annotation.Nullable; +import android.view.View; + +import org.briarproject.R; +import org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; +import org.briarproject.android.sharing.InvitationViewHolder; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; + +public class GroupInvitationViewHolder extends InvitationViewHolder { + + public GroupInvitationViewHolder(View v) { + super(v); + } + + @Override + public void onBind(@Nullable final GroupInvitationItem item, + final InvitationClickListener listener) { + super.onBind(item, listener); + if (item == null) return; + + sharedBy.setText( + sharedBy.getContext().getString(R.string.groups_created_by, + item.getCreator().getAuthor().getName())); + } + +} \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationGroupAdapter.java b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationGroupAdapter.java new file mode 100644 index 000000000..7a53d48bd --- /dev/null +++ b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationGroupAdapter.java @@ -0,0 +1,28 @@ +package org.briarproject.android.privategroup.invitation; + +import android.content.Context; +import android.view.ViewGroup; + +import org.briarproject.android.sharing.InvitationAdapter; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; + +class InvitationGroupAdapter extends + InvitationAdapter { + + InvitationGroupAdapter(Context ctx, + InvitationClickListener listener) { + super(ctx, GroupInvitationItem.class, listener); + } + + @Override + public GroupInvitationViewHolder onCreateViewHolder(ViewGroup parent, + int viewType) { + return new GroupInvitationViewHolder(getView(parent)); + } + + @Override + public boolean areContentsTheSame(GroupInvitationItem item1, + GroupInvitationItem item2) { + return item1.isSubscribed() == item2.isSubscribed(); + } +} diff --git a/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupActivity.java b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupActivity.java new file mode 100644 index 000000000..2815e6fb3 --- /dev/null +++ b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupActivity.java @@ -0,0 +1,47 @@ +package org.briarproject.android.privategroup.invitation; + +import android.content.Context; + +import org.briarproject.R; +import org.briarproject.android.ActivityComponent; +import org.briarproject.android.sharing.InvitationAdapter; +import org.briarproject.android.sharing.InvitationsActivity; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; + +import javax.inject.Inject; + +import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener; + +public class InvitationsGroupActivity + extends InvitationsActivity { + + @Inject + protected InvitationsGroupController controller; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + @Override + protected InvitationsGroupController getController() { + return controller; + } + + @Override + protected InvitationAdapter getAdapter(Context ctx, + InvitationClickListener listener) { + return new InvitationGroupAdapter(ctx, listener); + } + + @Override + protected int getAcceptRes() { + return R.string.groups_invitations_joined; + } + + @Override + protected int getDeclineRes() { + return R.string.groups_invitations_declined; + } + +} diff --git a/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupController.java b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupController.java new file mode 100644 index 000000000..f158064ba --- /dev/null +++ b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupController.java @@ -0,0 +1,8 @@ +package org.briarproject.android.privategroup.invitation; + +import org.briarproject.android.sharing.InvitationsController; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; + +public interface InvitationsGroupController + extends InvitationsController { +} diff --git a/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupControllerImpl.java b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupControllerImpl.java new file mode 100644 index 000000000..0bde16e85 --- /dev/null +++ b/briar-android/src/org/briarproject/android/privategroup/invitation/InvitationsGroupControllerImpl.java @@ -0,0 +1,83 @@ +package org.briarproject.android.privategroup.invitation; + +import org.briarproject.android.controller.handler.ResultExceptionHandler; +import org.briarproject.android.sharing.InvitationsControllerImpl; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DatabaseExecutor; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.GroupInvitationReceivedEvent; +import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.privategroup.PrivateGroup; +import org.briarproject.api.privategroup.PrivateGroupManager; +import org.briarproject.api.privategroup.invitation.GroupInvitationItem; +import org.briarproject.api.privategroup.invitation.GroupInvitationManager; +import org.briarproject.api.sync.ClientId; + +import java.util.Collection; +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +import static java.util.logging.Level.WARNING; + +public class InvitationsGroupControllerImpl + extends InvitationsControllerImpl + implements InvitationsGroupController { + + private final PrivateGroupManager privateGroupManager; + private final GroupInvitationManager groupInvitationManager; + + @Inject + InvitationsGroupControllerImpl(@DatabaseExecutor Executor dbExecutor, + LifecycleManager lifecycleManager, EventBus eventBus, + PrivateGroupManager privateGroupManager, + GroupInvitationManager groupInvitationManager) { + super(dbExecutor, lifecycleManager, eventBus); + this.privateGroupManager = privateGroupManager; + this.groupInvitationManager = groupInvitationManager; + } + + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + + if (e instanceof GroupInvitationReceivedEvent) { + LOG.info("Group invitation received, reloading"); + listener.loadInvitations(false); + } + } + + @Override + protected ClientId getClientId() { + return privateGroupManager.getClientId(); + } + + @Override + protected Collection getInvitations() + throws DbException { + return groupInvitationManager.getInvitations(); + } + + @Override + public void respondToInvitation(final GroupInvitationItem item, + final boolean accept, + final ResultExceptionHandler handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + PrivateGroup g = (PrivateGroup) item.getShareable(); + Contact c = item.getCreator(); + groupInvitationManager.respondToInvitation(g, c, accept); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + +} diff --git a/briar-android/src/org/briarproject/android/privategroup/list/GroupListController.java b/briar-android/src/org/briarproject/android/privategroup/list/GroupListController.java index fbe05315d..f102f82e4 100644 --- a/briar-android/src/org/briarproject/android/privategroup/list/GroupListController.java +++ b/briar-android/src/org/briarproject/android/privategroup/list/GroupListController.java @@ -30,6 +30,9 @@ public interface GroupListController extends DbController { void removeGroup(GroupId g, ResultExceptionHandler result); + void loadAvailableGroups( + ResultExceptionHandler result); + interface GroupListListener extends DestroyableContext { @UiThread diff --git a/briar-android/src/org/briarproject/android/privategroup/list/GroupListControllerImpl.java b/briar-android/src/org/briarproject/android/privategroup/list/GroupListControllerImpl.java index efa36fe5f..76856f244 100644 --- a/briar-android/src/org/briarproject/android/privategroup/list/GroupListControllerImpl.java +++ b/briar-android/src/org/briarproject/android/privategroup/list/GroupListControllerImpl.java @@ -20,6 +20,7 @@ import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.privategroup.GroupMessageHeader; import org.briarproject.api.privategroup.PrivateGroup; import org.briarproject.api.privategroup.PrivateGroupManager; +import org.briarproject.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.GroupId; @@ -41,6 +42,7 @@ public class GroupListControllerImpl extends DbControllerImpl Logger.getLogger(GroupListControllerImpl.class.getName()); private final PrivateGroupManager groupManager; + private final GroupInvitationManager groupInvitationManager; private final EventBus eventBus; private final AndroidNotificationManager notificationManager; private final IdentityManager identityManager; @@ -50,10 +52,12 @@ public class GroupListControllerImpl extends DbControllerImpl @Inject GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor, LifecycleManager lifecycleManager, PrivateGroupManager groupManager, - EventBus eventBus, AndroidNotificationManager notificationManager, + GroupInvitationManager groupInvitationManager, EventBus eventBus, + AndroidNotificationManager notificationManager, IdentityManager identityManager) { super(dbExecutor, lifecycleManager); this.groupManager = groupManager; + this.groupInvitationManager = groupInvitationManager; this.eventBus = eventBus; this.notificationManager = notificationManager; this.identityManager = identityManager; @@ -187,4 +191,22 @@ public class GroupListControllerImpl extends DbControllerImpl }); } + @Override + public void loadAvailableGroups( + final ResultExceptionHandler handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + handler.onResult( + groupInvitationManager.getInvitations().size()); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + } diff --git a/briar-android/src/org/briarproject/android/privategroup/list/GroupListFragment.java b/briar-android/src/org/briarproject/android/privategroup/list/GroupListFragment.java index 9e77003ac..597e8b120 100644 --- a/briar-android/src/org/briarproject/android/privategroup/list/GroupListFragment.java +++ b/briar-android/src/org/briarproject/android/privategroup/list/GroupListFragment.java @@ -4,13 +4,16 @@ import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.annotation.UiThread; +import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityOptionsCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import org.briarproject.R; @@ -18,6 +21,7 @@ import org.briarproject.android.ActivityComponent; import org.briarproject.android.controller.handler.UiResultExceptionHandler; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.privategroup.creation.CreateGroupActivity; +import org.briarproject.android.privategroup.invitation.InvitationsGroupActivity; import org.briarproject.android.privategroup.list.GroupListController.GroupListListener; import org.briarproject.android.privategroup.list.GroupViewHolder.OnGroupRemoveClickListener; import org.briarproject.android.view.BriarRecyclerView; @@ -30,10 +34,11 @@ import java.util.logging.Logger; import javax.inject.Inject; +import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE; import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation; public class GroupListFragment extends BaseFragment implements - GroupListListener, OnGroupRemoveClickListener { + GroupListListener, OnGroupRemoveClickListener, OnClickListener { public final static String TAG = GroupListFragment.class.getName(); private static final Logger LOG = Logger.getLogger(TAG); @@ -47,6 +52,7 @@ public class GroupListFragment extends BaseFragment implements private BriarRecyclerView list; private GroupListAdapter adapter; + private Snackbar snackbar; @Nullable @Override @@ -61,6 +67,12 @@ public class GroupListFragment extends BaseFragment implements list.setLayoutManager(new LinearLayoutManager(getContext())); list.setAdapter(adapter); + snackbar = Snackbar.make(list, "", LENGTH_INDEFINITE); + snackbar.getView().setBackgroundResource(R.color.briar_primary); + snackbar.setAction(R.string.show, this); + snackbar.setActionTextColor(ContextCompat + .getColor(getContext(), R.color.briar_button_positive)); + return v; } @@ -76,6 +88,7 @@ public class GroupListFragment extends BaseFragment implements controller.onStart(); list.startPeriodicUpdate(); loadGroups(); + loadAvailableGroups(); } @Override @@ -180,4 +193,40 @@ public class GroupListFragment extends BaseFragment implements }); } + private void loadAvailableGroups() { + controller.loadAvailableGroups( + new UiResultExceptionHandler(this) { + @Override + public void onResultUi(Integer num) { + if (num == 0) { + snackbar.dismiss(); + } else { + snackbar.setText(getResources().getQuantityString( + R.plurals.groups_invitations_open, num, + num)); + if (!snackbar.isShownOrQueued()) snackbar.show(); + } + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO handle this error + finish(); + } + }); + } + + /** + * This method is handling the available groups snackbar action + */ + @Override + public void onClick(View v) { + Intent i = new Intent(getContext(), InvitationsGroupActivity.class); + ActivityOptionsCompat options = + makeCustomAnimation(getActivity(), + android.R.anim.slide_in_left, + android.R.anim.slide_out_right); + startActivity(i, options.toBundle()); + } + } From e00219c15fd03d8a016ad5b7e67b402b61e75bd8 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 18 Oct 2016 08:49:34 -0200 Subject: [PATCH 05/10] Allow responding to sharing invitations based on SessionId --- .../api/forum/ForumInvitationRequest.java | 7 +-- .../api/sharing/SharingManager.java | 10 ++- .../sharing/SharingManagerImpl.java | 61 ++++++++++++------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java b/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java index 3e90116c0..5d4c8d554 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java +++ b/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java @@ -5,16 +5,15 @@ import org.briarproject.api.contact.ContactId; import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; -import org.jetbrains.annotations.Nullable; public class ForumInvitationRequest extends InvitationRequest { private final String forumName; public ForumInvitationRequest(MessageId id, SessionId sessionId, - GroupId groupId, ContactId contactId, String forumName, String message, - boolean available, long time, boolean local, boolean sent, - boolean seen, boolean read) { + GroupId groupId, ContactId contactId, String forumName, + String message, boolean available, long time, boolean local, + boolean sent, boolean seen, boolean read) { super(id, sessionId, groupId, contactId, message, available, time, local, sent, seen, read); diff --git a/briar-api/src/org/briarproject/api/sharing/SharingManager.java b/briar-api/src/org/briarproject/api/sharing/SharingManager.java index 3e37191dd..c7b1c8004 100644 --- a/briar-api/src/org/briarproject/api/sharing/SharingManager.java +++ b/briar-api/src/org/briarproject/api/sharing/SharingManager.java @@ -1,6 +1,7 @@ package org.briarproject.api.sharing; import org.briarproject.api.clients.MessageTracker; +import org.briarproject.api.clients.SessionId; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.db.DbException; @@ -30,7 +31,14 @@ public interface SharingManager extends MessageTracker { throws DbException; /** - * Returns all group sharing messages sent by the given contact. + * Responds to a pending group invitation + */ + void respondToInvitation(SessionId id, boolean accept) + throws DbException; + + /** + * Returns all group sharing messages sent by the Contact + * identified by contactId. */ Collection getInvitationMessages( ContactId contactId) throws DbException; diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java index dd06fc2c4..a35501877 100644 --- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java @@ -316,27 +316,7 @@ abstract class SharingManagerImpl engine = - new InviteeEngine(getIRFactory(), clock); - StateUpdate update = - engine.onLocalAction(localState, localAction); - processInviteeStateUpdate(txn, null, update); - - // track message - // TODO handle this properly without engine hacks (#376) - long time = update.toSend.get(0).getTime(); - trackMessage(txn, localState.getGroupId(), time, true); - + respondToInvitation(txn, localState, accept); txn.setComplete(); } catch (FormatException e) { throw new DbException(e); @@ -345,6 +325,45 @@ abstract class SharingManagerImpl engine = + new InviteeEngine(getIRFactory(), clock); + StateUpdate update = + engine.onLocalAction(localState, localAction); + processInviteeStateUpdate(txn, null, update); + + // track message + // TODO handle this properly without engine hacks (#376) + long time = update.toSend.get(0).getTime(); + trackMessage(txn, localState.getGroupId(), time, true); + } + @Override public Collection getInvitationMessages(ContactId contactId) throws DbException { From 5ffcdc4e46c235deab71123170f1b3bdd36da10a Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 18 Oct 2016 09:38:13 -0200 Subject: [PATCH 06/10] Refactor ConversationAdapter and its ConversationItems --- ....xml => list_item_conversation_msg_in.xml} | 6 +- ...xml => list_item_conversation_msg_out.xml} | 16 +- ...l => list_item_conversation_notice_in.xml} | 25 +- ... => list_item_conversation_notice_out.xml} | 18 +- ...xml => list_item_conversation_request.xml} | 20 +- .../res/layout/list_item_notice_in.xml | 33 -- .../res/layout/list_item_notice_out.xml | 52 -- briar-android/res/values/strings.xml | 3 - .../android/contact/ContactListFragment.java | 12 +- .../android/contact/ContactListItem.java | 6 +- .../android/contact/ConversationActivity.java | 164 ++++-- .../android/contact/ConversationAdapter.java | 497 ++---------------- .../android/contact/ConversationInItem.java | 31 ++ .../ConversationIntroductionInItem.java | 33 -- .../contact/ConversationIntroductionItem.java | 31 -- .../ConversationIntroductionOutItem.java | 47 -- .../android/contact/ConversationItem.java | 292 +++++----- .../contact/ConversationItemViewHolder.java | 42 ++ .../contact/ConversationMessageInItem.java | 31 +- .../contact/ConversationMessageItem.java | 29 - .../contact/ConversationMessageOutItem.java | 43 +- .../ConversationMessageOutViewHolder.java | 16 + .../contact/ConversationNoticeInItem.java | 36 +- .../ConversationNoticeInViewHolder.java | 43 ++ .../contact/ConversationNoticeItem.java | 20 - .../contact/ConversationNoticeOutItem.java | 47 +- .../ConversationNoticeOutViewHolder.java | 48 ++ .../android/contact/ConversationOutItem.java | 40 ++ .../ConversationOutItemViewHolder.java | 44 ++ .../contact/ConversationRequestItem.java | 46 ++ .../ConversationRequestViewHolder.java | 58 ++ ...ConversationShareableInvitationInItem.java | 43 -- .../ConversationShareableInvitationItem.java | 18 - ...onversationShareableInvitationOutItem.java | 60 --- 34 files changed, 769 insertions(+), 1181 deletions(-) rename briar-android/res/layout/{list_item_msg_in.xml => list_item_conversation_msg_in.xml} (92%) rename briar-android/res/layout/{list_item_msg_out.xml => list_item_conversation_msg_out.xml} (84%) rename briar-android/res/layout/{list_item_shareable_invitation_in.xml => list_item_conversation_notice_in.xml} (71%) rename briar-android/res/layout/{list_item_msg_notice_out.xml => list_item_conversation_notice_out.xml} (84%) rename briar-android/res/layout/{list_item_introduction_in.xml => list_item_conversation_request.xml} (84%) delete mode 100644 briar-android/res/layout/list_item_notice_in.xml delete mode 100644 briar-android/res/layout/list_item_notice_out.xml create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationInItem.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationIntroductionInItem.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationIntroductionItem.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationIntroductionOutItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationItemViewHolder.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationMessageItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationMessageOutViewHolder.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeInViewHolder.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeOutViewHolder.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationOutItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationOutItemViewHolder.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationRequestItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationRequestViewHolder.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationShareableInvitationInItem.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationShareableInvitationItem.java delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationShareableInvitationOutItem.java diff --git a/briar-android/res/layout/list_item_msg_in.xml b/briar-android/res/layout/list_item_conversation_msg_in.xml similarity index 92% rename from briar-android/res/layout/list_item_msg_in.xml rename to briar-android/res/layout/list_item_conversation_msg_in.xml index 3c18ca1a8..ef5c7a953 100644 --- a/briar-android/res/layout/list_item_msg_in.xml +++ b/briar-android/res/layout/list_item_conversation_msg_in.xml @@ -1,6 +1,6 @@ diff --git a/briar-android/res/layout/list_item_shareable_invitation_in.xml b/briar-android/res/layout/list_item_conversation_notice_in.xml similarity index 71% rename from briar-android/res/layout/list_item_shareable_invitation_in.xml rename to briar-android/res/layout/list_item_conversation_notice_in.xml index b7cc1bb36..073edf537 100644 --- a/briar-android/res/layout/list_item_shareable_invitation_in.xml +++ b/briar-android/res/layout/list_item_conversation_notice_in.xml @@ -7,7 +7,7 @@ android:orientation="vertical"> -