Scroll to top on chat press when already on that tab.

This commit is contained in:
Alex Hart 2022-05-16 16:15:07 -03:00 committed by Cody Henthorne
parent 3c08b070fc
commit 77f8489e51
3 changed files with 47 additions and 0 deletions

View file

@ -137,11 +137,14 @@ import org.thoughtcrime.securesms.search.SearchResult;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
import org.thoughtcrime.securesms.stories.tabs.ConversationListTab;
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.util.AppStartup;
import org.thoughtcrime.securesms.util.BottomSheetUtil;
import org.thoughtcrime.securesms.util.ConversationUtil;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.LifecycleDisposable;
import org.thoughtcrime.securesms.util.PlayStoreUtil;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
@ -185,6 +188,8 @@ public class ConversationListFragment extends MainFragment implements ActionMode
public static final short MESSAGE_REQUESTS_REQUEST_CODE_CREATE_NAME = 32562;
public static final short SMS_ROLE_REQUEST_CODE = 32563;
private static final int LIST_SMOOTH_SCROLL_TO_TOP_THRESHOLD = 25;
private static final String TAG = Log.tag(ConversationListFragment.class);
private static final int MAXIMUM_PINNED_CONVERSATIONS = 4;
@ -213,10 +218,12 @@ public class ConversationListFragment extends MainFragment implements ActionMode
private VoiceNotePlayerView voiceNotePlayerView;
private SignalBottomActionBar bottomActionBar;
private SignalContextMenu activeContextMenu;
private LifecycleDisposable lifecycleDisposable;
protected ConversationListArchiveItemDecoration archiveDecoration;
protected ConversationListItemAnimator itemAnimator;
private Stopwatch startupStopwatch;
private ConversationListTabsViewModel conversationListTabsViewModel;
public static ConversationListFragment newInstance() {
return new ConversationListFragment();
@ -317,6 +324,21 @@ public class ConversationListFragment extends MainFragment implements ActionMode
}
}
});
lifecycleDisposable = new LifecycleDisposable();
conversationListTabsViewModel = new ViewModelProvider(requireActivity()).get(ConversationListTabsViewModel.class);
lifecycleDisposable.bindTo(getViewLifecycleOwner());
lifecycleDisposable.add(conversationListTabsViewModel.getTabClickEvents().filter(tab -> tab == ConversationListTab.CHATS)
.subscribe(unused -> {
LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (firstVisibleItemPosition <= LIST_SMOOTH_SCROLL_TO_TOP_THRESHOLD) {
list.smoothScrollToPosition(0);
} else {
list.scrollToPosition(0);
}
}));
}
@Override

View file

@ -16,6 +16,7 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.app.SharedElementCallback
import androidx.core.view.ViewCompat
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.BaseTransientBottomBar
@ -43,6 +44,7 @@ import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
import org.thoughtcrime.securesms.stories.dialogs.StoryDialogs
import org.thoughtcrime.securesms.stories.my.MyStoriesActivity
import org.thoughtcrime.securesms.stories.settings.StorySettingsActivity
import org.thoughtcrime.securesms.stories.tabs.ConversationListTab
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
import org.thoughtcrime.securesms.util.LifecycleDisposable
@ -54,6 +56,10 @@ import java.util.concurrent.TimeUnit
*/
class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_landing_fragment) {
companion object {
private const val LIST_SMOOTH_SCROLL_TO_TOP_THRESHOLD = 25
}
private lateinit var emptyNotice: View
private lateinit var cameraFab: FloatingActionButton
@ -137,6 +143,17 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
}
}
)
lifecycleDisposable += tabsViewModel.tabClickEvents
.filter { it == ConversationListTab.STORIES }
.subscribeBy(onNext = {
val layoutManager = recyclerView?.layoutManager as? LinearLayoutManager ?: return@subscribeBy
if (layoutManager.findFirstVisibleItemPosition() <= LIST_SMOOTH_SCROLL_TO_TOP_THRESHOLD) {
recyclerView?.smoothScrollToPosition(0)
} else {
recyclerView?.scrollToPosition(0)
}
})
}
private fun getConfiguration(state: StoriesLandingState): DSLConfiguration {

View file

@ -3,8 +3,11 @@ package org.thoughtcrime.securesms.stories.tabs
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
import org.thoughtcrime.securesms.util.livedata.Store
class ConversationListTabsViewModel(repository: ConversationListTabRepository) : ViewModel() {
@ -14,6 +17,9 @@ class ConversationListTabsViewModel(repository: ConversationListTabRepository) :
val state: LiveData<ConversationListTabsState> = store.stateLiveData
val disposables = CompositeDisposable()
private val internalTabClickEvents: Subject<ConversationListTab> = PublishSubject.create()
val tabClickEvents: Observable<ConversationListTab> = internalTabClickEvents
init {
disposables += repository.getNumberOfUnreadConversations().subscribe { unreadChats ->
store.update { it.copy(unreadChatsCount = unreadChats) }
@ -29,10 +35,12 @@ class ConversationListTabsViewModel(repository: ConversationListTabRepository) :
}
fun onChatsSelected() {
internalTabClickEvents.onNext(ConversationListTab.CHATS)
store.update { it.copy(tab = ConversationListTab.CHATS) }
}
fun onStoriesSelected() {
internalTabClickEvents.onNext(ConversationListTab.STORIES)
store.update { it.copy(tab = ConversationListTab.STORIES) }
}