diff --git a/briar-android/res/layout/activity_fragment_container.xml b/briar-android/res/layout/activity_fragment_container.xml index 8bf59ee5acc2ae1186ebae445268a3028fbb7bae..e6c20760fb5078de5def86eec38402fc2db9042a 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 a7cf1e4243eebaa076e59f7ecedc373b5cf2251c..bfd1a0b13ae9bbeac959058b58c67e1173b0269d 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 06153e422f286c8278c811af08c4d1b53e32a9d0..85c5dff3359c65e651c4e7e00ed41e8de818610f 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 1b35bc5ced54153325ef84a420fdd238e410f53e..5f4fc731db722f32c588a1114e2ad4b0514998b5 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 b3dea0b8c96a5faf7753d96ceec98efb47c69b25..b463e3130261d81b4a31965befd596ebb7b268e5 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 4d5c35cbc2d3efc3572cadd6c19983376e671e9b..ba02cacd1c594772b806a4a8cb4c1b37437175dd 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 ad7b7597d2e40387fb7acb3f0e1f518d68810fa8..ebc976468917ecb47d62e1131b3ed61b5b5e162d 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 4d5c1f5ce433f6b6c69c3ce66f6c1a636f2422a6..963b7175ea740ac116deec87081c5d18b5054499 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 536d05f241f305b9043441521aed197fd464fce0..163840ae23706ed915fdd06a66bdbcc73e72e7ed 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 badf034503d5d99fc57e0a89860d8abe99b9a5f5..ae67d9cfcec82119979d41108c304df58a5afce9 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 747b661593e1d0cb12f6efd2dc73a247c08dcff1..64295c731713576dad6f891dcab7ca0a46b61e04 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 f0a534b84714e8616dc77b07d671167ce76ebb12..560e62e38bacf01221f4addc89bff3eb101ab8d9 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 ddf71da9410be1457875b6f55f862e230c8f91df..865b0df35511a763c74b611cbb7b99af3399e0ff 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 ab9444104c6b3a84496be03d97cbe9d81a26f941..5f5c351dc1a465dcf880caa26cf22250b48b74f1 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 2ad13eb343991cda0740c1eb1e4d9d7061851b8c..aa92468158054470d8377118fb1edf3659cf54ed 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 a784a9d909ded6e5b72a36965f0493478ab5f362..b1ab777c442989c4735d3b2d210729d4482ba065 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 6ae5c46d7980c67226f7671441861c80ac597803..a2cf8012d3eae990d857108fa282a63234822805 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 312184f77d9f6d19d22cdc8b8c1d0b5095e11ea4..5feb4d3a15a3014145aec79ac0d0e033e77770b1 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 e86189f31a82d3a2fd6a299aa4f3c40d22cda5bf..3fa184bf2f8cd47da961d30e0bd083e65c7e814e 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 d37f23a02933377cf35ee112103910c2abe6d585..9c3ba15fe3d578a3c5269ae79999678bfdf95fda 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 fc9f63b37d7436c8a8499e553d0f0779e12cd1ef..94f2e2e4e322b956f9b9a228e7e76059c3a1c401 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 a0629d5d2eb9f071104f8a25578adce87cf9cbdb..059ab8cd11e00b8714cd1b6ec94baf97f71b2994 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 78b0e34b6c3fb852efa5c008603e091cde787a94..7b0e7dfa6e108067aed9470e96f88921216518de 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 422022baa6a8b1476ef22abbe4f0c096ca3eac4f..0d4d68912f5754397e9d417b1a56b63403131021 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 1535b8cdc0f67c1d7eda269e934243b74721c647..cfe914a9c2949f7b74b42dc508232f2aae2f865a 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 00852f7e9cbb66b90e20cf9fa310b0c7cb27f105..db35fd55bc4dbd0ee3a416d6112167eee42514f1 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 18f70fe78b7d4ae28b79b4daf4c1824a7f2fba6a..5f7dd803da443e0751b195d17a469fcff9ae1e41 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 0000000000000000000000000000000000000000..0385c56c362027dad5ced4167a10ef574657d48d --- /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 40f8e50693e96fc29f25b385c6cfc0242c535dbe..2a1e928cdaad71420f364122fcc3e7d43449b6f2 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;