diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt index 6a7e7cfcf5..21071a6831 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt @@ -46,27 +46,16 @@ class ShowQrCodePresenter( var qrCodeRotationCounter by remember { mutableIntStateOf(MAX_QR_CODE_ROTATION) } val state by produceState( initialValue = ShowQrCodeState( - data1 = AsyncData.Success(initialData), - data2 = AsyncData.Uninitialized, - dataToRender = 1, + data = AsyncData.Success(initialData), ) ) { linkNewMobileHandler.stepFlow.collect { step -> - val currentValue = value when (step) { is LinkMobileStep.QrReady -> { loadingJob?.cancel() - if (currentValue.dataToRender == 1) { - value = currentValue.copy( - data2 = AsyncData.Success(step.data), - dataToRender = 2, - ) - } else { - value = currentValue.copy( - data1 = AsyncData.Success(step.data), - dataToRender = 1, - ) - } + value = ShowQrCodeState( + data = AsyncData.Success(step.data), + ) } is LinkMobileStep.QrRotating -> { if (qrCodeRotationCounter-- > 0) { @@ -75,17 +64,9 @@ class ShowQrCodePresenter( // Ensure that outdated data is not rendered too long while rotating QR code loadingJob = launch { delay(1000) - if (currentValue.dataToRender == 1) { - value = currentValue.copy( - data2 = AsyncData.Loading(), - dataToRender = 2, - ) - } else { - value = currentValue.copy( - data1 = AsyncData.Loading(), - dataToRender = 1, - ) - } + value = ShowQrCodeState( + data = AsyncData.Loading(), + ) } } else { Timber.tag(tag.value).w("Max QR code rotation reached, not rotating anymore") diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeState.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeState.kt index 76302b71aa..e69dde8264 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeState.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeState.kt @@ -10,7 +10,5 @@ package io.element.android.features.linknewdevice.impl.screens.qrcode import io.element.android.libraries.architecture.AsyncData data class ShowQrCodeState( - val data1: AsyncData, - val data2: AsyncData, - val dataToRender: Int, + val data: AsyncData, ) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeStateProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeStateProvider.kt index 6079d0918c..e6d33c2544 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeStateProvider.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeStateProvider.kt @@ -15,22 +15,13 @@ class ShowQrCodeStateProvider : PreviewParameterProvider { get() = sequenceOf( aShowQrCodeState(), aShowQrCodeState( - data1 = AsyncData.Loading(), - ), - aShowQrCodeState( - data1 = AsyncData.Success("DATA"), - data2 = AsyncData.Success("DATA2"), - dataToRender = 2, + data = AsyncData.Loading(), ), ) } internal fun aShowQrCodeState( - data1: AsyncData = AsyncData.Success("DATA"), - data2: AsyncData = AsyncData.Uninitialized, - dataToRender: Int = 1, + data: AsyncData = AsyncData.Success("DATA"), ) = ShowQrCodeState( - data1 = data1, - data2 = data2, - dataToRender = dataToRender, + data = data, ) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt index 0791847288..ee38342ce2 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt @@ -9,9 +9,11 @@ package io.element.android.features.linknewdevice.impl.screens.qrcode -import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -44,6 +46,7 @@ import kotlinx.collections.immutable.persistentListOf * QrCode display screen: * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2027-23617 */ +@OptIn(ExperimentalAnimationApi::class) @Composable fun ShowQrCodeView( state: ShowQrCodeState, @@ -61,14 +64,15 @@ fun ShowQrCodeView( Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, ) { - Box { + AnimatedContent( + targetState = state.data.dataOrNull(), + transitionSpec = { + fadeIn().togetherWith(fadeOut()) + } + ) { data -> QrCodeOrLoading( - isVisible = state.dataToRender == 1, - data = state.data1.dataOrNull(), - ) - QrCodeOrLoading( - isVisible = state.dataToRender == 2, - data = state.data2.dataOrNull(), + modifier = modifier.size(220.dp), + data = data, ) } Spacer(modifier = Modifier.height(32.dp)) @@ -92,31 +96,21 @@ fun ShowQrCodeView( @Composable private fun QrCodeOrLoading( - isVisible: Boolean, data: String?, modifier: Modifier = Modifier, ) { - AnimatedVisibility( - modifier = modifier, - visible = isVisible, - enter = fadeIn(), - exit = fadeOut(), - ) { - if (data == null) { - Box( - modifier = Modifier - .size(220.dp), - contentAlignment = Alignment.Center, - ) { - CircularProgressIndicator() - } - } else { - QrCodeImage( - data = data, - modifier = Modifier - .size(220.dp) - ) + if (data == null) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + CircularProgressIndicator() } + } else { + QrCodeImage( + modifier = modifier, + data = data, + ) } } diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenterTest.kt index 8ecc0ea008..f92cf66102 100644 --- a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenterTest.kt +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenterTest.kt @@ -32,9 +32,7 @@ class ShowQrCodePresenterTest { fun `present - initial state`() = runTest { createPresenter().test { val initialState = awaitItem() - assertThat(initialState.data1.dataOrNull()).isEqualTo("DATA") - assertThat(initialState.data2.isUninitialized()).isTrue() - assertThat(initialState.dataToRender).isEqualTo(1) + assertThat(initialState.data.dataOrNull()).isEqualTo("DATA") } } @@ -61,8 +59,7 @@ class ShowQrCodePresenterTest { ) runCurrent() val finalState = awaitItem() - assertThat(finalState.data2.isLoading()).isTrue() - assertThat(finalState.dataToRender).isEqualTo(2) + assertThat(finalState.data.isLoading()).isTrue() createLinkMobileHandlerResult.assertions().isCalledExactly(2) } } @@ -90,9 +87,7 @@ class ShowQrCodePresenterTest { LinkMobileStep.QrReady("DATA2") ) val finalState = awaitItem() - assertThat(finalState.data1.dataOrNull()).isEqualTo("DATA") - assertThat(finalState.data2.dataOrNull()).isEqualTo("DATA2") - assertThat(finalState.dataToRender).isEqualTo(2) + assertThat(finalState.data.dataOrNull()).isEqualTo("DATA2") } } diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_2_en.png deleted file mode 100644 index 2f06e29863..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:151eaa4b5619afd76b94de518dc2868d735b6b7a167056941e1f429520c3bf0d -size 31836 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_2_en.png deleted file mode 100644 index 99f134760d..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aa2303b621070608ba79673322f61bfa686b9729eb445913dd8d059d62c9764a -size 32374