From 08eb8de09b82f803265de69aff80b45867792e0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 22 Dec 2022 17:33:04 +0100 Subject: [PATCH] Create a UserViewModel to avoid duplicated code. --- features/preferences/build.gradle.kts | 1 + .../features/preferences/PreferencesScreen.kt | 4 +- .../preferences/user/UserPreferences.kt | 46 +++++++++++++++++ .../x/features/roomlist/RoomListScreen.kt | 5 +- .../x/features/roomlist/RoomListViewModel.kt | 4 -- .../roomlist/model/RoomListViewState.kt | 2 - libraries/matrixui/build.gradle.kts | 3 ++ .../ui/viewmodels/user/UserViewModel.kt | 49 +++++++++++++++++++ .../ui/viewmodels/user/UserViewState.kt | 26 ++++++++++ 9 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 features/preferences/src/main/java/io/element/android/x/features/preferences/user/UserPreferences.kt create mode 100644 libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt create mode 100644 libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt diff --git a/features/preferences/build.gradle.kts b/features/preferences/build.gradle.kts index e31375be26..e3c7f064e5 100644 --- a/features/preferences/build.gradle.kts +++ b/features/preferences/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { anvil(project(":anvilcodegen")) implementation(project(":libraries:di")) implementation(project(":libraries:core")) + implementation(project(":libraries:matrixui")) implementation(project(":features:rageshake")) implementation(project(":features:logout")) implementation(project(":libraries:designsystem")) diff --git a/features/preferences/src/main/java/io/element/android/x/features/preferences/PreferencesScreen.kt b/features/preferences/src/main/java/io/element/android/x/features/preferences/PreferencesScreen.kt index 98a7158eea..61f38f4a14 100644 --- a/features/preferences/src/main/java/io/element/android/x/features/preferences/PreferencesScreen.kt +++ b/features/preferences/src/main/java/io/element/android/x/features/preferences/PreferencesScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.Preview import io.element.android.x.designsystem.components.preferences.PreferenceScreen import io.element.android.x.element.resources.R as ElementR import io.element.android.x.features.logout.LogoutPreference +import io.element.android.x.features.preferences.user.UserPreferences import io.element.android.x.features.rageshake.preferences.RageshakePreferences @Composable @@ -52,8 +53,9 @@ fun PreferencesContent( onBackPressed = onBackPressed, title = stringResource(id = ElementR.string.settings) ) { - LogoutPreference(onSuccessLogout = onSuccessLogout) + UserPreferences() RageshakePreferences(onOpenRageShake = onOpenRageShake) + LogoutPreference(onSuccessLogout = onSuccessLogout) } } diff --git a/features/preferences/src/main/java/io/element/android/x/features/preferences/user/UserPreferences.kt b/features/preferences/src/main/java/io/element/android/x/features/preferences/user/UserPreferences.kt new file mode 100644 index 0000000000..0736c5dcdd --- /dev/null +++ b/features/preferences/src/main/java/io/element/android/x/features/preferences/user/UserPreferences.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 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 io.element.android.x.features.preferences.user + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.airbnb.mvrx.Fail +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.Success +import com.airbnb.mvrx.Uninitialized +import com.airbnb.mvrx.compose.collectAsState +import com.airbnb.mvrx.compose.mavericksViewModel +import io.element.android.x.matrix.ui.components.MatrixUserHeader +import io.element.android.x.matrix.ui.viewmodels.user.UserViewModel +import io.element.android.x.matrix.ui.viewmodels.user.UserViewState + +@Composable +fun UserPreferences( + viewModel: UserViewModel = mavericksViewModel() +) { + val user by viewModel.collectAsState(UserViewState::user) + when (user) { + is Fail -> Spacer(modifier = Modifier.height(1.dp)) + is Loading -> Spacer(modifier = Modifier.height(1.dp)) + is Success -> MatrixUserHeader(matrixUser = user.invoke()!!) + Uninitialized -> Spacer(modifier = Modifier.height(1.dp)) + } +} diff --git a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt index 022479b7e2..3695a80c48 100644 --- a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt +++ b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt @@ -50,19 +50,22 @@ import io.element.android.x.features.roomlist.model.stubbedRoomSummaries import io.element.android.x.matrix.core.RoomId import io.element.android.x.matrix.core.UserId import io.element.android.x.matrix.ui.model.MatrixUser +import io.element.android.x.matrix.ui.viewmodels.user.UserViewModel +import io.element.android.x.matrix.ui.viewmodels.user.UserViewState import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @Composable fun RoomListScreen( viewModel: RoomListViewModel = mavericksViewModel(), + userViewModel: UserViewModel = mavericksViewModel(), onRoomClicked: (RoomId) -> Unit = { }, onOpenSettings: () -> Unit = { }, ) { val filter by viewModel.collectAsState(RoomListViewState::filter) LogCompositions(tag = "RoomListScreen", msg = "Root") val roomSummaries by viewModel.collectAsState(RoomListViewState::rooms) - val matrixUser by viewModel.collectAsState(RoomListViewState::user) + val matrixUser by userViewModel.collectAsState(UserViewState::user) RoomListContent( roomSummaries = roomSummaries().orEmpty().toImmutableList(), matrixUser = matrixUser(), diff --git a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt index 9ecac4f705..e1fdb5cfa6 100644 --- a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt +++ b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt @@ -78,10 +78,6 @@ class RoomListViewModel @AssistedInject constructor( } private fun handleInit() { - matrixUserHelper.getCurrentUserData(avatarSize = AvatarSize.SMALL).execute { - copy(user = it) - } - // Observe the room list and the filter combine( client.roomSummaryDataSource().roomSummaries() diff --git a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/model/RoomListViewState.kt b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/model/RoomListViewState.kt index 05f773537d..4fb02b054c 100644 --- a/features/roomlist/src/main/java/io/element/android/x/features/roomlist/model/RoomListViewState.kt +++ b/features/roomlist/src/main/java/io/element/android/x/features/roomlist/model/RoomListViewState.kt @@ -20,10 +20,8 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized import io.element.android.x.matrix.core.RoomId -import io.element.android.x.matrix.ui.model.MatrixUser data class RoomListViewState( - val user: Async = Uninitialized, // Will contain the filtered rooms, using ::filter (if filter is not empty) val rooms: Async> = Uninitialized, val filter: String = "", diff --git a/libraries/matrixui/build.gradle.kts b/libraries/matrixui/build.gradle.kts index 02a07aa0dd..c33aa13795 100644 --- a/libraries/matrixui/build.gradle.kts +++ b/libraries/matrixui/build.gradle.kts @@ -28,6 +28,9 @@ anvil { } dependencies { + implementation(project(":anvilannotations")) + anvil(project(":anvilcodegen")) + implementation(project(":libraries:di")) implementation(project(":libraries:matrix")) implementation(project(":libraries:designsystem")) implementation(project(":libraries:core")) diff --git a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt new file mode 100644 index 0000000000..9ec53ee912 --- /dev/null +++ b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 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 io.element.android.x.matrix.ui.viewmodels.user + +import com.airbnb.mvrx.MavericksViewModel +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.x.anvilannotations.ContributesViewModel +import io.element.android.x.core.di.daggerMavericksViewModelFactory +import io.element.android.x.designsystem.components.avatar.AvatarSize +import io.element.android.x.di.SessionScope +import io.element.android.x.matrix.MatrixClient +import io.element.android.x.matrix.ui.MatrixItemHelper + +@ContributesViewModel(SessionScope::class) +class UserViewModel @AssistedInject constructor( + client: MatrixClient, + @Assisted initialState: UserViewState +) : MavericksViewModel(initialState) { + + companion object : MavericksViewModelFactory by daggerMavericksViewModelFactory() + + private val matrixUserHelper = MatrixItemHelper(client) + + init { + handleInit() + } + + private fun handleInit() { + matrixUserHelper.getCurrentUserData(avatarSize = AvatarSize.SMALL).execute { + copy(user = it) + } + } +} diff --git a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt new file mode 100644 index 0000000000..60d7c5bd48 --- /dev/null +++ b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 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 io.element.android.x.matrix.ui.viewmodels.user + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MavericksState +import com.airbnb.mvrx.Uninitialized +import io.element.android.x.matrix.ui.model.MatrixUser + +data class UserViewState( + val user: Async = Uninitialized, +) : MavericksState