From 92f2e7b0fcd2dfe3d250602e30bc087006024bec Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson <ernir@ymirmobile.com> Date: Tue, 27 Sep 2016 23:34:00 +0200 Subject: [PATCH] merge with master and fixes after comments --- .../android/forum/ForumActivity.java | 90 ++++++----- .../android/forum/ForumController.java | 14 +- .../android/forum/ForumControllerImpl.java | 32 ++-- .../android/forum/ForumEntry.java | 12 +- .../android/forum/NestedForumAdapter.java | 150 +++++++++--------- .../android/util/NestedTreeList.java | 4 +- .../android/forum/ForumActivityTest.java | 7 +- .../briarproject/api/clients/MessageTree.java | 2 + .../briarproject/clients/MessageTreeImpl.java | 11 +- .../briarproject/clients/MessageTreeTest.java | 10 ++ 10 files changed, 186 insertions(+), 146 deletions(-) diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index 19ce6d499e..2ed6ccbfb8 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -19,6 +19,7 @@ import org.briarproject.R; import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidNotificationManager; +import org.briarproject.android.controller.handler.UiResultExceptionHandler; import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.forum.ForumController.ForumPostListener; import org.briarproject.android.forum.NestedForumAdapter.OnNestedForumListener; @@ -27,8 +28,8 @@ import org.briarproject.android.sharing.SharingStatusForumActivity; import org.briarproject.android.view.BriarRecyclerView; import org.briarproject.android.view.TextInputView; import org.briarproject.android.view.TextInputView.TextInputListener; +import org.briarproject.api.db.DbException; import org.briarproject.api.forum.Forum; -import org.briarproject.api.forum.ForumPost; import org.briarproject.api.forum.ForumPostHeader; import org.briarproject.api.sync.GroupId; import org.briarproject.util.StringUtils; @@ -64,7 +65,6 @@ public class ForumActivity extends BriarActivity implements private BriarRecyclerView recyclerView; private TextInputView textInput; - private LinearLayoutManager linearLayoutManager; private volatile GroupId groupId = null; @@ -93,29 +93,31 @@ public class ForumActivity extends BriarActivity implements recyclerView.setEmptyText(R.string.no_forum_posts); forumController.loadForum(groupId, - new UiResultHandler<List<ForumEntry>>(this) { + new UiResultExceptionHandler<List<ForumEntry>, DbException>( + this) { @Override public void onResultUi(List<ForumEntry> result) { - if (result != null) { - Forum forum = forumController.getForum(); - if (forum != null) setTitle(forum.getName()); - List<ForumEntry> entries = new ArrayList<>(result); - if (entries.isEmpty()) { - recyclerView.showData(); - } else { - forumAdapter.setEntries(entries); - if (state != null) { - byte[] replyId = - state.getByteArray(KEY_REPLY_ID); - if (replyId != null) - forumAdapter.setReplyEntryById(replyId); - } - } + Forum forum = forumController.getForum(); + if (forum != null) setTitle(forum.getName()); + List<ForumEntry> entries = new ArrayList<>(result); + if (entries.isEmpty()) { + recyclerView.showData(); } else { - // TODO Improve UX ? - finish(); + forumAdapter.setEntries(entries); + if (state != null) { + byte[] replyId = + state.getByteArray(KEY_REPLY_ID); + if (replyId != null) + forumAdapter.setReplyEntryById(replyId); + } } } + + @Override + public void onExceptionUi(DbException exception) { + // TODO Improve UX ? + finish(); + } }); } @@ -248,22 +250,21 @@ public class ForumActivity extends BriarActivity implements public void onSendClick(String text) { if (text.trim().length() == 0) return; - if (forumController.getForum() == null) return; ForumEntry replyEntry = forumAdapter.getReplyEntry(); - UiResultHandler<ForumPost> resultHandler = - new UiResultHandler<ForumPost>(this) { + UiResultExceptionHandler<ForumEntry, DbException> resultHandler = + new UiResultExceptionHandler<ForumEntry, DbException>(this) { @Override - public void onResultUi(ForumPost result) { - forumController.storePost(result, - new UiResultHandler<ForumEntry>( - ForumActivity.this) { - @Override - public void onResultUi(ForumEntry result) { - onForumEntryAdded(result, true); - } - }); + public void onResultUi(ForumEntry result) { + onForumEntryAdded(result, true); + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO Improve UX ? + finish(); } }; + if (replyEntry == null) { // root post forumController.createPost(StringUtils.toUtf8(text), resultHandler); @@ -322,11 +323,14 @@ public class ForumActivity extends BriarActivity implements private void onForumEntryAdded(final ForumEntry entry, boolean isLocal) { forumAdapter.addEntry(entry); - if (isLocal) { + if (isLocal && forumAdapter.isVisible(entry)) { displaySnackbarShort(R.string.forum_new_entry_posted); } else { Snackbar snackbar = Snackbar.make(recyclerView, - R.string.forum_new_entry_received, Snackbar.LENGTH_LONG); + isLocal ? R.string.forum_new_entry_posted : + R.string.forum_new_entry_received, + Snackbar.LENGTH_LONG); + snackbar.getView().setBackgroundResource(R.color.briar_primary); snackbar.setActionTextColor(ContextCompat .getColor(ForumActivity.this, R.color.briar_button_positive)); @@ -343,12 +347,18 @@ public class ForumActivity extends BriarActivity implements @Override public void onExternalEntryAdded(ForumPostHeader header) { - forumController.loadPost(header, new UiResultHandler<ForumEntry>(this) { - @Override - public void onResultUi(final ForumEntry result) { - onForumEntryAdded(result, false); - } - }); + forumController.loadPost(header, + new UiResultExceptionHandler<ForumEntry, DbException>(this) { + @Override + public void onResultUi(final ForumEntry result) { + onForumEntryAdded(result, false); + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO add proper exception handling + } + }); } } diff --git a/briar-android/src/org/briarproject/android/forum/ForumController.java b/briar-android/src/org/briarproject/android/forum/ForumController.java index 79499d48de..459aafb2ff 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumController.java +++ b/briar-android/src/org/briarproject/android/forum/ForumController.java @@ -4,9 +4,10 @@ import android.support.annotation.Nullable; import android.support.annotation.UiThread; import org.briarproject.android.controller.ActivityLifecycleController; +import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.android.controller.handler.ResultHandler; +import org.briarproject.api.db.DbException; import org.briarproject.api.forum.Forum; -import org.briarproject.api.forum.ForumPost; import org.briarproject.api.forum.ForumPostHeader; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; @@ -17,13 +18,13 @@ import java.util.List; public interface ForumController extends ActivityLifecycleController { void loadForum(GroupId groupId, - ResultHandler<List<ForumEntry>> resultHandler); + ResultExceptionHandler<List<ForumEntry>, DbException> resultHandler); @Nullable Forum getForum(); void loadPost(ForumPostHeader header, - ResultHandler<ForumEntry> resultHandler); + ResultExceptionHandler<ForumEntry, DbException> resultHandler); void unsubscribe(ResultHandler<Boolean> resultHandler); @@ -31,12 +32,11 @@ public interface ForumController extends ActivityLifecycleController { void entriesRead(Collection<ForumEntry> messageIds); - void createPost(byte[] body, ResultHandler<ForumPost> resultHandler); + void createPost(byte[] body, + ResultExceptionHandler<ForumEntry, DbException> resultHandler); void createPost(byte[] body, MessageId parentId, - ResultHandler<ForumPost> resultHandler); - - void storePost(ForumPost post, ResultHandler<ForumEntry> resultHandler); + ResultExceptionHandler<ForumEntry, DbException> resultHandler); interface ForumPostListener { @UiThread diff --git a/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java b/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java index ef66d18bc5..bf147491b1 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java +++ b/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.support.annotation.Nullable; import org.briarproject.android.controller.DbControllerImpl; +import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.api.FormatException; import org.briarproject.api.crypto.CryptoComponent; @@ -42,7 +43,7 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.identity.Author.Status.VERIFIED; +import static org.briarproject.api.identity.Author.Status.OURSELVES; public class ForumControllerImpl extends DbControllerImpl implements ForumController, EventListener { @@ -149,9 +150,7 @@ public class ForumControllerImpl extends DbControllerImpl // Get First Identity now = System.currentTimeMillis(); - localAuthor = - identityManager.getLocalAuthors().iterator() - .next(); + localAuthor = identityManager.getLocalAuthor(); duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Loading author took " + duration + " ms"); @@ -214,7 +213,7 @@ public class ForumControllerImpl extends DbControllerImpl @Override public void loadForum(final GroupId groupId, - final ResultHandler<List<ForumEntry>> resultHandler) { + final ResultExceptionHandler<List<ForumEntry>, DbException> resultHandler) { runOnDbThread(new Runnable() { @Override public void run() { @@ -231,7 +230,7 @@ public class ForumControllerImpl extends DbControllerImpl } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - resultHandler.onResult(null); + resultHandler.onException(e); } } }); @@ -245,7 +244,7 @@ public class ForumControllerImpl extends DbControllerImpl @Override public void loadPost(final ForumPostHeader header, - final ResultHandler<ForumEntry> resultHandler) { + final ResultExceptionHandler<ForumEntry, DbException> resultHandler) { runOnDbThread(new Runnable() { @Override public void run() { @@ -255,7 +254,9 @@ public class ForumControllerImpl extends DbControllerImpl resultHandler.onResult(new ForumEntry(header, StringUtils .fromUtf8(bodyCache.get(header.getId())))); } catch (DbException e) { - e.printStackTrace(); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + resultHandler.onException(e); } } }); @@ -311,13 +312,13 @@ public class ForumControllerImpl extends DbControllerImpl @Override public void createPost(byte[] body, - ResultHandler<ForumPost> resultHandler) { + ResultExceptionHandler<ForumEntry, DbException> resultHandler) { createPost(body, null, resultHandler); } @Override public void createPost(final byte[] body, final MessageId parentId, - final ResultHandler<ForumPost> resultHandler) { + final ResultExceptionHandler<ForumEntry, DbException> resultHandler) { cryptoExecutor.execute(new Runnable() { @Override public void run() { @@ -336,14 +337,13 @@ public class ForumControllerImpl extends DbControllerImpl throw new RuntimeException(e); } bodyCache.put(p.getMessage().getId(), body); - resultHandler.onResult(p); + storePost(p, resultHandler); } }); } - @Override - public void storePost(final ForumPost p, - final ResultHandler<ForumEntry> resultHandler) { + private void storePost(final ForumPost p, + final ResultExceptionHandler<ForumEntry, DbException> resultHandler) { runOnDbThread(new Runnable() { @Override public void run() { @@ -359,8 +359,7 @@ public class ForumControllerImpl extends DbControllerImpl new ForumPostHeader(p.getMessage().getId(), p.getParent(), p.getMessage().getTimestamp(), - p.getAuthor(), VERIFIED, - true); + p.getAuthor(), OURSELVES, true); resultHandler.onResult(new ForumEntry(h, StringUtils .fromUtf8(bodyCache.get(p.getMessage().getId())))); @@ -368,6 +367,7 @@ public class ForumControllerImpl extends DbControllerImpl } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + resultHandler.onException(e); } } }); diff --git a/briar-android/src/org/briarproject/android/forum/ForumEntry.java b/briar-android/src/org/briarproject/android/forum/ForumEntry.java index 889ef9802e..49e1ee32f5 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumEntry.java +++ b/briar-android/src/org/briarproject/android/forum/ForumEntry.java @@ -6,6 +6,7 @@ import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author.Status; import org.briarproject.api.sync.MessageId; +/* This class is not thread safe */ public class ForumEntry implements MessageTree.MessageNode { public final static int LEVEL_UNDEFINED = -1; @@ -18,6 +19,7 @@ public class ForumEntry implements MessageTree.MessageNode { private Status status; private int level = LEVEL_UNDEFINED; private boolean isShowingDescendants = true; + private int descendantCount = 0; private boolean isRead = true; ForumEntry(ForumPostHeader h, String text) { @@ -70,7 +72,7 @@ public class ForumEntry implements MessageTree.MessageNode { return isShowingDescendants; } - void setLevel(int level) { + public void setLevel(int level) { this.level = level; } @@ -89,4 +91,12 @@ public class ForumEntry implements MessageTree.MessageNode { void setRead(boolean read) { isRead = read; } + + public boolean hasDescendants() { + return descendantCount > 0; + } + + public void setDescendantCount(int descendantCount) { + this.descendantCount = descendantCount; + } } diff --git a/briar-android/src/org/briarproject/android/forum/NestedForumAdapter.java b/briar-android/src/org/briarproject/android/forum/NestedForumAdapter.java index 175ce5a162..c85803da6e 100644 --- a/briar-android/src/org/briarproject/android/forum/NestedForumAdapter.java +++ b/briar-android/src/org/briarproject/android/forum/NestedForumAdapter.java @@ -3,10 +3,8 @@ package org.briarproject.android.forum; import android.animation.Animator; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; -import android.annotation.TargetApi; import android.content.Context; import android.graphics.drawable.ColorDrawable; -import android.os.Build; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; @@ -26,7 +24,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Stack; import static android.support.v7.widget.RecyclerView.NO_POSITION; import static android.view.View.GONE; @@ -61,90 +58,80 @@ public class NestedForumAdapter return replyEntry; } - private void setForumEntryLevels() { - Stack<MessageId> idStack = new Stack<>(); - for (ForumEntry forumEntry : forumEntries) { - if (forumEntry.getParentId() == null) { - idStack.clear(); - } else if (idStack.isEmpty() || - !idStack.contains(forumEntry.getParentId())) { - idStack.push(forumEntry.getParentId()); - } else if (!forumEntry.getParentId().equals(idStack.peek())) { - do { - idStack.pop(); - } while (!forumEntry.getParentId().equals(idStack.peek())); - } - forumEntry.setLevel(idStack.size()); - } - } - void setEntries(List<ForumEntry> entries) { forumEntries.clear(); forumEntries.addAll(entries); - setForumEntryLevels(); notifyItemRangeInserted(0, entries.size()); } void addEntry(ForumEntry entry) { - boolean isShowingDescendants = false; forumEntries.add(entry); - setForumEntryLevels(); - if (entry.getLevel() > 0) { - // update parent and make sure descendants are visible - // Note that the parent's visibility is guaranteed (otherwise - // the reply button would not be visible) + addedEntry = entry; + if (entry.getParentId() == null) { + notifyItemInserted(getVisiblePos(entry)); + } else { + // Try to find the entry's parent and perform the proper ui update if + // it's present and visible. for (int i = forumEntries.indexOf(entry) - 1; i >= 0; i--) { ForumEntry higherEntry = forumEntries.get(i); if (higherEntry.getLevel() < entry.getLevel()) { // parent found - if (!higherEntry.isShowingDescendants()) { - isShowingDescendants = true; - showDescendants(higherEntry); + if (higherEntry.isShowingDescendants()) { + int parentVisiblePos = getVisiblePos(higherEntry); + if (parentVisiblePos != NO_POSITION) { + // parent is visible, we need to update its ui + notifyItemChanged(parentVisiblePos); + // new entry insert ui + int visiblePos = getVisiblePos(entry); + notifyItemInserted(visiblePos); + break; + } + } else { + // do not show the new entry if its parent is not showing + // descendants (this can be overridden by the user by + // pressing the snack bar) + break; } - notifyItemChanged(getVisiblePos(higherEntry)); - break; } } } - if (!isShowingDescendants) { - int visiblePos = getVisiblePos(entry); - notifyItemInserted(visiblePos); - } - addedEntry = entry; } void scrollToEntry(ForumEntry entry) { - layoutManager - .scrollToPositionWithOffset(getVisiblePos(entry), 0); - } - - private boolean hasDescendants(ForumEntry forumEntry) { - int i = forumEntries.indexOf(forumEntry); - if (i >= 0 && i < forumEntries.size() - 1) { - if (forumEntries.get(i + 1).getLevel() > - forumEntry.getLevel()) { - return true; + int visiblePos = getVisiblePos(entry); + if (visiblePos == NO_POSITION && entry.getParentId() != null) { + // The entry is not visible due to being hidden by its parent entry. + // Find the parent and make it visible and traverse up the parent + // chain if necessary to make the entry visible + MessageId parentId = entry.getParentId(); + for (int i = forumEntries.indexOf(entry) - 1; i >= 0; i--) { + ForumEntry higherEntry = forumEntries.get(i); + if (higherEntry.getId().equals(parentId)) { + // parent found + showDescendants(higherEntry); + int parentPos = getVisiblePos(higherEntry); + if (parentPos != NO_POSITION) { + // parent or ancestor is visible, entry's visibility + // is ensured + notifyItemChanged(parentPos); + visiblePos = parentPos; + break; + } + // parent or ancestor is hidden, we need to continue up the + // dependency chain + parentId = higherEntry.getParentId(); + } } } - return false; - } - - private boolean hasVisibleDescendants(ForumEntry forumEntry) { - int visiblePos = getVisiblePos(forumEntry); - int levelLimit = forumEntry.getLevel(); - if (visiblePos + 1 < getItemCount()) { - ForumEntry entry = getVisibleEntry(visiblePos + 1); - if (entry == null || entry.getLevel() > levelLimit) - return true; - } - return false; + if (visiblePos != NO_POSITION) + layoutManager.scrollToPositionWithOffset(visiblePos, 0); } private int getReplyCount(ForumEntry entry) { int counter = 0; int pos = forumEntries.indexOf(entry); if (pos >= 0) { - int ancestorLvl = forumEntries.get(pos).getLevel(); + int ancestorLvl = entry.getLevel(); for (int i = pos + 1; i < forumEntries.size(); i++) { int descendantLvl = forumEntries.get(i).getLevel(); if (descendantLvl <= ancestorLvl) @@ -210,14 +197,12 @@ public class NestedForumAdapter List<Integer> indexList = getSubTreeIndexes(visiblePos, forumEntry.getLevel()); if (!indexList.isEmpty()) { - if (Build.VERSION.SDK_INT >= 11) { - // stop animating children - for (int index : indexList) { - ValueAnimator anim = - animatingEntries.get(forumEntries.get(index)); - if (anim != null && anim.isRunning()) { - anim.cancel(); - } + // stop animating children + for (int index : indexList) { + ValueAnimator anim = + animatingEntries.get(forumEntries.get(index)); + if (anim != null && anim.isRunning()) { + anim.cancel(); } } if (indexList.size() == 1) { @@ -231,11 +216,18 @@ public class NestedForumAdapter } + /** + * + * @param position is visible entry index + * @return the visible entry at index position from an ordered list of visible + * entries, or null if position is larger then the number of visible entries. + */ @Nullable ForumEntry getVisibleEntry(int position) { int levelLimit = UNDEFINED; for (ForumEntry forumEntry : forumEntries) { if (levelLimit >= 0) { + // skip hidden entries that their parent is hiding if (forumEntry.getLevel() > levelLimit) { continue; } @@ -251,7 +243,6 @@ public class NestedForumAdapter return null; } - @TargetApi(11) private void animateFadeOut(final NestedForumHolder ui, final ForumEntry addedEntry) { ui.setIsRecyclable(false); @@ -341,9 +332,9 @@ public class NestedForumAdapter replies, replies)); } - if (hasDescendants(entry)) { + if (entry.hasDescendants()) { ui.chevron.setVisibility(VISIBLE); - if (hasVisibleDescendants(entry)) { + if (entry.isShowingDescendants()) { ui.chevron.setSelected(false); } else { ui.chevron.setSelected(true); @@ -369,9 +360,7 @@ public class NestedForumAdapter ui.cell.setBackgroundColor(ContextCompat .getColor(ctx, R.color.forum_cell_highlight)); - if (Build.VERSION.SDK_INT >= 11) { - animateFadeOut(ui, addedEntry); - } + animateFadeOut(ui, addedEntry); addedEntry = null; } else { ui.cell.setBackgroundColor(ContextCompat @@ -386,12 +375,24 @@ public class NestedForumAdapter }); } + public boolean isVisible(ForumEntry entry) { + return getVisiblePos(entry) != NO_POSITION; + } + + /** + * @param sEntry the ForumEntry to find the visible positoin of, or null to + * return the total cound of visible elements + * @return the visible position of sEntry, or the total number of visible + * elements if sEntry is null. If sEntry is not visible a NO_POSITION is + * returned. + */ private int getVisiblePos(ForumEntry sEntry) { int visibleCounter = 0; int levelLimit = UNDEFINED; for (ForumEntry fEntry : forumEntries) { if (levelLimit >= 0) { if (fEntry.getLevel() > levelLimit) { + // skip all the entries below a non visible branch continue; } levelLimit = UNDEFINED; @@ -440,6 +441,7 @@ public class NestedForumAdapter cell = (ViewGroup) v.findViewById(R.id.forum_cell); topDivider = v.findViewById(R.id.top_divider); } + } interface OnNestedForumListener { diff --git a/briar-android/src/org/briarproject/android/util/NestedTreeList.java b/briar-android/src/org/briarproject/android/util/NestedTreeList.java index 23ba02298d..d190a9f6de 100644 --- a/briar-android/src/org/briarproject/android/util/NestedTreeList.java +++ b/briar-android/src/org/briarproject/android/util/NestedTreeList.java @@ -1,5 +1,7 @@ package org.briarproject.android.util; +import android.support.annotation.UiThread; + import org.briarproject.api.clients.MessageTree; import org.briarproject.clients.MessageTreeImpl; @@ -8,7 +10,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; -/* This class is not thread safe */ +@UiThread public class NestedTreeList<T extends MessageTree.MessageNode> implements Iterable<T> { diff --git a/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java b/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java index 92023f7f91..3e5431ac94 100644 --- a/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java +++ b/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java @@ -7,7 +7,8 @@ import junit.framework.Assert; import org.briarproject.BuildConfig; import org.briarproject.TestUtils; import org.briarproject.android.TestBriarApplication; -import org.briarproject.android.controller.handler.UiResultHandler; +import org.briarproject.android.controller.handler.UiResultExceptionHandler; +import org.briarproject.api.db.DbException; import org.briarproject.api.identity.Author; import org.briarproject.api.identity.AuthorId; import org.briarproject.api.sync.GroupId; @@ -80,7 +81,8 @@ public class ForumActivityTest { private TestForumActivity forumActivity; @Captor - private ArgumentCaptor<UiResultHandler<List<ForumEntry>>> rc; + private ArgumentCaptor<UiResultExceptionHandler<List<ForumEntry>, DbException>> + rc; @Before public void setUp() { @@ -91,7 +93,6 @@ public class ForumActivityTest { .withIntent(intent).create().resume().get(); } - private List<ForumEntry> getDummyData() { ForumEntry[] forumEntries = new ForumEntry[6]; for (int i = 0; i < forumEntries.length; i++) { diff --git a/briar-api/src/org/briarproject/api/clients/MessageTree.java b/briar-api/src/org/briarproject/api/clients/MessageTree.java index 1c0c92e9fe..14481f2a56 100644 --- a/briar-api/src/org/briarproject/api/clients/MessageTree.java +++ b/briar-api/src/org/briarproject/api/clients/MessageTree.java @@ -16,6 +16,8 @@ public interface MessageTree<T extends MessageTree.MessageNode> { interface MessageNode { MessageId getId(); MessageId getParentId(); + void setLevel(int level); + void setDescendantCount(int descendantCount); long getTimestamp(); } diff --git a/briar-core/src/org/briarproject/clients/MessageTreeImpl.java b/briar-core/src/org/briarproject/clients/MessageTreeImpl.java index 2c6eb1344a..b1cd81a571 100644 --- a/briar-core/src/org/briarproject/clients/MessageTreeImpl.java +++ b/briar-core/src/org/briarproject/clients/MessageTreeImpl.java @@ -77,10 +77,13 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode> } - private void traverse(List<T> list, T node) { + private void traverse(List<T> list, T node, int level) { list.add(node); - for (T child : nodeMap.get(node.getId())) { - traverse(list, child); + List<T> children = nodeMap.get(node.getId()); + node.setLevel(level); + node.setDescendantCount(children.size()); + for (T child : children) { + traverse(list, child, level+1); } } @@ -98,7 +101,7 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode> public synchronized Collection<T> depthFirstOrder() { List<T> orderedList = new ArrayList<T>(); for (T root : roots) { - traverse(orderedList, root); + traverse(orderedList, root, 0); } return Collections.unmodifiableList(orderedList); } diff --git a/briar-tests/src/org/briarproject/clients/MessageTreeTest.java b/briar-tests/src/org/briarproject/clients/MessageTreeTest.java index 1c6e165311..e198db4719 100644 --- a/briar-tests/src/org/briarproject/clients/MessageTreeTest.java +++ b/briar-tests/src/org/briarproject/clients/MessageTreeTest.java @@ -86,6 +86,16 @@ public class MessageTreeTest { return parentId; } + @Override + public void setLevel(int level) { + + } + + @Override + public void setDescendantCount(int descendantCount) { + + } + @Override public long getTimestamp() { return timestamp; -- GitLab