From ae9f23f1da3bbda0764686d99e2edcdd750d197e Mon Sep 17 00:00:00 2001 From: Vishwesh Date: Mon, 20 Feb 2017 18:11:25 +0530 Subject: [PATCH] Restore narrow and scroll after theme switch. Fix#406 --- .../main/java/com/zulip/android/ZulipApp.java | 46 ++++++++++++++ .../activities/MessageListFragment.java | 62 +++++++++++++++++-- .../android/activities/ZulipActivity.java | 34 +++++++++- 3 files changed, 137 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/zulip/android/ZulipApp.java b/app/src/main/java/com/zulip/android/ZulipApp.java index 5f8c87d24..2a1fb30e6 100644 --- a/app/src/main/java/com/zulip/android/ZulipApp.java +++ b/app/src/main/java/com/zulip/android/ZulipApp.java @@ -26,6 +26,7 @@ import com.j256.ormlite.misc.TransactionManager; import com.zulip.android.activities.ZulipActivity; import com.zulip.android.database.DatabaseHelper; +import com.zulip.android.filters.NarrowFilter; import com.zulip.android.models.Emoji; import com.zulip.android.models.Message; import com.zulip.android.models.MessageType; @@ -123,6 +124,19 @@ public void setZulipActivity(ZulipActivity zulipActivity) { this.zulipActivity = zulipActivity; } + //store narrowFilter before switching theme + private NarrowFilter narrowFilter = null; + + //set it after restore + //for narrowed view + private int tempNarrowedViewPointer = -1; + //for home view + private int tempHomeViewPointer = -1; + + //useful when switch takes place from narrowed view + //on switch theme activity is recreated + private boolean isThemeSwitchedFromHome = true; + @Override public void onCreate() { super.onCreate(); @@ -560,4 +574,36 @@ public void setMessageContentEditParams(int seconds, boolean param) { } } } + + public NarrowFilter getNarrowFilter() { + return narrowFilter; + } + + public void setNarrowFilter(NarrowFilter narrowFilter) { + this.narrowFilter = narrowFilter; + } + + public void setTempNarrowedViewPointer(int mID) { + this.tempNarrowedViewPointer = mID; + } + + public int getTempNarrowedViewPointer() { + return tempNarrowedViewPointer; + } + + public int getTempHomeViewPointer() { + return tempHomeViewPointer; + } + + public void setTempHomeViewPointer(int tempHomeViewPointer) { + this.tempHomeViewPointer = tempHomeViewPointer; + } + + public boolean isThemeSwitchedFromHome() { + return isThemeSwitchedFromHome; + } + + public void setThemeSwitchedFromHome(boolean themeSwitchedFromHome) { + isThemeSwitchedFromHome = themeSwitchedFromHome; + } } diff --git a/app/src/main/java/com/zulip/android/activities/MessageListFragment.java b/app/src/main/java/com/zulip/android/activities/MessageListFragment.java index 4471c20de..f6fbc4c34 100644 --- a/app/src/main/java/com/zulip/android/activities/MessageListFragment.java +++ b/app/src/main/java/com/zulip/android/activities/MessageListFragment.java @@ -347,7 +347,7 @@ public void onTaskFailure(String result) { 100, filter); } - private void selectPointer() { + public void selectPointer() { if (filter != null) { Where filteredWhere; try { @@ -365,16 +365,38 @@ private void selectPointer() { // use anchor message id if message was narrowed if (anchorId != -1) { - selectMessage(getMessageById(anchorId)); + if (app.getTempNarrowedViewPointer() != -1 && app.getTempNarrowedViewPointer() < anchorId) { + //user have scrolled above before switching theme + scrollWithZeroOffset(getMessageById(app.getTempNarrowedViewPointer())); + app.setTempNarrowedViewPointer(-1); + } else { + selectMessage(getMessageById(anchorId)); + } } else { - recyclerView.scrollToPosition(adapter.getItemIndex(closestMessage)); + if (app.getTempNarrowedViewPointer() != -1 && adapter.getItemIndex(getMessageById(app.getTempNarrowedViewPointer())) < adapter.getItemIndex(closestMessage)) { + //user have scrolled above before switching theme + scrollWithZeroOffset(getMessageById(app.getTempNarrowedViewPointer())); + app.setTempNarrowedViewPointer(-1); + }else { + recyclerView.scrollToPosition(adapter.getItemIndex(closestMessage)); + } } } catch (SQLException e) { throw new RuntimeException(e); } } else { int anc = app.getPointer(); - selectMessage(getMessageById(anc)); + int tempPointer = app.getTempHomeViewPointer(); + if (tempPointer != -1 && tempPointer < anc) { + //user have scrolled above before switching theme + scrollWithZeroOffset(getMessageById(tempPointer)); + //will be useful when user switch theme from narrowed view and back trace to home + if (app.isThemeSwitchedFromHome()) { + app.setTempHomeViewPointer(-1); + } + } else { + selectMessage(getMessageById(anc)); + } } } @@ -693,6 +715,16 @@ private void selectMessage(final Message message) { recyclerView.scrollToPosition(adapter.getItemIndex(message)); } + /** + * scroll such that message comes to top of the view + * + * @param message that should come to top + * @see {@link } + */ + private void scrollWithZeroOffset(Message message) { + linearLayoutManager.scrollToPositionWithOffset(adapter.getItemIndex(message), 0); + } + private Message getMessageById(int id) { return this.messageIndex.get(id); } @@ -732,4 +764,26 @@ public boolean scrolledToLastMessage() { public RecyclerMessageAdapter getAdapter() { return this.adapter; } + + /** + * get messageId of FirstCompletelyVisibleItem + * loop until we get message + * skip message header + * + * @return messagedId of message which is at top + */ + public int getTopMessageId() { + int position = linearLayoutManager.findFirstCompletelyVisibleItemPosition(); + //if there aren't any visible items position = -1 + if (position >= 0) { + for (int i = position; i < adapter.getItemCount(); i++) { + Object topObject = adapter.getItem(i); + if (topObject instanceof Message) { + return ((Message) topObject).getID(); + } + } + } + return -1; + + } } diff --git a/app/src/main/java/com/zulip/android/activities/ZulipActivity.java b/app/src/main/java/com/zulip/android/activities/ZulipActivity.java index df769161b..2365ab86a 100644 --- a/app/src/main/java/com/zulip/android/activities/ZulipActivity.java +++ b/app/src/main/java/com/zulip/android/activities/ZulipActivity.java @@ -576,6 +576,8 @@ public Cursor runQuery(CharSequence charSequence) { this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); } + + /** * Called when fragment is changed * When narrowedList == null means home page show Today in menu @@ -588,10 +590,14 @@ public void onBackStackChanged() { if (menu == null) return; if (narrowedList == null) { + //will be useful when user switch theme from narrowed view and back trace to home + app.setThemeSwitchedFromHome(true); calendar = Calendar.getInstance(); menu.getItem(2).getSubMenu().getItem(0).setTitle(R.string.menu_today); switchToStream(); checkForChatBoxFocusRequest(); + //on narrowed view is restored after switching and coming back to homeView set pointer accordingly + homeList.selectPointer(); } else if (narrowedList.filter instanceof NarrowFilterByDate) { menu.getItem(2).getSubMenu().getItem(0).setTitle(R.string.menu_one_day_before); } @@ -821,6 +827,17 @@ protected void onNewIntent(Intent intent) { } } + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + //check if it was narrowed before switching theme + if (app.getNarrowFilter() != null) { + //restore narrow + doNarrow(app.getNarrowFilter()); + app.setNarrowFilter(null); + } + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) { @@ -1763,7 +1780,12 @@ private void pushListFragment(MessageListFragment list, String back) { transaction.replace(R.id.list_fragment_container, list); if (back != null) { transaction.addToBackStack(back); - clearSearch(); + //searchView is in menu + //menu is inflated in onCreateOptionsMenu + //onCreateOptionsMenu is called somewhere in between onCreate is executing + if (searchView != null) { + clearSearch(); + } } transaction.commit(); getSupportFragmentManager().executePendingTransactions(); @@ -2057,6 +2079,16 @@ public void onClick( } break; case R.id.daynight: + //for narrowed view + if (narrowedList != null) { + app.setNarrowFilter(narrowedList.filter); + app.setTempNarrowedViewPointer(narrowedList.getTopMessageId()); + app.setThemeSwitchedFromHome(false); + } + //for home view + if (app.getTempHomeViewPointer() == -1 || app.isThemeSwitchedFromHome()) { + app.setTempHomeViewPointer(homeList.getTopMessageId()); + } switch (AppCompatDelegate.getDefaultNightMode()) { case -1: case AppCompatDelegate.MODE_NIGHT_NO: