Show current user in the settings and extract code in CurrentUserProvider.

This commit is contained in:
Benoit Marty 2023-06-30 14:26:35 +02:00 committed by Benoit Marty
parent b4a5128a05
commit e1b528e861
12 changed files with 226 additions and 69 deletions

View file

@ -17,23 +17,38 @@
package io.element.android.features.preferences.impl.root
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesPresenter
import io.element.android.features.logout.api.LogoutPreferencePresenter
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesPresenter
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.matrix.api.user.CurrentUserProvider
import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
class PreferencesRootPresenter @Inject constructor(
private val logoutPresenter: LogoutPreferencePresenter,
private val rageshakePresenter: RageshakePreferencesPresenter,
private val analyticsPresenter: AnalyticsPreferencesPresenter,
private val currentUserProvider: CurrentUserProvider,
private val buildType: BuildType,
) : Presenter<PreferencesRootState> {
@Composable
override fun present(): PreferencesRootState {
val matrixUser: MutableState<MatrixUser?> = rememberSaveable {
mutableStateOf(null)
}
LaunchedEffect(Unit) {
initialLoad(matrixUser)
}
val logoutState = logoutPresenter.present()
val rageshakeState = rageshakePresenter.present()
val analyticsState = analyticsPresenter.present()
@ -42,8 +57,12 @@ class PreferencesRootPresenter @Inject constructor(
logoutState = logoutState,
rageshakeState = rageshakeState,
analyticsState = analyticsState,
myUser = Async.Uninitialized,
myUser = matrixUser.value,
showDeveloperSettings = showDeveloperSettings
)
}
private fun CoroutineScope.initialLoad(matrixUser: MutableState<MatrixUser?>) = launch {
matrixUser.value = currentUserProvider.provide()
}
}

View file

@ -19,13 +19,12 @@ package io.element.android.features.preferences.impl.root
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
import io.element.android.features.logout.api.LogoutPreferenceState
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.user.MatrixUser
data class PreferencesRootState(
val logoutState: LogoutPreferenceState,
val rageshakeState: RageshakePreferencesState,
val analyticsState: AnalyticsPreferencesState,
val myUser: Async<MatrixUser>,
val myUser: MatrixUser?,
val showDeveloperSettings: Boolean
)

View file

@ -19,12 +19,11 @@ package io.element.android.features.preferences.impl.root
import io.element.android.features.analytics.api.preferences.aAnalyticsPreferencesState
import io.element.android.features.logout.api.aLogoutPreferenceState
import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState
import io.element.android.libraries.architecture.Async
fun aPreferencesRootState() = PreferencesRootState(
logoutState = aLogoutPreferenceState(),
rageshakeState = aRageshakePreferencesState(),
analyticsState = aAnalyticsPreferencesState(),
myUser = Async.Uninitialized,
myUser = null,
showDeveloperSettings = true
)

View file

@ -92,5 +92,5 @@ fun PreferencesRootViewDarkPreview(@PreviewParameter(MatrixUserProvider::class)
@Composable
private fun ContentToPreview(matrixUser: MatrixUser) {
PreferencesRootView(aPreferencesRootState().copy(myUser = Async.Success(matrixUser)))
PreferencesRootView(aPreferencesRootState().copy(myUser = matrixUser))
}

View file

@ -16,14 +16,10 @@
package io.element.android.features.preferences.impl.user
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.matrix.api.user.MatrixUser
@ -32,16 +28,13 @@ import io.element.android.libraries.matrix.ui.components.MatrixUserWithNullProvi
@Composable
fun UserPreferences(
user: Async<MatrixUser>,
user: MatrixUser?,
modifier: Modifier = Modifier,
) {
when (val userData = user.dataOrNull()) {
null -> Spacer(modifier = modifier.height(1.dp))
else -> MatrixUserHeader(
modifier = modifier,
matrixUser = userData
)
}
MatrixUserHeader(
modifier = modifier,
matrixUser = user
)
}
@Preview
@ -56,9 +49,5 @@ internal fun UserPreferencesDarkPreview(@PreviewParameter(MatrixUserWithNullProv
@Composable
private fun ContentToPreview(matrixUser: MatrixUser?) {
if (matrixUser == null) {
UserPreferences(Async.Uninitialized)
} else {
UserPreferences(Async.Success(matrixUser))
}
UserPreferences(matrixUser)
}

View file

@ -28,6 +28,10 @@ import io.element.android.features.rageshake.impl.preferences.DefaultRageshakePr
import io.element.android.features.rageshake.test.rageshake.FakeRageShake
import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.user.CurrentUserProvider
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.FakeMatrixClient
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -35,27 +39,36 @@ import org.junit.Test
class PreferencesRootPresenterTest {
@Test
fun `present - initial state`() = runTest {
val logoutPresenter = DefaultLogoutPreferencePresenter(FakeMatrixClient())
val matrixClient = FakeMatrixClient()
val logoutPresenter = DefaultLogoutPreferencePresenter(matrixClient)
val rageshakePresenter = DefaultRageshakePreferencesPresenter(FakeRageShake(), FakeRageshakeDataStore())
val analyticsPresenter = DefaultAnalyticsPreferencesPresenter(FakeAnalyticsService(), A_BUILD_META)
val presenter = PreferencesRootPresenter(
logoutPresenter,
rageshakePresenter,
analyticsPresenter,
CurrentUserProvider(matrixClient),
A_BUILD_META.buildType
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.logoutState.logoutAction).isEqualTo(Async.Uninitialized)
assertThat(initialState.analyticsState.isEnabled).isFalse()
assertThat(initialState.rageshakeState.isEnabled).isTrue()
assertThat(initialState.rageshakeState.isSupported).isTrue()
assertThat(initialState.rageshakeState.sensitivity).isEqualTo(1.0f)
assertThat(initialState.myUser).isEqualTo(Async.Uninitialized)
assertThat(initialState.showDeveloperSettings).isEqualTo(true)
assertThat(initialState.myUser).isNull()
val loadedState = awaitItem()
assertThat(loadedState.logoutState.logoutAction).isEqualTo(Async.Uninitialized)
assertThat(loadedState.analyticsState.isEnabled).isFalse()
assertThat(loadedState.rageshakeState.isEnabled).isTrue()
assertThat(loadedState.rageshakeState.isSupported).isTrue()
assertThat(loadedState.rageshakeState.sensitivity).isEqualTo(1.0f)
assertThat(loadedState.myUser).isEqualTo(
MatrixUser(
userId = matrixClient.sessionId,
displayName = A_USER_NAME,
avatarUrl = AN_AVATAR_URL
)
)
assertThat(loadedState.showDeveloperSettings).isEqualTo(true)
}
}
}