From b2fa039474f631aa5114972098cf7e0ede3d21f4 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Mon, 3 Oct 2016 19:29:14 -0300 Subject: [PATCH] Refactor existing adapters into a generic superclass This commit also moves various blog classes into their own packages and makes the required visibility changes. --- .../layout/activity_fragment_container.xml | 12 +- .../android/blogs/BaseController.java | 2 +- .../android/blogs/BasePostFragment.java | 2 +- .../android/blogs/BlogActivity.java | 3 - .../android/blogs/BlogCommentItem.java | 4 +- .../android/blogs/BlogController.java | 4 - .../android/blogs/BlogControllerImpl.java | 7 +- .../android/blogs/BlogFragment.java | 2 +- .../briarproject/android/blogs/BlogItem.java | 44 +----- .../android/blogs/BlogPostAdapter.java | 80 ++--------- .../android/blogs/BlogPostItem.java | 5 +- .../android/blogs/BlogPostPagerFragment.java | 1 - .../android/blogs/BlogPostViewHolder.java | 5 +- .../android/blogs/FeedPostPagerFragment.java | 3 +- .../android/blogs/RssFeedAdapter.java | 109 +++----------- .../contact/BaseContactListAdapter.java | 136 +++++------------- .../android/contact/ContactListAdapter.java | 9 +- .../android/contact/ContactListFragment.java | 20 +-- .../android/contact/ConversationAdapter.java | 105 ++++---------- .../android/forum/ForumListAdapter.java | 118 +++++---------- .../android/forum/ForumListFragment.java | 5 +- .../introduction/ContactChooserAdapter.java | 5 +- .../sharing/BlogInvitationAdapter.java | 7 +- .../sharing/ContactSelectorAdapter.java | 15 +- .../sharing/ForumInvitationAdapter.java | 7 +- .../android/sharing/InvitationAdapter.java | 95 +++--------- .../android/sharing/SharingStatusAdapter.java | 6 - .../android/util/BriarAdapter.java | 106 ++++++++++++++ .../briarproject/android/view/AuthorView.java | 1 - 29 files changed, 304 insertions(+), 614 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/util/BriarAdapter.java diff --git a/briar-android/res/layout/activity_fragment_container.xml b/briar-android/res/layout/activity_fragment_container.xml index 8bf59ee5ac..e6c20760fb 100644 --- a/briar-android/res/layout/activity_fragment_container.xml +++ b/briar-android/res/layout/activity_fragment_container.xml @@ -3,14 +3,4 @@ android:id="@+id/fragmentContainer" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent"> - - <ProgressBar - android:id="@+id/progressBar" - style="?android:attr/progressBarStyleLarge" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:visibility="invisible"/> - -</FrameLayout> \ No newline at end of file + android:layout_height="match_parent"/> \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/blogs/BaseController.java b/briar-android/src/org/briarproject/android/blogs/BaseController.java index a7cf1e4243..bfd1a0b13a 100644 --- a/briar-android/src/org/briarproject/android/blogs/BaseController.java +++ b/briar-android/src/org/briarproject/android/blogs/BaseController.java @@ -11,7 +11,7 @@ import org.briarproject.api.sync.MessageId; import java.util.Collection; -public interface BaseController { +interface BaseController { @UiThread void onStart(); diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java index 06153e422f..85c5dff335 100644 --- a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java @@ -20,7 +20,7 @@ import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION; -public abstract class BasePostFragment extends BaseFragment { +abstract class BasePostFragment extends BaseFragment { private final Logger LOG = Logger.getLogger(BasePostFragment.class.getName()); diff --git a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java index 1b35bc5ced..5f4fc731db 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java @@ -21,8 +21,6 @@ public class BlogActivity extends BriarActivity implements static final String BLOG_NAME = "briar.BLOG_NAME"; static final String IS_NEW_BLOG = "briar.IS_NEW_BLOG"; - private ProgressBar progressBar; - @Inject BlogController blogController; @@ -45,7 +43,6 @@ public class BlogActivity extends BriarActivity implements boolean isNew = i.getBooleanExtra(IS_NEW_BLOG, false); setContentView(R.layout.activity_fragment_container); - progressBar = (ProgressBar) findViewById(R.id.progressBar); if (state == null) { BlogFragment f = BlogFragment.newInstance(groupId, blogName, isNew); diff --git a/briar-android/src/org/briarproject/android/blogs/BlogCommentItem.java b/briar-android/src/org/briarproject/android/blogs/BlogCommentItem.java index b3dea0b8c9..b463e31302 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogCommentItem.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogCommentItem.java @@ -1,7 +1,5 @@ package org.briarproject.android.blogs; -import android.support.annotation.UiThread; - import org.briarproject.api.blogs.BlogCommentHeader; import org.briarproject.api.blogs.BlogPostHeader; @@ -10,7 +8,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -@UiThread +// This class is not thread-safe class BlogCommentItem extends BlogPostItem { private static final BlogCommentComparator COMPARATOR = diff --git a/briar-android/src/org/briarproject/android/blogs/BlogController.java b/briar-android/src/org/briarproject/android/blogs/BlogController.java index 4d5c35cbc2..ba02cacd1c 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogController.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogController.java @@ -1,10 +1,6 @@ package org.briarproject.android.blogs; -import android.support.annotation.UiThread; - -import org.briarproject.android.controller.ActivityLifecycleController; import org.briarproject.android.controller.handler.ResultExceptionHandler; -import org.briarproject.api.blogs.BlogPostHeader; import org.briarproject.api.db.DbException; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; diff --git a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java index ad7b7597d2..ebc9764689 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java @@ -3,7 +3,6 @@ package org.briarproject.android.blogs; import org.briarproject.android.controller.ActivityLifecycleController; import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.api.blogs.Blog; -import org.briarproject.api.blogs.BlogPostHeader; import org.briarproject.api.db.DbException; import org.briarproject.api.event.BlogPostAddedEvent; import org.briarproject.api.event.Event; @@ -14,7 +13,6 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; import java.util.Collection; -import java.util.Collections; import java.util.logging.Logger; import javax.inject.Inject; @@ -108,9 +106,7 @@ public class BlogControllerImpl extends BaseControllerImpl Blog b = blogManager.getBlog(groupId); boolean ours = a.getId().equals(b.getAuthor().getId()); boolean removable = blogManager.canBeRemoved(groupId); - BlogItem blog = new BlogItem(b, - Collections.<BlogPostHeader>emptyList(), - ours, removable); + BlogItem blog = new BlogItem(b, ours, removable); handler.onResult(blog); } catch (DbException e) { if (LOG.isLoggable(WARNING)) @@ -119,7 +115,6 @@ public class BlogControllerImpl extends BaseControllerImpl } } }); - } @Override diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java index 4d5c1f5ce4..963b7175ea 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java @@ -62,7 +62,7 @@ public class BlogFragment extends BaseFragment implements private MenuItem writeButton, deleteButton; private boolean isMyBlog = false, canDeleteBlog = false; - static BlogFragment newInstance(GroupId groupId, String name, + static BlogFragment newInstance(GroupId groupId, @Nullable String name, boolean isNew) { BlogFragment f = new BlogFragment(); diff --git a/briar-android/src/org/briarproject/android/blogs/BlogItem.java b/briar-android/src/org/briarproject/android/blogs/BlogItem.java index 536d05f241..163840ae23 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogItem.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogItem.java @@ -1,40 +1,14 @@ package org.briarproject.android.blogs; import org.briarproject.api.blogs.Blog; -import org.briarproject.api.blogs.BlogPostHeader; - -import java.util.Collection; class BlogItem { private final Blog blog; - private final int postCount; - private final long timestamp; - private final int unread; private final boolean ours, removable; - BlogItem(Blog blog, Collection<BlogPostHeader> headers, boolean ours, - boolean removable) { + BlogItem(Blog blog, boolean ours, boolean removable) { this.blog = blog; - if (headers.isEmpty()) { - postCount = 0; - timestamp = 0; - unread = 0; - } else { - BlogPostHeader newest = null; - long timestamp = -1; - int unread = 0; - for (BlogPostHeader h : headers) { - if (h.getTimestamp() > timestamp) { - timestamp = h.getTimestamp(); - newest = h; - } - if (!h.isRead()) unread++; - } - this.postCount = headers.size(); - this.timestamp = newest.getTimestamp(); - this.unread = unread; - } this.ours = ours; this.removable = removable; } @@ -47,22 +21,6 @@ class BlogItem { return blog.getName(); } - boolean isEmpty() { - return postCount == 0; - } - - int getPostCount() { - return postCount; - } - - long getTimestamp() { - return timestamp; - } - - int getUnreadCount() { - return unread; - } - boolean isOurs() { return ours; } diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java b/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java index badf034503..ae67d9cfce 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java @@ -1,60 +1,20 @@ package org.briarproject.android.blogs; import android.content.Context; -import android.support.v7.util.SortedList; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import org.briarproject.R; +import org.briarproject.android.util.BriarAdapter; -import java.util.Collection; +class BlogPostAdapter + extends BriarAdapter<BlogPostItem, BlogPostViewHolder> { -class BlogPostAdapter extends RecyclerView.Adapter<BlogPostViewHolder> { - - private SortedList<BlogPostItem> posts = new SortedList<>( - BlogPostItem.class, new SortedList.Callback<BlogPostItem>() { - @Override - public int compare(BlogPostItem a, BlogPostItem b) { - return a.compareTo(b); - } - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @Override - public boolean areContentsTheSame(BlogPostItem a, BlogPostItem b) { - return a.isRead() == b.isRead(); - } - - @Override - public boolean areItemsTheSame(BlogPostItem a, BlogPostItem b) { - return a.getId().equals(b.getId()); - } - }); - private final Context ctx; private final OnBlogPostClickListener listener; BlogPostAdapter(Context ctx, OnBlogPostClickListener listener) { - this.ctx = ctx; + super(ctx, BlogPostItem.class); this.listener = listener; } @@ -70,36 +30,22 @@ class BlogPostAdapter extends RecyclerView.Adapter<BlogPostViewHolder> { @Override public void onBindViewHolder(BlogPostViewHolder ui, int position) { - ui.bindItem(getItem(position)); + ui.bindItem(getItemAt(position)); } @Override - public int getItemCount() { - return posts.size(); - } - - public BlogPostItem getItem(int position) { - return posts.get(position); + public int compare(BlogPostItem a, BlogPostItem b) { + return a.compareTo(b); } - public void add(BlogPostItem item) { - posts.add(item); - } - - public void addAll(Collection<BlogPostItem> items) { - posts.addAll(items); - } - - public void remove(BlogPostItem item) { - posts.remove(item); - } - - public void clear() { - posts.clear(); + @Override + public boolean areContentsTheSame(BlogPostItem a, BlogPostItem b) { + return a.isRead() == b.isRead(); } - public boolean isEmpty() { - return posts.size() == 0; + @Override + public boolean areItemsTheSame(BlogPostItem a, BlogPostItem b) { + return a.getId().equals(b.getId()); } interface OnBlogPostClickListener { diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java b/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java index 747b661593..64295c7317 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java @@ -2,7 +2,6 @@ package org.briarproject.android.blogs; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.annotation.UiThread; import org.briarproject.api.blogs.BlogPostHeader; import org.briarproject.api.identity.Author; @@ -10,8 +9,8 @@ import org.briarproject.api.identity.Author.Status; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; -@UiThread -class BlogPostItem implements Comparable<BlogPostItem> { +// This class is not thread-safe +public class BlogPostItem implements Comparable<BlogPostItem> { private final BlogPostHeader header; protected String body; diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java index f0a534b847..560e62e38b 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java @@ -12,7 +12,6 @@ import java.util.Collection; import javax.inject.Inject; - public class BlogPostPagerFragment extends BasePostPagerFragment { public final static String TAG = BlogPostPagerFragment.class.getName(); diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java index ddf71da941..865b0df355 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java @@ -3,6 +3,7 @@ package org.briarproject.android.blogs; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; @@ -85,7 +86,9 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder { return "blogPost" + id.hashCode(); } - void bindItem(final BlogPostItem item) { + void bindItem(@Nullable final BlogPostItem item) { + if (item == null) return; + setTransitionName(item.getId()); if (listener != null) { layout.setClickable(true); diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java index ab9444104c..5f5c351dc1 100644 --- a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java @@ -40,7 +40,7 @@ public class FeedPostPagerFragment extends BasePostPagerFragment { return TAG; } - + @Override void loadBlogPosts(final MessageId select) { feedController.loadBlogPosts( new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>( @@ -57,6 +57,7 @@ public class FeedPostPagerFragment extends BasePostPagerFragment { }); } + @Override void loadBlogPost(BlogPostHeader header) { feedController.loadBlogPost(header, new UiResultExceptionHandler<BlogPostItem, DbException>( diff --git a/briar-android/src/org/briarproject/android/blogs/RssFeedAdapter.java b/briar-android/src/org/briarproject/android/blogs/RssFeedAdapter.java index 2ad13eb343..aa92468158 100644 --- a/briar-android/src/org/briarproject/android/blogs/RssFeedAdapter.java +++ b/briar-android/src/org/briarproject/android/blogs/RssFeedAdapter.java @@ -1,8 +1,6 @@ package org.briarproject.android.blogs; -import android.app.Activity; -import android.support.annotation.Nullable; -import android.support.v7.util.SortedList; +import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -13,67 +11,18 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.util.AndroidUtils; +import org.briarproject.android.util.BriarAdapter; import org.briarproject.api.feed.Feed; -import org.briarproject.api.sync.GroupId; - -import java.util.Collection; import static android.view.View.GONE; import static android.view.View.VISIBLE; -class RssFeedAdapter extends - RecyclerView.Adapter<RssFeedAdapter.FeedViewHolder> { - - private SortedList<Feed> feeds = new SortedList<>( - Feed.class, new SortedList.Callback<Feed>() { - - @Override - public int compare(Feed a, Feed b) { - if (a == b) return 0; - long aTime = a.getAdded(), bTime = b.getAdded(); - if (aTime > bTime) return -1; - if (aTime < bTime) return 1; - return 0; - } - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @Override - public boolean areContentsTheSame(Feed a, Feed b) { - return a.getUpdated() == b.getUpdated(); - } - - @Override - public boolean areItemsTheSame(Feed a, Feed b) { - return a.getUrl().equals(b.getUrl()) && - a.getBlogId().equals(b.getBlogId()) && - a.getAdded() == b.getAdded(); - } - }); +class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> { - private final Activity ctx; private final RssFeedListener listener; - RssFeedAdapter(Activity ctx, RssFeedListener listener) { - this.ctx = ctx; + RssFeedAdapter(Context ctx, RssFeedListener listener) { + super(ctx, Feed.class); this.listener = listener; } @@ -86,7 +35,8 @@ class RssFeedAdapter extends @Override public void onBindViewHolder(FeedViewHolder ui, int position) { - final Feed item = getItem(position); + final Feed item = getItemAt(position); + if (item == null) return; // Feed Title if (item.getTitle() != null) { @@ -128,39 +78,24 @@ class RssFeedAdapter extends } @Override - public int getItemCount() { - return feeds.size(); - } - - public Feed getItem(int position) { - return feeds.get(position); - } - - @Nullable - public Feed getItem(GroupId g) { - for (int i = 0; i < feeds.size(); i++) { - Feed item = feeds.get(i); - if (item.getBlogId().equals(g)) { - return item; - } - } - return null; - } - - public void addAll(Collection<Feed> items) { - feeds.addAll(items); + public int compare(Feed a, Feed b) { + if (a == b) return 0; + long aTime = a.getAdded(), bTime = b.getAdded(); + if (aTime > bTime) return -1; + if (aTime < bTime) return 1; + return 0; } - public void remove(Feed item) { - feeds.remove(item); - } - - public void clear() { - feeds.clear(); + @Override + public boolean areContentsTheSame(Feed a, Feed b) { + return a.getUpdated() == b.getUpdated(); } - public boolean isEmpty() { - return feeds.size() == 0; + @Override + public boolean areItemsTheSame(Feed a, Feed b) { + return a.getUrl().equals(b.getUrl()) && + a.getBlogId().equals(b.getBlogId()) && + a.getAdded() == b.getAdded(); } static class FeedViewHolder extends RecyclerView.ViewHolder { @@ -172,7 +107,7 @@ class RssFeedAdapter extends private final TextView authorLabel; private final TextView description; - FeedViewHolder(View v) { + private FeedViewHolder(View v) { super(v); title = (TextView) v.findViewById(R.id.titleView); diff --git a/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java index a784a9d909..b1ab777c44 100644 --- a/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java @@ -1,8 +1,8 @@ package org.briarproject.android.contact; import android.content.Context; +import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; -import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; @@ -10,34 +10,32 @@ import android.widget.ImageView; import android.widget.TextView; import org.briarproject.R; +import org.briarproject.android.util.BriarAdapter; import org.briarproject.api.contact.ContactId; import org.briarproject.api.identity.Author; import org.briarproject.api.sync.GroupId; import org.briarproject.util.StringUtils; -import java.util.List; - import im.delight.android.identicons.IdenticonDrawable; import static android.support.v7.util.SortedList.INVALID_POSITION; public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.BaseContactHolder> - extends RecyclerView.Adapter<VH> { + extends BriarAdapter<ContactListItem, VH> { - protected final SortedList<ContactListItem> contacts; + @Nullable protected final OnItemClickListener listener; - protected Context ctx; - public BaseContactListAdapter(Context ctx, OnItemClickListener listener) { - this.ctx = ctx; + public BaseContactListAdapter(Context ctx, + @Nullable OnItemClickListener listener) { + super(ctx, ContactListItem.class); this.listener = listener; - this.contacts = new SortedList<>(ContactListItem.class, - new SortedListCallBacks()); } @Override public void onBindViewHolder(final VH ui, int position) { - final ContactListItem item = getItem(position); + final ContactListItem item = getItemAt(position); + if (item == null) return; Author author = item.getContact().getAuthor(); ui.avatar.setImageDrawable( @@ -59,30 +57,37 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B } @Override - public int getItemCount() { - return contacts.size(); - } - - public ContactListItem getItem(int position) { - if (position == INVALID_POSITION || contacts.size() <= position) { - return null; // Not found - } - return contacts.get(position); + public int compare(ContactListItem c1, ContactListItem c2) { + return compareByName(c1, c2); } - void updateItem(int position, ContactListItem item) { - contacts.updateItemAt(position, item); + @Override + public boolean areItemsTheSame(ContactListItem c1, ContactListItem c2) { + return c1.getContact().getId().equals(c2.getContact().getId()); } - public int findItemPosition(ContactListItem c) { - return contacts.indexOf(c); + @Override + public boolean areContentsTheSame(ContactListItem c1, ContactListItem c2) { + // check for all properties that influence visual + // representation of contact + if (c1.isConnected() != c2.isConnected()) { + return false; + } + if (c1.getUnreadCount() != c2.getUnreadCount()) { + return false; + } + if (c1.getTimestamp() != c2.getTimestamp()) { + return false; + } + return true; } int findItemPosition(ContactId c) { int count = getItemCount(); for (int i = 0; i < count; i++) { - ContactListItem item = getItem(i); - if (item.getContact().getId().equals(c)) return i; + ContactListItem item = getItemAt(i); + if (item != null && item.getContact().getId().equals(c)) + return i; } return INVALID_POSITION; // Not found } @@ -90,28 +95,13 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B int findItemPosition(GroupId g) { int count = getItemCount(); for (int i = 0; i < count; i++) { - ContactListItem item = getItem(i); - if (item.getGroupId().equals(g)) return i; + ContactListItem item = getItemAt(i); + if (item != null && item.getGroupId().equals(g)) + return i; } return INVALID_POSITION; // Not found } - public void addAll(List<ContactListItem> contacts) { - this.contacts.addAll(contacts); - } - - public void add(ContactListItem contact) { - contacts.add(contact); - } - - public void remove(ContactListItem contact) { - contacts.remove(contact); - } - - public void clear() { - contacts.clear(); - } - public static class BaseContactHolder extends RecyclerView.ViewHolder { public final ViewGroup layout; @@ -127,10 +117,6 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B } } - public int compareContactListItems(ContactListItem c1, ContactListItem c2) { - return compareByName(c1, c2); - } - protected int compareByName(ContactListItem c1, ContactListItem c2) { int authorCompare = c1.getLocalAuthor().getName() .compareTo(c2.getLocalAuthor().getName()); @@ -142,7 +128,7 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B } } - int compareByTime(ContactListItem c1, ContactListItem c2) { + protected int compareByTime(ContactListItem c1, ContactListItem c2) { long time1 = c1.getTimestamp(); long time2 = c2.getTimestamp(); if (time1 < time2) return 1; @@ -150,58 +136,8 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B return 0; } - private class SortedListCallBacks - extends SortedList.Callback<ContactListItem> { - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public int compare(ContactListItem c1, ContactListItem c2) { - return compareContactListItems(c1, c2); - } - - @Override - public boolean areItemsTheSame(ContactListItem c1, ContactListItem c2) { - return c1.getContact().getId().equals(c2.getContact().getId()); - } - - @Override - public boolean areContentsTheSame(ContactListItem c1, - ContactListItem c2) { - // check for all properties that influence visual - // representation of contact - if (c1.isConnected() != c2.isConnected()) { - return false; - } - if (c1.getUnreadCount() != c2.getUnreadCount()) { - return false; - } - if (c1.getTimestamp() != c2.getTimestamp()) { - return false; - } - return true; - } - } - public interface OnItemClickListener { void onItemClick(View view, ContactListItem item); } + } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java index 6ae5c46d79..a2cf8012d3 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java @@ -31,7 +31,8 @@ public class ContactListAdapter public void onBindViewHolder(ContactHolder ui, int position) { super.onBindViewHolder(ui, position); - ContactListItem item = getItem(position); + ContactListItem item = getItemAt(position); + if (item == null) return; // unread count int unread = item.getUnreadCount(); @@ -65,11 +66,11 @@ public class ContactListAdapter extends BaseContactListAdapter.BaseContactHolder { public final ImageView bulb; - final TextView unread; + private final TextView unread; public final TextView date; public final TextView identity; - ContactHolder(View v) { + private ContactHolder(View v) { super(v); bulb = (ImageView) v.findViewById(R.id.bulbView); @@ -80,7 +81,7 @@ public class ContactListAdapter } @Override - public int compareContactListItems(ContactListItem c1, ContactListItem c2) { + public int compare(ContactListItem c1, ContactListItem c2) { return compareByTime(c1, c2); } } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index 312184f77d..5feb4d3a15 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -97,9 +97,9 @@ public class ContactListFragment extends BaseFragment implements EventListener { protected volatile BlogSharingManager blogSharingManager; public static ContactListFragment newInstance() { - + Bundle args = new Bundle(); - + ContactListFragment fragment = new ContactListFragment(); fragment.setArguments(args); return fragment; @@ -320,10 +320,10 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { int position = adapter.findItemPosition(c); - ContactListItem item = adapter.getItem(position); + ContactListItem item = adapter.getItemAt(position); if (item != null) { item.setMessages(messages); - adapter.updateItem(position, item); + adapter.updateItemAt(position, item); } } }); @@ -334,10 +334,10 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { int position = adapter.findItemPosition(c); - ContactListItem item = adapter.getItem(position); + ContactListItem item = adapter.getItemAt(position); if (item != null) { item.addMessage(m); - adapter.updateItem(position, item); + adapter.updateItemAt(position, item); } } }); @@ -348,10 +348,10 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { int position = adapter.findItemPosition(g); - ContactListItem item = adapter.getItem(position); + ContactListItem item = adapter.getItemAt(position); if (item != null) { item.addMessage(m); - adapter.updateItem(position, item); + adapter.updateItemAt(position, item); } } }); @@ -362,7 +362,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { int position = adapter.findItemPosition(c); - ContactListItem item = adapter.getItem(position); + ContactListItem item = adapter.getItemAt(position); if (item != null) adapter.remove(item); } }); @@ -373,7 +373,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { @Override public void run() { int position = adapter.findItemPosition(c); - ContactListItem item = adapter.getItem(position); + ContactListItem item = adapter.getItemAt(position); if (item != null) { item.setConnected(connected); adapter.notifyItemChanged(position); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index e86189f31a..3fa184bf2f 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -2,7 +2,7 @@ package org.briarproject.android.contact; import android.content.Context; import android.content.Intent; -import android.support.v7.util.SortedList; +import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.LayoutInflater; @@ -16,6 +16,7 @@ import org.briarproject.R; import org.briarproject.android.sharing.InvitationsBlogActivity; import org.briarproject.android.sharing.InvitationsForumActivity; import org.briarproject.android.util.AndroidUtils; +import org.briarproject.android.util.BriarAdapter; import org.briarproject.api.blogs.BlogInvitationRequest; import org.briarproject.api.clients.SessionId; import org.briarproject.api.forum.ForumInvitationRequest; @@ -24,9 +25,6 @@ import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.util.StringUtils; -import java.util.List; - -import static android.support.v7.util.SortedList.INVALID_POSITION; import static android.support.v7.widget.RecyclerView.ViewHolder; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -43,18 +41,13 @@ import static org.briarproject.android.contact.ConversationItem.NOTICE_IN; import static org.briarproject.android.contact.ConversationItem.NOTICE_OUT; import static org.briarproject.android.contact.ConversationItem.OutgoingItem; -class ConversationAdapter extends RecyclerView.Adapter { - - private final SortedList<ConversationItem> items = - new SortedList<>(ConversationItem.class, new ListCallbacks()); +class ConversationAdapter extends BriarAdapter<ConversationItem, ViewHolder> { - private Context ctx; private IntroductionHandler intro; private String contactName; - ConversationAdapter(Context context, - IntroductionHandler introductionHandler) { - ctx = context; + ConversationAdapter(Context ctx, IntroductionHandler introductionHandler) { + super(ctx, ConversationItem.class); intro = introductionHandler; } @@ -65,7 +58,7 @@ class ConversationAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { - return getItem(position).getType(); + return items.get(position).getType(); } @Override @@ -114,7 +107,7 @@ class ConversationAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(ViewHolder ui, int position) { - ConversationItem item = getItem(position); + ConversationItem item = getItemAt(position); if (item instanceof ConversationMessageItem) { bindMessage((MessageHolder) ui, (ConversationMessageItem) item); } else if (item instanceof ConversationIntroductionOutItem) { @@ -370,17 +363,28 @@ class ConversationAdapter extends RecyclerView.Adapter { } @Override - public int getItemCount() { - return items.size(); + public int compare(ConversationItem c1, + ConversationItem c2) { + long time1 = c1.getTime(); + long time2 = c2.getTime(); + if (time1 < time2) return -1; + if (time1 > time2) return 1; + return 0; } - public ConversationItem getItem(int position) { - if (position == INVALID_POSITION || items.size() <= position) { - return null; // Not found - } - return items.get(position); + @Override + public boolean areItemsTheSame(ConversationItem c1, + ConversationItem c2) { + return c1.getId().equals(c2.getId()); } + @Override + public boolean areContentsTheSame(ConversationItem c1, + ConversationItem c2) { + return c1.equals(c2); + } + + @Nullable ConversationItem getLastItem() { if (items.size() > 0) { return items.get(items.size() - 1); @@ -425,23 +429,11 @@ class ConversationAdapter extends RecyclerView.Adapter { return messages; } - public void add(final ConversationItem message) { - this.items.add(message); - } - - public void clear() { - items.clear(); - } - - public void addAll(List<ConversationItem> items) { - this.items.addAll(items); - } - private static class MessageHolder extends RecyclerView.ViewHolder { public ViewGroup layout; public TextView body; - public TextView date; + private TextView date; public ImageView status; private MessageHolder(View v, int type) { @@ -532,51 +524,6 @@ class ConversationAdapter extends RecyclerView.Adapter { } } - private class ListCallbacks extends SortedList.Callback<ConversationItem> { - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public int compare(ConversationItem c1, - ConversationItem c2) { - long time1 = c1.getTime(); - long time2 = c2.getTime(); - if (time1 < time2) return -1; - if (time1 > time2) return 1; - return 0; - } - - @Override - public boolean areItemsTheSame(ConversationItem c1, - ConversationItem c2) { - return c1.getId().equals(c2.getId()); - } - - @Override - public boolean areContentsTheSame(ConversationItem c1, - ConversationItem c2) { - return c1.equals(c2); - } - } - interface IntroductionHandler { void respondToIntroduction(SessionId sessionId, boolean accept); } diff --git a/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java b/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java index d37f23a029..9c3ba15fe3 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.Intent; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; -import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -13,73 +12,21 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.util.AndroidUtils; +import org.briarproject.android.util.BriarAdapter; import org.briarproject.android.view.TextAvatarView; import org.briarproject.api.forum.Forum; import org.briarproject.api.sync.GroupId; -import java.util.Collection; - import static android.view.View.GONE; import static android.view.View.VISIBLE; import static org.briarproject.android.BriarActivity.GROUP_ID; import static org.briarproject.android.forum.ForumActivity.FORUM_NAME; -class ForumListAdapter extends - RecyclerView.Adapter<ForumListAdapter.ForumViewHolder> { - - private SortedList<ForumListItem> forums = new SortedList<>( - ForumListItem.class, new SortedList.Callback<ForumListItem>() { - - @Override - public int compare(ForumListItem a, ForumListItem b) { - if (a == b) return 0; - // The forum with the newest message comes first - long aTime = a.getTimestamp(), bTime = b.getTimestamp(); - if (aTime > bTime) return -1; - if (aTime < bTime) return 1; - // Break ties by forum name - String aName = a.getForum().getName(); - String bName = b.getForum().getName(); - return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); - } - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @Override - public boolean areContentsTheSame(ForumListItem a, ForumListItem b) { - return a.getForum().equals(b.getForum()) && - a.getTimestamp() == b.getTimestamp() && - a.getUnreadCount() == b.getUnreadCount(); - } - - @Override - public boolean areItemsTheSame(ForumListItem a, ForumListItem b) { - return a.getForum().equals(b.getForum()); - } - }); - - private final Context ctx; +class ForumListAdapter + extends BriarAdapter<ForumListItem, ForumListAdapter.ForumViewHolder> { ForumListAdapter(Context ctx) { - this.ctx = ctx; + super(ctx, ForumListItem.class); } @Override @@ -91,7 +38,8 @@ class ForumListAdapter extends @Override public void onBindViewHolder(ForumViewHolder ui, int position) { - final ForumListItem item = getItem(position); + final ForumListItem item = getItemAt(position); + if (item == null) return; // Avatar ui.avatar.setText(item.getForum().getName().substring(0, 1)); @@ -142,18 +90,34 @@ class ForumListAdapter extends } @Override - public int getItemCount() { - return forums.size(); + public int compare(ForumListItem a, ForumListItem b) { + if (a == b) return 0; + // The forum with the newest message comes first + long aTime = a.getTimestamp(), bTime = b.getTimestamp(); + if (aTime > bTime) return -1; + if (aTime < bTime) return 1; + // Break ties by forum name + String aName = a.getForum().getName(); + String bName = b.getForum().getName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); } - public ForumListItem getItem(int position) { - return forums.get(position); + @Override + public boolean areContentsTheSame(ForumListItem a, ForumListItem b) { + return a.getForum().equals(b.getForum()) && + a.getTimestamp() == b.getTimestamp() && + a.getUnreadCount() == b.getUnreadCount(); + } + + @Override + public boolean areItemsTheSame(ForumListItem a, ForumListItem b) { + return a.getForum().equals(b.getForum()); } @Nullable - public ForumListItem getItem(GroupId g) { - for (int i = 0; i < forums.size(); i++) { - ForumListItem item = forums.get(i); + public ForumListItem findItem(GroupId g) { + for (int i = 0; i < items.size(); i++) { + ForumListItem item = items.get(i); if (item.getForum().getGroup().getId().equals(g)) { return item; } @@ -161,26 +125,10 @@ class ForumListAdapter extends return null; } - public void addAll(Collection<ForumListItem> items) { - forums.addAll(items); - } - void updateItem(ForumListItem item) { - ForumListItem oldItem = getItem(item.getForum().getGroup().getId()); - int position = forums.indexOf(oldItem); - forums.updateItemAt(position, item); - } - - public void remove(ForumListItem item) { - forums.remove(item); - } - - public void clear() { - forums.clear(); - } - - public boolean isEmpty() { - return forums.size() == 0; + ForumListItem oldItem = findItem(item.getForum().getGroup().getId()); + int position = items.indexOf(oldItem); + items.updateItemAt(position, item); } static class ForumViewHolder extends RecyclerView.ViewHolder { @@ -191,7 +139,7 @@ class ForumListAdapter extends private final TextView postCount; private final TextView date; - ForumViewHolder(View v) { + private ForumViewHolder(View v) { super(v); layout = (ViewGroup) v; diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index fc9f63b37d..94f2e2e4e3 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -11,6 +11,7 @@ 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; @@ -44,7 +45,7 @@ import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; public class ForumListFragment extends BaseEventFragment implements - View.OnClickListener { + OnClickListener { public final static String TAG = "ForumListFragment"; @@ -288,7 +289,7 @@ public class ForumListFragment extends BaseEventFragment implements listener.runOnUiThread(new Runnable() { @Override public void run() { - ForumListItem item = adapter.getItem(g); + ForumListItem item = adapter.findItem(g); if (item != null) adapter.remove(item); } }); diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserAdapter.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserAdapter.java index a0629d5d2e..059ab8cd11 100644 --- a/briar-android/src/org/briarproject/android/introduction/ContactChooserAdapter.java +++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserAdapter.java @@ -21,7 +21,8 @@ public class ContactChooserAdapter extends ContactListAdapter { public void onBindViewHolder(final ContactHolder ui, final int position) { super.onBindViewHolder(ui, position); - final ContactListItem item = getItem(position); + final ContactListItem item = getItemAt(position); + if (item == null) return; ui.name.setText(item.getContact().getAuthor().getName()); @@ -34,7 +35,7 @@ public class ContactChooserAdapter extends ContactListAdapter { } @Override - public int compareContactListItems(ContactListItem c1, ContactListItem c2) { + public int compare(ContactListItem c1, ContactListItem c2) { return compareByName(c1, c2); } diff --git a/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java index 78b0e34b6c..7b0e7dfa6e 100644 --- a/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/BlogInvitationAdapter.java @@ -15,7 +15,9 @@ class BlogInvitationAdapter extends InvitationAdapter { @Override public void onBindViewHolder(InvitationsViewHolder ui, int position) { super.onBindViewHolder(ui, position); - InvitationItem item = getItem(position); + InvitationItem item = getItemAt(position); + if (item == null) return; + Blog blog = (Blog) item.getShareable(); ui.avatar.setAuthorAvatar(blog.getAuthor()); @@ -28,7 +30,8 @@ class BlogInvitationAdapter extends InvitationAdapter { } } - int compareInvitations(InvitationItem o1, InvitationItem o2) { + @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/ContactSelectorAdapter.java b/briar-android/src/org/briarproject/android/sharing/ContactSelectorAdapter.java index 422022baa6..0d4d68912f 100644 --- a/briar-android/src/org/briarproject/android/sharing/ContactSelectorAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/ContactSelectorAdapter.java @@ -9,7 +9,6 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.contact.BaseContactListAdapter; -import org.briarproject.android.contact.ContactListItem; import org.briarproject.api.contact.ContactId; import java.util.ArrayList; @@ -41,7 +40,8 @@ class ContactSelectorAdapter super.onBindViewHolder(ui, position); SelectableContactListItem item = - (SelectableContactListItem) getItem(position); + (SelectableContactListItem) getItemAt(position); + if (item == null) return; if (item.isSelected()) { ui.checkBox.setChecked(true); @@ -64,9 +64,9 @@ class ContactSelectorAdapter Collection<ContactId> getSelectedContactIds() { Collection<ContactId> selected = new ArrayList<>(); - for (int i = 0; i < contacts.size(); i++) { + for (int i = 0; i < items.size(); i++) { SelectableContactListItem item = - (SelectableContactListItem) contacts.get(i); + (SelectableContactListItem) items.get(i); if (item.isSelected()) selected.add(item.getContact().getId()); } @@ -79,7 +79,7 @@ class ContactSelectorAdapter private final CheckBox checkBox; private final TextView shared; - SelectableContactHolder(View v) { + private SelectableContactHolder(View v) { super(v); checkBox = (CheckBox) v.findViewById(R.id.checkBox); @@ -87,11 +87,6 @@ class ContactSelectorAdapter } } - @Override - public int compareContactListItems(ContactListItem c1, ContactListItem c2) { - return compareByName(c1, c2); - } - private void grayOutItem(SelectableContactHolder ui, boolean gray) { float alpha = gray ? 0.25f : 1f; ui.avatar.setAlpha(alpha); diff --git a/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java b/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java index 1535b8cdc0..cfe914a9c2 100644 --- a/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/ForumInvitationAdapter.java @@ -14,7 +14,9 @@ class ForumInvitationAdapter extends InvitationAdapter { @Override public void onBindViewHolder(InvitationsViewHolder ui, int position) { super.onBindViewHolder(ui, position); - InvitationItem item = getItem(position); + InvitationItem item = getItemAt(position); + if (item == null) return; + Forum forum = (Forum) item.getShareable(); ui.avatar.setText(forum.getName().substring(0, 1)); @@ -23,7 +25,8 @@ class ForumInvitationAdapter extends InvitationAdapter { ui.name.setText(forum.getName()); } - int compareInvitations(InvitationItem o1, InvitationItem o2) { + @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 00852f7e9c..db35fd55bc 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationAdapter.java @@ -1,7 +1,6 @@ package org.briarproject.android.sharing; import android.content.Context; -import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -10,6 +9,7 @@ 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; @@ -22,16 +22,12 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; abstract class InvitationAdapter extends - RecyclerView.Adapter<InvitationAdapter.InvitationsViewHolder> { + BriarAdapter<InvitationItem, InvitationAdapter.InvitationsViewHolder> { - protected final Context ctx; private final AvailableForumClickListener listener; - private final SortedList<InvitationItem> invitations = - new SortedList<>(InvitationItem.class, - new SortedListCallBacks()); InvitationAdapter(Context ctx, AvailableForumClickListener listener) { - this.ctx = ctx; + super(ctx, InvitationItem.class); this.listener = listener; } @@ -46,7 +42,8 @@ abstract class InvitationAdapter extends @Override public void onBindViewHolder(InvitationsViewHolder ui, int position) { - final InvitationItem item = getItem(position); + final InvitationItem item = getItemAt(position); + if (item == null) return; Collection<String> names = new ArrayList<>(); for (Contact c : item.getNewSharers()) @@ -75,40 +72,28 @@ abstract class InvitationAdapter extends } @Override - public int getItemCount() { - return invitations.size(); + public boolean areContentsTheSame(InvitationItem oldItem, + InvitationItem newItem) { + return oldItem.isSubscribed() == newItem.isSubscribed() && + oldItem.getNewSharers().equals(newItem.getNewSharers()); } - public InvitationItem getItem(int position) { - return invitations.get(position); - } - - public void add(InvitationItem item) { - invitations.add(item); - } - - public void addAll(Collection<InvitationItem> list) { - invitations.addAll(list); - } - - public void remove(InvitationItem item) { - invitations.remove(item); - } - - public void clear() { - invitations.clear(); + @Override + public boolean areItemsTheSame(InvitationItem oldItem, + InvitationItem newItem) { + return oldItem.getShareable().equals(newItem.getShareable()); } static class InvitationsViewHolder extends RecyclerView.ViewHolder { final TextAvatarView avatar; final TextView name; - final TextView sharedBy; + private final TextView sharedBy; final TextView subscribed; - final Button accept; - final Button decline; + private final Button accept; + private final Button decline; - InvitationsViewHolder(View v) { + private InvitationsViewHolder(View v) { super(v); avatar = (TextAvatarView) v.findViewById(R.id.avatarView); @@ -120,52 +105,6 @@ abstract class InvitationAdapter extends } } - abstract int compareInvitations(InvitationItem o1, InvitationItem o2); - - private class SortedListCallBacks - extends SortedList.Callback<InvitationItem> { - - @Override - public int compare(InvitationItem o1, - InvitationItem o2) { - return compareInvitations(o1, o2); - } - - @Override - public void onInserted(int position, int count) { - notifyItemRangeInserted(position, count); - } - - @Override - public void onRemoved(int position, int count) { - notifyItemRangeRemoved(position, count); - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onChanged(int position, int count) { - notifyItemRangeChanged(position, count); - } - - @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) { - return oldItem.getShareable().equals(newItem.getShareable()); - } - } - - interface AvailableForumClickListener { void onItemClick(InvitationItem item, boolean accept); } diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusAdapter.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusAdapter.java index 18f70fe78b..5f7dd803da 100644 --- a/briar-android/src/org/briarproject/android/sharing/SharingStatusAdapter.java +++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusAdapter.java @@ -7,7 +7,6 @@ import android.view.ViewGroup; import org.briarproject.R; import org.briarproject.android.contact.BaseContactListAdapter; -import org.briarproject.android.contact.ContactListItem; class SharingStatusAdapter extends BaseContactListAdapter<BaseContactListAdapter.BaseContactHolder> { @@ -24,9 +23,4 @@ class SharingStatusAdapter return new BaseContactHolder(v); } - @Override - public int compareContactListItems(ContactListItem c1, ContactListItem c2) { - return compareByName(c1, c2); - } - } diff --git a/briar-android/src/org/briarproject/android/util/BriarAdapter.java b/briar-android/src/org/briarproject/android/util/BriarAdapter.java new file mode 100644 index 0000000000..0385c56c36 --- /dev/null +++ b/briar-android/src/org/briarproject/android/util/BriarAdapter.java @@ -0,0 +1,106 @@ +package org.briarproject.android.util; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v7.util.SortedList; +import android.support.v7.widget.RecyclerView.Adapter; +import android.support.v7.widget.RecyclerView.ViewHolder; + +import java.util.Collection; + +import static android.support.v7.util.SortedList.INVALID_POSITION; + +public abstract class BriarAdapter<T, V extends ViewHolder> + extends Adapter<V> { + + protected final Context ctx; + protected final SortedList<T> items; + + public BriarAdapter(Context ctx, Class<T> c) { + this.ctx = ctx; + this.items = new SortedList<>(c, new SortedList.Callback<T>() { + @Override + public int compare(T item1, T item2) { + return BriarAdapter.this.compare(item1, item2); + } + + @Override + public void onInserted(int position, int count) { + notifyItemRangeInserted(position, count); + } + + @Override + public void onRemoved(int position, int count) { + notifyItemRangeRemoved(position, count); + } + + @Override + public void onMoved(int fromPosition, int toPosition) { + notifyItemMoved(fromPosition, toPosition); + } + + @Override + public void onChanged(int position, int count) { + notifyItemRangeChanged(position, count); + } + + @Override + public boolean areContentsTheSame(T item1, T item2) { + return BriarAdapter.this.areContentsTheSame(item1, item2); + } + + @Override + public boolean areItemsTheSame(T item1, T item2) { + return BriarAdapter.this.areItemsTheSame(item1, item2); + } + }); + } + + public abstract int compare(T item1, T item2); + + public abstract boolean areContentsTheSame(T item1, T item2); + + public abstract boolean areItemsTheSame(T item1, T item2); + + @Override + public int getItemCount() { + return items.size(); + } + + public void add(T item) { + items.add(item); + } + + public void addAll(Collection<T> items) { + this.items.addAll(items); + } + + @Nullable + public T getItemAt(int position) { + if (position == INVALID_POSITION || position >= items.size()) { + return null; + } + return items.get(position); + } + + public int findItemPosition(T item) { + return items.indexOf(item); + } + + public void updateItemAt(int position, T item) { + items.updateItemAt(position, item); + } + + public void remove(T item) { + items.remove(item); + } + + public void clear() { + items.clear(); + } + + public boolean isEmpty() { + return items.size() == 0; + } + +} diff --git a/briar-android/src/org/briarproject/android/view/AuthorView.java b/briar-android/src/org/briarproject/android/view/AuthorView.java index 40f8e50693..2a1e928cda 100644 --- a/briar-android/src/org/briarproject/android/view/AuthorView.java +++ b/briar-android/src/org/briarproject/android/view/AuthorView.java @@ -20,7 +20,6 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.android.blogs.BlogActivity; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.android.view.TrustIndicatorView; import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author.Status; import org.briarproject.api.sync.GroupId; -- GitLab