From 9e1ded941fdf340c8a4811e4e1cb44c128da3bd0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2019 12:29:37 +0200 Subject: [PATCH] Persist active tab between sessions (#503) --- CHANGES.md | 2 +- .../vector/riotx/core/di/ScreenComponent.kt | 3 + .../vector/riotx/core/di/VectorComponent.kt | 3 + .../riotx/features/home/HomeDetailFragment.kt | 6 ++ .../features/home/HomeDetailViewModel.kt | 12 ++++ .../riotx/features/ui/UiStateRepository.kt | 56 +++++++++++++++++++ 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt diff --git a/CHANGES.md b/CHANGES.md index 07eab082d0..ee803b43cf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features: - Improvements: - - + - Persist active tab between sessions (#503) Other changes: - diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index 01db4b4a01..3b18d3042e 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -65,6 +65,7 @@ import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment import im.vector.riotx.features.settings.* import im.vector.riotx.features.settings.push.PushGatewaysFragment +import im.vector.riotx.features.ui.UiStateRepository @Component(dependencies = [VectorComponent::class], modules = [AssistedInjectModule::class, ViewModelModule::class, HomeModule::class]) @ScreenScope @@ -80,6 +81,8 @@ interface ScreenComponent { fun navigator(): Navigator + fun uiStateRepository(): UiStateRepository + fun inject(activity: HomeActivity) fun inject(roomDetailFragment: RoomDetailFragment) diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt index a76091fb36..61c461c655 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt @@ -42,6 +42,7 @@ import im.vector.riotx.features.rageshake.BugReporter import im.vector.riotx.features.rageshake.VectorFileLogger import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.settings.VectorPreferences +import im.vector.riotx.features.ui.UiStateRepository import javax.inject.Singleton @Component(modules = [VectorModule::class]) @@ -106,6 +107,8 @@ interface VectorComponent { fun vectorFileLogger(): VectorFileLogger + fun uiStateRepository(): UiStateRepository + @Component.Factory interface Factory { fun create(@BindsInstance context: Context): VectorComponent diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt index a236bec747..112fae1b24 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt @@ -166,6 +166,12 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { private fun switchDisplayMode(displayMode: RoomListFragment.DisplayMode) { groupToolbarTitleView.setText(displayMode.titleRes) updateSelectedFragment(displayMode) + // Update the navigation view (for when we restore the tabs) + bottomNavigationView.selectedItemId = when (displayMode) { + RoomListFragment.DisplayMode.PEOPLE -> R.id.bottom_action_people + RoomListFragment.DisplayMode.ROOMS -> R.id.bottom_action_rooms + else -> R.id.bottom_action_home + } } private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt index be8648da35..688d2b6b7b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt @@ -23,8 +23,10 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session import im.vector.matrix.rx.rx +import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers /** @@ -33,6 +35,7 @@ import io.reactivex.schedulers.Schedulers */ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState, private val session: Session, + private val uiStateRepository: UiStateRepository, private val homeRoomListStore: HomeRoomListObservableStore) : VectorViewModel(initialState) { @@ -43,6 +46,13 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho companion object : MvRxViewModelFactory { + override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState? { + val uiStateRepository = (viewModelContext.activity as HasScreenInjector).injector().uiStateRepository() + return HomeDetailViewState( + displayMode = uiStateRepository.getDisplayMode() + ) + } + @JvmStatic override fun create(viewModelContext: ViewModelContext, state: HomeDetailViewState): HomeDetailViewModel? { val fragment: HomeDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() @@ -60,6 +70,8 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho setState { copy(displayMode = displayMode) } + + uiStateRepository.storeDisplayMode(displayMode) } } diff --git a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt new file mode 100644 index 0000000000..be8e624100 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.ui + +import android.content.SharedPreferences +import androidx.core.content.edit +import im.vector.riotx.features.home.room.list.RoomListFragment +import javax.inject.Inject + + +/** + * This class is used to persist UI state across application restart + */ +class UiStateRepository @Inject constructor(private val sharedPreferences: SharedPreferences) { + + fun getDisplayMode(): RoomListFragment.DisplayMode { + return when (sharedPreferences.getInt(KEY_DISPLAY_MODE, VALUE_DISPLAY_MODE_CATCHUP)) { + VALUE_DISPLAY_MODE_PEOPLE -> RoomListFragment.DisplayMode.PEOPLE + VALUE_DISPLAY_MODE_ROOMS -> RoomListFragment.DisplayMode.ROOMS + else -> RoomListFragment.DisplayMode.HOME + } + } + + fun storeDisplayMode(displayMode: RoomListFragment.DisplayMode) { + sharedPreferences.edit { + putInt(KEY_DISPLAY_MODE, + when (displayMode) { + RoomListFragment.DisplayMode.PEOPLE -> VALUE_DISPLAY_MODE_PEOPLE + RoomListFragment.DisplayMode.ROOMS -> VALUE_DISPLAY_MODE_ROOMS + else -> VALUE_DISPLAY_MODE_CATCHUP + }) + } + } + + + companion object { + private const val KEY_DISPLAY_MODE = "UI_STATE_DISPLAY_MODE" + private const val VALUE_DISPLAY_MODE_CATCHUP = 0 + private const val VALUE_DISPLAY_MODE_PEOPLE = 1 + private const val VALUE_DISPLAY_MODE_ROOMS = 2 + } +} \ No newline at end of file