From 15d139afd4a79cd267b12e197d4b9651ca122df1 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 29 Jul 2016 16:09:39 -0300 Subject: [PATCH 1/4] Pause Periodic List Refresh when View is not Visible Closes #553 --- .../android/contact/ContactListFragment.java | 3 ++- .../android/contact/ConversationActivity.java | 3 ++- .../android/forum/ForumActivity.java | 8 +++++++- .../android/forum/ForumListFragment.java | 3 ++- .../briarproject/android/util/AndroidUtils.java | 12 ++++++------ .../android/util/BriarRecyclerView.java | 17 +++++++++++------ 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index e113a9a08..683bc6bd4 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -153,7 +153,6 @@ public class ContactListFragment extends BaseFragment implements EventListener { list.setLayoutManager(new LinearLayoutManager(getContext())); list.setAdapter(adapter); list.setEmptyText(getString(R.string.no_contacts)); - list.periodicallyUpdateContent(); return contentView; } @@ -183,6 +182,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { super.onResume(); eventBus.addListener(this); loadContacts(); + list.startPeriodicUpdate(); } @Override @@ -190,6 +190,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { super.onPause(); adapter.clear(); eventBus.removeListener(this); + list.stopPeriodicUpdate(); } private void loadContacts() { diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index c85e84d8c..4a936be8d 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -170,7 +170,6 @@ public class ConversationActivity extends BriarActivity list.setLayoutManager(new LinearLayoutManager(this)); list.setAdapter(adapter); list.setEmptyText(getString(R.string.no_private_messages)); - list.periodicallyUpdateContent(); content = (EditText) findViewById(R.id.input_text); sendButton = findViewById(R.id.btn_send); @@ -205,6 +204,7 @@ public class ConversationActivity extends BriarActivity notificationManager.blockNotification(groupId); notificationManager.clearPrivateMessageNotification(groupId); loadData(); + list.startPeriodicUpdate(); } @Override @@ -212,6 +212,7 @@ public class ConversationActivity extends BriarActivity super.onPause(); eventBus.removeListener(this); notificationManager.unblockNotification(groupId); + list.stopPeriodicUpdate(); if (isFinishing()) markMessagesRead(); } diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index dec9c6984..a949dc500 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -119,7 +119,7 @@ public class ForumActivity extends BriarActivity implements forumAdapter = new ForumAdapter( forumController.getForumEntries()); recyclerView.setAdapter(forumAdapter); - recyclerView.periodicallyUpdateContent(); + recyclerView.startPeriodicUpdate(); if (state != null) { byte[] replyId = state.getByteArray(KEY_REPLY_ID); @@ -250,12 +250,18 @@ public class ForumActivity extends BriarActivity implements super.onResume(); notificationManager.blockNotification(groupId); notificationManager.clearForumPostNotification(groupId); + if (recyclerView.getRecyclerView().getAdapter() != null) { + recyclerView.startPeriodicUpdate(); + } } @Override public void onPause() { super.onPause(); notificationManager.unblockNotification(groupId); + if (recyclerView.getRecyclerView().getAdapter() != null) { + recyclerView.stopPeriodicUpdate(); + } } public void sendMessage(View view) { diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index 1916bce32..cca381a80 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -84,7 +84,6 @@ public class ForumListFragment extends BaseEventFragment implements list.setLayoutManager(new LinearLayoutManager(getActivity())); list.setAdapter(adapter); list.setEmptyText(getString(R.string.no_forums)); - list.periodicallyUpdateContent(); snackbar = Snackbar.make(list, "", LENGTH_INDEFINITE); snackbar.getView().setBackgroundResource(R.color.briar_primary); @@ -111,6 +110,7 @@ public class ForumListFragment extends BaseEventFragment implements loadForumHeaders(); loadAvailableForums(); + list.startPeriodicUpdate(); } @Override @@ -118,6 +118,7 @@ public class ForumListFragment extends BaseEventFragment implements super.onPause(); adapter.clear(); + list.stopPeriodicUpdate(); } @Override diff --git a/briar-android/src/org/briarproject/android/util/AndroidUtils.java b/briar-android/src/org/briarproject/android/util/AndroidUtils.java index 077dc8aa5..0488e927f 100644 --- a/briar-android/src/org/briarproject/android/util/AndroidUtils.java +++ b/briar-android/src/org/briarproject/android/util/AndroidUtils.java @@ -30,6 +30,8 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS; public class AndroidUtils { + static final long MIN_RESOLUTION = MINUTE_IN_MILLIS; + // Fake Bluetooth address returned by BluetoothAdapter on API 23 and later private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00"; @@ -97,22 +99,20 @@ public class AndroidUtils { } public static String formatDate(Context ctx, long time) { - // update BriarRecyclerView#DEFAULT_REFRESH_INTERVAL along with this - long minResolution = MINUTE_IN_MILLIS; int flags = FORMAT_ABBREV_RELATIVE | FORMAT_SHOW_DATE | FORMAT_ABBREV_TIME | FORMAT_ABBREV_MONTH; long diff = System.currentTimeMillis() - time; - if (diff < minResolution) return ctx.getString(R.string.now); + if (diff < MIN_RESOLUTION) return ctx.getString(R.string.now); if (diff >= DAY_IN_MILLIS && diff < WEEK_IN_MILLIS) { // also show time when older than a day, but newer than a week - return DateUtils.getRelativeDateTimeString(ctx, time, minResolution, - WEEK_IN_MILLIS, flags).toString(); + return DateUtils.getRelativeDateTimeString(ctx, time, + MIN_RESOLUTION, WEEK_IN_MILLIS, flags).toString(); } // otherwise just show "...ago" or date string return DateUtils .getRelativeTimeSpanString(time, System.currentTimeMillis(), - minResolution, flags).toString(); + MIN_RESOLUTION, flags).toString(); } } diff --git a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java index 6cd36dd6b..40884487a 100644 --- a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java +++ b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java @@ -17,6 +17,7 @@ import org.briarproject.R; import java.util.logging.Logger; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; +import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION; public class BriarRecyclerView extends FrameLayout { @@ -28,7 +29,7 @@ public class BriarRecyclerView extends FrameLayout { private boolean isScrollingToEnd = false; private final Logger LOG = Logger.getLogger(getClass().getName()); - private final long DEFAULT_REFRESH_INTERVAL = MINUTE_IN_MILLIS; + private final long DEFAULT_REFRESH_INTERVAL = MIN_RESOLUTION; public BriarRecyclerView(Context context) { this(context, null, 0); @@ -52,10 +53,7 @@ public class BriarRecyclerView extends FrameLayout { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (refresher != null) { - LOG.info("Removing Handler Callback"); - removeCallbacks(refresher); - } + stopPeriodicUpdate(); } private void initViews() { @@ -172,7 +170,7 @@ public class BriarRecyclerView extends FrameLayout { return this.recyclerView; } - public void periodicallyUpdateContent() { + public void startPeriodicUpdate() { if (recyclerView == null || recyclerView.getAdapter() == null) { throw new IllegalStateException("Need to call setAdapter() first!"); } @@ -188,4 +186,11 @@ public class BriarRecyclerView extends FrameLayout { postDelayed(refresher, DEFAULT_REFRESH_INTERVAL); } + public void stopPeriodicUpdate() { + if (refresher != null) { + LOG.info("Removing Handler Callback"); + removeCallbacks(refresher); + } + } + } From 5a2fd2018fb6f05a3f9cb2e9cf4c6c2d6784e6e8 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 29 Jul 2016 16:10:29 -0300 Subject: [PATCH 2/4] Fix Chevron in Forum sometimes losing its Blue Color --- briar-android/res/drawable/chevron48dp_down.xml | 11 ++++++++--- briar-android/res/drawable/chevron48dp_up.xml | 11 ++++++++--- briar-android/res/drawable/selector_chevron.xml | 2 +- briar-android/res/layout/forum_discussion_cell.xml | 4 +--- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/briar-android/res/drawable/chevron48dp_down.xml b/briar-android/res/drawable/chevron48dp_down.xml index 16dd3cd9d..6f1f305df 100644 --- a/briar-android/res/drawable/chevron48dp_down.xml +++ b/briar-android/res/drawable/chevron48dp_down.xml @@ -1,4 +1,9 @@ - - + + diff --git a/briar-android/res/drawable/chevron48dp_up.xml b/briar-android/res/drawable/chevron48dp_up.xml index 7d59523a9..50894206e 100644 --- a/briar-android/res/drawable/chevron48dp_up.xml +++ b/briar-android/res/drawable/chevron48dp_up.xml @@ -1,4 +1,9 @@ - - + + diff --git a/briar-android/res/drawable/selector_chevron.xml b/briar-android/res/drawable/selector_chevron.xml index bc08694ba..f3a72a87d 100644 --- a/briar-android/res/drawable/selector_chevron.xml +++ b/briar-android/res/drawable/selector_chevron.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/briar-android/res/layout/forum_discussion_cell.xml b/briar-android/res/layout/forum_discussion_cell.xml index c8dd79dd6..fc6e1a20a 100644 --- a/briar-android/res/layout/forum_discussion_cell.xml +++ b/briar-android/res/layout/forum_discussion_cell.xml @@ -148,9 +148,7 @@ android:layout_marginRight="@dimen/margin_medium" android:layout_marginTop="@dimen/margin_small" android:clickable="true" - android:src="@drawable/selector_chevron" - android:tint="@color/briar_button_positive" - /> + android:src="@drawable/selector_chevron"/> Date: Mon, 1 Aug 2016 14:33:27 +0100 Subject: [PATCH 3/4] Initialise adapter in onCreate() to avoid double refreshing. --- .../android/forum/ForumActivity.java | 95 +++++++++---------- .../activity/TestForumActivity.java | 2 +- 2 files changed, 45 insertions(+), 52 deletions(-) diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index a949dc500..02a78cacc 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -9,7 +9,6 @@ import android.content.Intent; import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; @@ -63,9 +62,9 @@ public class ForumActivity extends BriarActivity implements ForumController.ForumPostListener { static final String FORUM_NAME = "briar.FORUM_NAME"; - private static final int REQUEST_FORUM_SHARED = 3; - private final static int UNDEFINED = -1; + private static final int REQUEST_FORUM_SHARED = 3; + private static final int UNDEFINED = -1; private static final String KEY_INPUT_VISIBILITY = "inputVisibility"; private static final String KEY_REPLY_ID = "replyId"; @@ -77,6 +76,9 @@ public class ForumActivity extends BriarActivity implements @Inject protected ForumController forumController; + // Protected access for testing + protected ForumAdapter forumAdapter; + private BriarRecyclerView recyclerView; private EditText textInput; private ViewGroup inputContainer; @@ -84,8 +86,6 @@ public class ForumActivity extends BriarActivity implements private volatile GroupId groupId = null; - protected ForumAdapter forumAdapter; - @Override public void onCreate(final Bundle state) { super.onCreate(state); @@ -99,50 +99,46 @@ public class ForumActivity extends BriarActivity implements String forumName = i.getStringExtra(FORUM_NAME); if (forumName != null) setTitle(forumName); + forumAdapter = new ForumAdapter(); + inputContainer = (ViewGroup) findViewById(R.id.text_input_container); inputContainer.setVisibility(GONE); textInput = (EditText) findViewById(R.id.input_text); recyclerView = (BriarRecyclerView) findViewById(R.id.forum_discussion_list); + recyclerView.setAdapter(forumAdapter); linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); recyclerView.setEmptyText(getString(R.string.no_forum_posts)); recyclerView.showProgressBar(); - forumController.loadForum(groupId, - new UiResultHandler(this) { - @Override - public void onResultUi(Boolean result) { - if (result) { - Forum forum = forumController.getForum(); - if (forum != null) setTitle(forum.getName()); - forumAdapter = new ForumAdapter( - forumController.getForumEntries()); - recyclerView.setAdapter(forumAdapter); - recyclerView.startPeriodicUpdate(); - if (state != null) { - byte[] replyId = - state.getByteArray(KEY_REPLY_ID); - if (replyId != null) { - forumAdapter.setReplyEntryById(replyId); - } - } - recyclerView.showData(); - } else { - // TODO Maybe an error dialog ? - finish(); - } + forumController.loadForum(groupId, new UiResultHandler(this) { + @Override + public void onResultUi(Boolean result) { + if (result) { + Forum forum = forumController.getForum(); + if (forum != null) setTitle(forum.getName()); + forumAdapter.setEntries(forumController.getForumEntries()); + if (state != null) { + byte[] replyId = state.getByteArray(KEY_REPLY_ID); + if (replyId != null) + forumAdapter.setReplyEntryById(replyId); } - }); + recyclerView.showData(); + } else { + // TODO Maybe an error dialog ? + finish(); + } + } + }); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - inputContainer - .setVisibility( - savedInstanceState.getBoolean(KEY_INPUT_VISIBILITY) ? - VISIBLE : GONE); + inputContainer.setVisibility( + savedInstanceState.getBoolean(KEY_INPUT_VISIBILITY) ? + VISIBLE : GONE); } @@ -250,18 +246,14 @@ public class ForumActivity extends BriarActivity implements super.onResume(); notificationManager.blockNotification(groupId); notificationManager.clearForumPostNotification(groupId); - if (recyclerView.getRecyclerView().getAdapter() != null) { - recyclerView.startPeriodicUpdate(); - } + recyclerView.startPeriodicUpdate(); } @Override public void onPause() { super.onPause(); notificationManager.unblockNotification(groupId); - if (recyclerView.getRecyclerView().getAdapter() != null) { - recyclerView.stopPeriodicUpdate(); - } + recyclerView.stopPeriodicUpdate(); } public void sendMessage(View view) { @@ -373,23 +365,25 @@ public class ForumActivity extends BriarActivity implements public class ForumAdapter extends RecyclerView.Adapter { - private final List forumEntries; + private final List forumEntries = new ArrayList<>(); + private final Map animatingEntries = + new HashMap<>(); + // highlight not dependant on time private ForumEntry replyEntry; // temporary highlight private ForumEntry addedEntry; - Map animatingEntries = new HashMap<>(); - - ForumAdapter(@NonNull List forumEntries) { - this.forumEntries = forumEntries; - } private ForumEntry getReplyEntry() { return replyEntry; } - void addEntry(int index, ForumEntry entry, - boolean isScrolling) { + void setEntries(List entries) { + forumEntries.clear(); + forumEntries.addAll(entries); + } + + void addEntry(int index, ForumEntry entry, boolean isScrolling) { forumEntries.add(index, entry); boolean isShowingDescendants = false; if (entry.getLevel() > 0) { @@ -559,7 +553,7 @@ public class ForumActivity extends BriarActivity implements return null; } - @TargetApi(Build.VERSION_CODES.HONEYCOMB) + @TargetApi(11) private void animateFadeOut(final ForumViewHolder ui, final ForumEntry addedEntry) { ui.setIsRecyclable(false); @@ -605,8 +599,8 @@ public class ForumActivity extends BriarActivity implements } @Override - public ForumViewHolder onCreateViewHolder( - ViewGroup parent, int viewType) { + public ForumViewHolder onCreateViewHolder(ViewGroup parent, + int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.forum_discussion_cell, parent, false); return new ForumViewHolder(v); @@ -730,5 +724,4 @@ public class ForumActivity extends BriarActivity implements } } - } diff --git a/briar-android/test/java/briarproject/activity/TestForumActivity.java b/briar-android/test/java/briarproject/activity/TestForumActivity.java index f73d83e18..9455ace7e 100644 --- a/briar-android/test/java/briarproject/activity/TestForumActivity.java +++ b/briar-android/test/java/briarproject/activity/TestForumActivity.java @@ -9,7 +9,7 @@ import org.briarproject.android.forum.ForumControllerImpl; import org.mockito.Mockito; /** - * This class exposes the SetupController and offers the possibility to + * This class exposes the ForumController and offers the possibility to * override it. */ public class TestForumActivity extends ForumActivity { From 2c993b62c28a9bd35fdb36ce5084e7756f1ff5c7 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 1 Aug 2016 14:34:52 +0100 Subject: [PATCH 4/4] Made the logger and a constant static. --- .../org/briarproject/android/util/BriarRecyclerView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java index 40884487a..6c403747f 100644 --- a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java +++ b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java @@ -16,11 +16,14 @@ import org.briarproject.R; import java.util.logging.Logger; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION; public class BriarRecyclerView extends FrameLayout { + private static final long DEFAULT_REFRESH_INTERVAL = MIN_RESOLUTION; + private static final Logger LOG = + Logger.getLogger(BriarRecyclerView.class.getName()); + private RecyclerView recyclerView; private TextView emptyView; private ProgressBar progressBar; @@ -28,9 +31,6 @@ public class BriarRecyclerView extends FrameLayout { private Runnable refresher = null; private boolean isScrollingToEnd = false; - private final Logger LOG = Logger.getLogger(getClass().getName()); - private final long DEFAULT_REFRESH_INTERVAL = MIN_RESOLUTION; - public BriarRecyclerView(Context context) { this(context, null, 0); }