From ba727d7568b1f4db671f17601a876ed0176de4f1 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Tue, 15 Aug 2017 14:46:40 +0100 Subject: [PATCH] Don't add threaded messages to the UI before their parents. --- .../briar/android/forum/ForumActivity.java | 5 +-- .../briar/android/forum/ForumController.java | 6 +-- .../android/forum/ForumControllerImpl.java | 17 ++++---- .../android/forum/ForumListFragment.java | 2 +- .../conversation/GroupActivity.java | 7 ++-- .../conversation/GroupController.java | 7 ++-- .../conversation/GroupControllerImpl.java | 9 +++-- .../android/threaded/NestedTreeList.java | 13 +++--- .../android/threaded/ThreadItemAdapter.java | 8 +++- .../android/threaded/ThreadItemListImpl.java | 1 + .../android/threaded/ThreadListActivity.java | 35 +++++++--------- .../threaded/ThreadListController.java | 13 +++--- .../threaded/ThreadListControllerImpl.java | 33 +-------------- .../src/main/res/menu/group_actions.xml | 12 +++--- .../briar/api/client/MessageTree.java | 2 + .../forum/event/ForumPostReceivedEvent.java | 23 ++++++----- .../event/GroupMessageAddedEvent.java | 9 ++++- .../briar/client/MessageTreeImpl.java | 4 ++ .../briar/forum/ForumManagerImpl.java | 40 +++++++++---------- .../privategroup/PrivateGroupManagerImpl.java | 29 ++++++++------ 20 files changed, 130 insertions(+), 145 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java index 2af57aa1a0..ccff1a6ce3 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java @@ -28,7 +28,6 @@ import org.briarproject.briar.android.threaded.ThreadItemAdapter; import org.briarproject.briar.android.threaded.ThreadListActivity; import org.briarproject.briar.android.threaded.ThreadListController; import org.briarproject.briar.api.forum.Forum; -import org.briarproject.briar.api.forum.ForumPostHeader; import javax.annotation.Nullable; import javax.inject.Inject; @@ -41,7 +40,7 @@ import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BOD @MethodsNotNullByDefault @ParametersNotNullByDefault public class ForumActivity extends - ThreadListActivity<Forum, ThreadItemAdapter<ForumItem>, ForumItem, ForumPostHeader> + ThreadListActivity<Forum, ForumItem, ThreadItemAdapter<ForumItem>> implements ForumListener { @Inject @@ -53,7 +52,7 @@ public class ForumActivity extends } @Override - protected ThreadListController<Forum, ForumItem, ForumPostHeader> getController() { + protected ThreadListController<Forum, ForumItem> getController() { return forumController; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumController.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumController.java index 3d800e241f..a9e5d661fe 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumController.java @@ -6,13 +6,11 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.android.threaded.ThreadListController; import org.briarproject.briar.api.forum.Forum; -import org.briarproject.briar.api.forum.ForumPostHeader; @NotNullByDefault -interface ForumController - extends ThreadListController<Forum, ForumItem, ForumPostHeader> { +interface ForumController extends ThreadListController<Forum, ForumItem> { - interface ForumListener extends ThreadListListener<ForumPostHeader> { + interface ForumListener extends ThreadListListener<ForumItem> { @UiThread void onForumLeft(ContactId c); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java index f218f4393e..dde424f7b8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java @@ -75,10 +75,10 @@ class ForumControllerImpl extends super.eventOccurred(e); if (e instanceof ForumPostReceivedEvent) { - ForumPostReceivedEvent pe = (ForumPostReceivedEvent) e; - if (pe.getGroupId().equals(getGroupId())) { + ForumPostReceivedEvent f = (ForumPostReceivedEvent) e; + if (f.getGroupId().equals(getGroupId())) { LOG.info("Forum post received, adding..."); - onForumPostHeaderReceived(pe.getForumPostHeader()); + onForumPostReceived(f.getHeader(), f.getBody()); } } else if (e instanceof ForumInvitationResponseReceivedEvent) { ForumInvitationResponseReceivedEvent f = @@ -90,10 +90,10 @@ class ForumControllerImpl extends onForumInvitationAccepted(r.getContactId()); } } else if (e instanceof ContactLeftShareableEvent) { - ContactLeftShareableEvent s = (ContactLeftShareableEvent) e; - if (s.getGroupId().equals(getGroupId())) { + ContactLeftShareableEvent c = (ContactLeftShareableEvent) e; + if (c.getGroupId().equals(getGroupId())) { LOG.info("Forum left by contact"); - onForumLeft(s.getContactId()); + onForumLeft(c.getContactId()); } } } @@ -195,11 +195,12 @@ class ForumControllerImpl extends return new ForumItem(header, body); } - private void onForumPostHeaderReceived(final ForumPostHeader h) { + private void onForumPostReceived(ForumPostHeader h, String body) { + final ForumItem item = buildItem(h, body); listener.runOnUiThreadUnlessDestroyed(new Runnable() { @Override public void run() { - listener.onHeaderReceived(h); + listener.onItemReceived(item); } }); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java index 42f22288d5..4873684ccb 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java @@ -254,7 +254,7 @@ public class ForumListFragment extends BaseEventFragment implements } else if (e instanceof ForumPostReceivedEvent) { ForumPostReceivedEvent f = (ForumPostReceivedEvent) e; LOG.info("Forum post added, updating item"); - updateItem(f.getGroupId(), f.getForumPostHeader()); + updateItem(f.getGroupId(), f.getHeader()); } else if (e instanceof ForumInvitationRequestReceivedEvent) { LOG.info("Forum invitation received, reloading available forums"); loadAvailableForums(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java index c19aa38a26..4a8d1c83fa 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java @@ -29,7 +29,6 @@ import org.briarproject.briar.android.privategroup.memberlist.GroupMemberListAct import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity; import org.briarproject.briar.android.threaded.ThreadListActivity; import org.briarproject.briar.android.threaded.ThreadListController; -import org.briarproject.briar.api.privategroup.GroupMessageHeader; import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.Visibility; @@ -44,7 +43,7 @@ import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_ @MethodsNotNullByDefault @ParametersNotNullByDefault public class GroupActivity extends - ThreadListActivity<PrivateGroup, GroupMessageAdapter, GroupMessageItem, GroupMessageHeader> + ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageAdapter> implements GroupListener, OnClickListener { @Inject @@ -60,7 +59,7 @@ public class GroupActivity extends } @Override - protected ThreadListController<PrivateGroup, GroupMessageItem, GroupMessageHeader> getController() { + protected ThreadListController<PrivateGroup, GroupMessageItem> getController() { return controller; } @@ -276,7 +275,7 @@ public class GroupActivity extends public void onGroupDissolved() { setGroupEnabled(false); AlertDialog.Builder builder = - new AlertDialog.Builder(this, R.style.BriarDialogTheme); + new AlertDialog.Builder(this, R.style.BriarDialogTheme); builder.setTitle(getString(R.string.groups_dissolved_dialog_title)); builder.setMessage(getString(R.string.groups_dissolved_dialog_message)); builder.setNeutralButton(R.string.ok, null); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupController.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupController.java index 61817fcb4e..5f7cba4d6c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupController.java @@ -8,13 +8,11 @@ import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.android.threaded.ThreadListController; -import org.briarproject.briar.api.privategroup.GroupMessageHeader; import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.Visibility; public interface GroupController - extends - ThreadListController<PrivateGroup, GroupMessageItem, GroupMessageHeader> { + extends ThreadListController<PrivateGroup, GroupMessageItem> { void loadLocalAuthor( ResultExceptionHandler<LocalAuthor, DbException> handler); @@ -22,7 +20,8 @@ public interface GroupController void isDissolved( ResultExceptionHandler<Boolean, DbException> handler); - interface GroupListener extends ThreadListListener<GroupMessageHeader> { + interface GroupListener extends ThreadListListener<GroupMessageItem> { + @UiThread void onContactRelationshipRevealed(AuthorId memberId, ContactId contactId, Visibility v); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java index ebd41767ce..a3e5c60e26 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java @@ -80,14 +80,15 @@ class GroupControllerImpl extends super.eventOccurred(e); if (e instanceof GroupMessageAddedEvent) { - GroupMessageAddedEvent gmae = (GroupMessageAddedEvent) e; - if (!gmae.isLocal() && gmae.getGroupId().equals(getGroupId())) { + GroupMessageAddedEvent g = (GroupMessageAddedEvent) e; + if (!g.isLocal() && g.getGroupId().equals(getGroupId())) { LOG.info("Group message received, adding..."); - final GroupMessageHeader h = gmae.getHeader(); + final GroupMessageItem item = + buildItem(g.getHeader(), g.getBody()); listener.runOnUiThreadUnlessDestroyed(new Runnable() { @Override public void run() { - listener.onHeaderReceived(h); + listener.onItemReceived(item); } }); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/NestedTreeList.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/NestedTreeList.java index d4fd06b7c3..a8517b64b0 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/NestedTreeList.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/NestedTreeList.java @@ -3,7 +3,9 @@ package org.briarproject.briar.android.threaded; import android.support.annotation.UiThread; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.MessageTree; +import org.briarproject.briar.api.client.MessageTree.MessageNode; import org.briarproject.briar.client.MessageTreeImpl; import java.util.ArrayList; @@ -13,8 +15,7 @@ import java.util.List; @UiThread @NotNullByDefault -public class NestedTreeList<T extends MessageTree.MessageNode> - implements Iterable<T> { +public class NestedTreeList<T extends MessageNode> implements Iterable<T> { private final MessageTree<T> tree = new MessageTreeImpl<>(); private List<T> depthFirstCollection = new ArrayList<>(); @@ -38,14 +39,14 @@ public class NestedTreeList<T extends MessageTree.MessageNode> return depthFirstCollection.get(index); } - public int indexOf(T elem) { - return depthFirstCollection.indexOf(elem); - } - public int size() { return depthFirstCollection.size(); } + public boolean contains(MessageId m) { + return tree.contains(m); + } + @Override public Iterator<T> iterator() { return depthFirstCollection.iterator(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java index 21d0ede14a..49140f571c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java @@ -1,6 +1,5 @@ package org.briarproject.briar.android.threaded; -import android.os.Handler; import android.support.annotation.UiThread; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -28,7 +27,6 @@ public class ThreadItemAdapter<I extends ThreadItem> protected final NestedTreeList<I> items = new NestedTreeList<>(); private final ThreadItemListener<I> listener; private final LinearLayoutManager layoutManager; - private final Handler handler = new Handler(); private volatile int revision = 0; @@ -104,6 +102,10 @@ public class ThreadItemAdapter<I extends ThreadItem> return NO_POSITION; // Not found } + boolean contains(MessageId m) { + return items.contains(m); + } + /** * Highlights the item with the given {@link MessageId} * and disables the highlight for a previously highlighted item, if any. @@ -184,6 +186,7 @@ public class ThreadItemAdapter<I extends ThreadItem> } static class UnreadCount { + final int top, bottom; private UnreadCount(int top, int bottom) { @@ -193,6 +196,7 @@ public class ThreadItemAdapter<I extends ThreadItem> } public interface ThreadItemListener<I> { + void onUnreadItemVisible(I item); void onReplyClick(I item); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemListImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemListImpl.java index 2886607edc..bfd63fa5bf 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemListImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemListImpl.java @@ -16,6 +16,7 @@ public class ThreadItemListImpl<I extends ThreadItem> extends ArrayList<I> return bottomVisibleItemId; } + @Override public void setFirstVisibleId(@Nullable MessageId bottomVisibleItemId) { this.bottomVisibleItemId = bottomVisibleItemId; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java index dc30cc19b5..829ba292cc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java @@ -32,7 +32,6 @@ import org.briarproject.briar.android.view.TextInputView; import org.briarproject.briar.android.view.TextInputView.TextInputListener; import org.briarproject.briar.android.view.UnreadMessageButton; import org.briarproject.briar.api.client.NamedGroup; -import org.briarproject.briar.api.client.PostHeader; import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout; import java.util.Collection; @@ -49,9 +48,9 @@ import static org.briarproject.briar.android.threaded.ThreadItemAdapter.UnreadCo @MethodsNotNullByDefault @ParametersNotNullByDefault -public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadItemAdapter<I>, I extends ThreadItem, H extends PostHeader> +public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadItem, A extends ThreadItemAdapter<I>> extends BriarActivity - implements ThreadListListener<H>, TextInputListener, SharingListener, + implements ThreadListListener<I>, TextInputListener, SharingListener, ThreadItemListener<I>, ThreadListDataSource { protected static final String KEY_REPLY_ID = "replyId"; @@ -68,7 +67,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI @Nullable private MessageId replyId; - protected abstract ThreadListController<G, I, H> getController(); + protected abstract ThreadListController<G, I> getController(); @Inject protected SharingController sharingController; @@ -190,7 +189,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI if (items.isEmpty()) { list.showData(); } else { - initList(items); + displayItems(items); updateTextInput(); } } else { @@ -206,7 +205,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI }); } - private void initList(final ThreadItemList<I> items) { + private void displayItems(final ThreadItemList<I> items) { adapter.setItems(items); MessageId messageId = items.getFirstVisibleItemId(); if (messageId != null) @@ -383,19 +382,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI protected abstract int getMaxBodyLength(); @Override - public void onHeaderReceived(H header) { - getController().loadItem(header, - new UiResultExceptionHandler<I, DbException>(this) { - @Override - public void onResultUi(final I result) { - addItem(result, false); - } - - @Override - public void onExceptionUi(DbException exception) { - handleDbException(exception); - } - }); + public void onItemReceived(I item) { + addItem(item, false); } @Override @@ -403,8 +391,15 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI supportFinishAfterTransition(); } - protected void addItem(I item, boolean isLocal) { + private void addItem(I item, boolean isLocal) { adapter.incrementRevision(); + MessageId parent = item.getParentId(); + if (parent != null && !adapter.contains(parent)) { + // We've incremented the adapter's revision, so the item will be + // loaded when its parent has been loaded + LOG.info("Ignoring item with missing parent"); + return; + } adapter.add(item); if (isLocal) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListController.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListController.java index d39c8b453a..f64a707689 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListController.java @@ -12,14 +12,13 @@ import org.briarproject.briar.android.controller.ActivityLifecycleController; import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.api.client.NamedGroup; -import org.briarproject.briar.api.client.PostHeader; import java.util.Collection; import javax.annotation.Nullable; @NotNullByDefault -public interface ThreadListController<G extends NamedGroup, I extends ThreadItem, H extends PostHeader> +public interface ThreadListController<G extends NamedGroup, I extends ThreadItem> extends ActivityLifecycleController { void setGroupId(GroupId groupId); @@ -29,9 +28,8 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem void loadSharingContacts( ResultExceptionHandler<Collection<ContactId>, DbException> handler); - void loadItem(H header, ResultExceptionHandler<I, DbException> handler); - - void loadItems(ResultExceptionHandler<ThreadItemList<I>, DbException> handler); + void loadItems( + ResultExceptionHandler<ThreadItemList<I>, DbException> handler); void markItemRead(I item); @@ -42,9 +40,10 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem void deleteNamedGroup(ExceptionHandler<DbException> handler); - interface ThreadListListener<H> extends ThreadListDataSource { + interface ThreadListListener<I> extends ThreadListDataSource { + @UiThread - void onHeaderReceived(H header); + void onItemReceived(I item); @UiThread void onGroupRemoved(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java index 5f520611af..26bb1aff32 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java @@ -39,9 +39,9 @@ import static java.util.logging.Level.WARNING; @MethodsNotNullByDefault @ParametersNotNullByDefault -public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage, L extends ThreadListListener<H>> +public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage, L extends ThreadListListener<I>> extends DbControllerImpl - implements ThreadListController<G, I, H>, EventListener { + implements ThreadListController<G, I>, EventListener { private static final Logger LOG = Logger.getLogger(ThreadListControllerImpl.class.getName()); @@ -203,35 +203,6 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T @DatabaseExecutor protected abstract String loadMessageBody(H header) throws DbException; - @Override - public void loadItem(final H header, - final ResultExceptionHandler<I, DbException> handler) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - long now = System.currentTimeMillis(); - String body; - if (!bodyCache.containsKey(header.getId())) { - body = loadMessageBody(header); - bodyCache.put(header.getId(), body); - } else { - body = bodyCache.get(header.getId()); - } - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Loading item took " + duration + " ms"); - I item = buildItem(header, body); - handler.onResult(item); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - handler.onException(e); - } - } - }); - } - @Override public void markItemRead(I item) { markItemsRead(Collections.singletonList(item)); diff --git a/briar-android/src/main/res/menu/group_actions.xml b/briar-android/src/main/res/menu/group_actions.xml index 1336c01de3..eac18cd621 100644 --- a/briar-android/src/main/res/menu/group_actions.xml +++ b/briar-android/src/main/res/menu/group_actions.xml @@ -3,18 +3,18 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> - <item - android:id="@+id/action_group_member_list" - android:icon="@drawable/ic_group_white" - android:title="@string/groups_member_list" - app:showAsAction="ifRoom"/> - <item android:id="@+id/action_group_invite" android:icon="@drawable/social_share_white" android:title="@string/groups_invite_members" app:showAsAction="ifRoom"/> + <item + android:id="@+id/action_group_member_list" + android:icon="@drawable/ic_group_white" + android:title="@string/groups_member_list" + app:showAsAction="ifRoom"/> + <item android:id="@+id/action_group_reveal" android:icon="@drawable/ic_visibility_white" diff --git a/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java b/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java index 8d2ed6cd9a..e850391d05 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java @@ -21,6 +21,8 @@ public interface MessageTree<T extends MessageTree.MessageNode> { Collection<T> depthFirstOrder(); + boolean contains(MessageId m); + @NotNullByDefault interface MessageNode { diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumPostReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumPostReceivedEvent.java index 0aef3a23f5..44a24db8fc 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumPostReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumPostReceivedEvent.java @@ -14,21 +14,26 @@ import javax.annotation.concurrent.Immutable; @NotNullByDefault public class ForumPostReceivedEvent extends Event { - private final ForumPostHeader forumPostHeader; private final GroupId groupId; + private final ForumPostHeader header; + private final String body; - public ForumPostReceivedEvent(ForumPostHeader forumPostHeader, - GroupId groupId) { - - this.forumPostHeader = forumPostHeader; + public ForumPostReceivedEvent(GroupId groupId, ForumPostHeader header, + String body) { this.groupId = groupId; - } - - public ForumPostHeader getForumPostHeader() { - return forumPostHeader; + this.header = header; + this.body = body; } public GroupId getGroupId() { return groupId; } + + public ForumPostHeader getHeader() { + return header; + } + + public String getBody() { + return body; + } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupMessageAddedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupMessageAddedEvent.java index 91d363779b..ce75850e52 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupMessageAddedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupMessageAddedEvent.java @@ -17,13 +17,14 @@ public class GroupMessageAddedEvent extends Event { private final GroupId groupId; private final GroupMessageHeader header; + private final String body; private final boolean local; public GroupMessageAddedEvent(GroupId groupId, GroupMessageHeader header, - boolean local) { - + String body, boolean local) { this.groupId = groupId; this.header = header; + this.body = body; this.local = local; } @@ -35,6 +36,10 @@ public class GroupMessageAddedEvent extends Event { return header; } + public String getBody() { + return body; + } + public boolean isLocal() { return local; } diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java index 5636c5f751..41b4410d8a 100644 --- a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java @@ -107,4 +107,8 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode> return orderedList; } + @Override + public boolean contains(MessageId m) { + return nodeMap.containsKey(m); + } } diff --git a/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java index fef8224bdd..f9328d2827 100644 --- a/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java @@ -45,7 +45,6 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; -import static org.briarproject.bramble.api.identity.Author.Status.ANONYMOUS; import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES; import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR; import static org.briarproject.briar.api.forum.ForumConstants.KEY_ID; @@ -85,9 +84,10 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager { messageTracker.trackIncomingMessage(txn, m); - ForumPostHeader post = getForumPostHeader(txn, m.getId(), meta); + ForumPostHeader header = getForumPostHeader(txn, m.getId(), meta); + String postBody = getPostBody(body); ForumPostReceivedEvent event = - new ForumPostReceivedEvent(post, m.getGroupId()); + new ForumPostReceivedEvent(m.getGroupId(), header, postBody); txn.attach(event); // share message @@ -215,14 +215,19 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager { public String getPostBody(MessageId m) throws DbException { try { // Parent ID, author, forum post body, signature - BdfList message = clientHelper.getMessageAsList(m); - if (message == null) throw new DbException(); - return message.getString(2); + BdfList body = clientHelper.getMessageAsList(m); + if (body == null) throw new DbException(); + return getPostBody(body); } catch (FormatException e) { throw new DbException(e); } } + private String getPostBody(BdfList body) throws FormatException { + // Parent ID, author, forum post body, signature + return body.getString(2); + } + @Override public Collection<ForumPostHeader> getPostHeaders(GroupId g) throws DbException { @@ -294,24 +299,17 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager { throws DbException, FormatException { long timestamp = meta.getLong(KEY_TIMESTAMP); - Author author = null; - Status status = ANONYMOUS; MessageId parentId = null; if (meta.containsKey(KEY_PARENT)) parentId = new MessageId(meta.getRaw(KEY_PARENT)); - // TODO: Remove support for anonymous forum posts - BdfDictionary d1 = meta.getDictionary(KEY_AUTHOR, null); - if (d1 != null) { - AuthorId authorId = new AuthorId(d1.getRaw(KEY_ID)); - String name = d1.getString(KEY_NAME); - byte[] publicKey = d1.getRaw(KEY_PUBLIC_NAME); - author = new Author(authorId, name, publicKey); - if (statuses.containsKey(authorId)) { - status = statuses.get(authorId); - } else { - status = identityManager.getAuthorStatus(txn, author.getId()); - } - } + BdfDictionary authorDict = meta.getDictionary(KEY_AUTHOR); + AuthorId authorId = new AuthorId(authorDict.getRaw(KEY_ID)); + String name = authorDict.getString(KEY_NAME); + byte[] publicKey = authorDict.getRaw(KEY_PUBLIC_NAME); + Author author = new Author(authorId, name, publicKey); + Status status = statuses.get(authorId); + if (status == null) + status = identityManager.getAuthorStatus(txn, author.getId()); boolean read = meta.getBoolean(MSG_KEY_READ); return new ForumPostHeader(id, parentId, timestamp, author, status, diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java index cdaf0c928a..d0becaecd7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java @@ -307,16 +307,20 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook @Override public String getMessageBody(MessageId m) throws DbException { try { - // type(0), member_name(1), member_public_key(2), parent_id(3), - // previous_message_id(4), content(5), signature(6) BdfList body = clientHelper.getMessageAsList(m); if (body == null) throw new DbException(); - return body.getString(5); + return getMessageBody(body); } catch (FormatException e) { throw new DbException(e); } } + private String getMessageBody(BdfList body) throws FormatException { + // type(0), member_name(1), member_public_key(2), parent_id(3), + // previous_message_id(4), content(5), signature(6) + return body.getString(5); + } + @Override public Collection<GroupMessageHeader> getHeaders(GroupId g) throws DbException { @@ -579,21 +583,20 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook private void attachGroupMessageAddedEvent(Transaction txn, Message m, BdfDictionary meta, boolean local) throws DbException, FormatException { - GroupMessageHeader h = - getGroupMessageHeader(txn, m.getGroupId(), m.getId(), meta, - Collections.<AuthorId, Status>emptyMap()); - Event e = new GroupMessageAddedEvent(m.getGroupId(), h, local); - txn.attach(e); + GroupMessageHeader header = getGroupMessageHeader(txn, m.getGroupId(), + m.getId(), meta, Collections.<AuthorId, Status>emptyMap()); + String body = getMessageBody(clientHelper.toList(m)); + txn.attach(new GroupMessageAddedEvent(m.getGroupId(), header, body, + local)); } private void attachJoinMessageAddedEvent(Transaction txn, Message m, BdfDictionary meta, boolean local, Visibility v) throws DbException, FormatException { - JoinMessageHeader h = - getJoinMessageHeader(txn, m.getGroupId(), m.getId(), meta, - Collections.<AuthorId, Status>emptyMap(), v); - Event e = new GroupMessageAddedEvent(m.getGroupId(), h, local); - txn.attach(e); + JoinMessageHeader header = getJoinMessageHeader(txn, m.getGroupId(), + m.getId(), meta, Collections.<AuthorId, Status>emptyMap(), v); + txn.attach(new GroupMessageAddedEvent(m.getGroupId(), header, "", + local)); } private void addMember(Transaction txn, GroupId g, Author a, Visibility v) -- GitLab