From 2cb2ecb24349454f71afd0eac05a02e60e4052c8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 14:37:53 +0200 Subject: [PATCH 01/13] Remove dead code. --- .../libraries/matrix/test/roomlist/FakeRoomListService.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt index 4b8da511d0..c489a0bb1d 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.flow.StateFlow class FakeRoomListService : RoomListService { private val allRoomSummariesFlow = MutableStateFlow>(emptyList()) - private val inviteRoomSummariesFlow = MutableStateFlow>(emptyList()) private val allRoomsLoadingStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) private val roomListStateFlow = MutableStateFlow(RoomListService.State.Idle) private val syncIndicatorStateFlow = MutableStateFlow(RoomListService.SyncIndicator.Hide) @@ -35,10 +34,6 @@ class FakeRoomListService : RoomListService { allRoomSummariesFlow.emit(roomSummaries) } - suspend fun postInviteRooms(roomSummaries: List) { - inviteRoomSummariesFlow.emit(roomSummaries) - } - suspend fun postAllRoomsLoadingState(loadingState: RoomList.LoadingState) { allRoomsLoadingStateFlow.emit(loadingState) } From ef316032f858dc6cd36b3d81cdac8aeee750115a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 14:45:13 +0200 Subject: [PATCH 02/13] Fix toString content --- .../textcomposer/components/markdown/StableCharSequence.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/StableCharSequence.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/StableCharSequence.kt index 5491f9ccf4..8792a8b30d 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/StableCharSequence.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/StableCharSequence.kt @@ -37,6 +37,6 @@ class StableCharSequence(initialText: CharSequence = "") { fun needsDisplaying(): Boolean = needsDisplaying override fun toString(): String { - return "ImmutableCharSequence(value='$value', needsDisplaying=$needsDisplaying)" + return "StableCharSequence(value='$value', needsDisplaying=$needsDisplaying)" } } From c6f5033661b093fe9ded9ddbb0f74b7a5b14ca80 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 14:47:47 +0200 Subject: [PATCH 03/13] Add missing preview --- .../impl/changeserver/ChangeServerStateProvider.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt index 014c3352ce..b8452788b6 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt @@ -17,16 +17,22 @@ package io.element.android.features.login.impl.changeserver import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.login.impl.error.ChangeServerError import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.ui.strings.CommonStrings open class ChangeServerStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aChangeServerState(), + aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.Error(CommonStrings.error_unknown))), + aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.SlidingSyncAlert)), ) } -fun aChangeServerState() = ChangeServerState( - changeServerAction = AsyncData.Uninitialized, +fun aChangeServerState( + changeServerAction: AsyncData = AsyncData.Uninitialized, +) = ChangeServerState( + changeServerAction = changeServerAction, eventSink = {} ) From 47856c22ce3c4993f69c81f4306a4fd0b55c2836 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 15:39:43 +0200 Subject: [PATCH 04/13] Allow scroll in the "Enter recovery key" screen. #3042 --- .../enter/SecureBackupEnterRecoveryKeyView.kt | 3 +- .../designsystem/atomic/pages/FlowStepPage.kt | 2 + .../atomic/pages/HeaderFooterPage.kt | 64 ++++++++++++++----- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt index cbb46849a9..952bfaad5f 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt @@ -55,6 +55,7 @@ fun SecureBackupEnterRecoveryKeyView( FlowStepPage( modifier = modifier, + isScrollable = true, onBackClick = onBackClick, iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()), title = stringResource(id = R.string.screen_recovery_key_confirm_title), @@ -70,7 +71,7 @@ private fun Content( state: SecureBackupEnterRecoveryKeyState, ) { RecoveryKeyView( - modifier = Modifier.padding(top = 52.dp), + modifier = Modifier.padding(top = 52.dp, bottom = 32.dp), state = state.recoveryKeyViewState, onClick = null, onChange = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/FlowStepPage.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/FlowStepPage.kt index 9218061638..7480f2115d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/FlowStepPage.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/FlowStepPage.kt @@ -52,6 +52,7 @@ fun FlowStepPage( iconStyle: BigIcon.Style, title: String, modifier: Modifier = Modifier, + isScrollable: Boolean = false, onBackClick: (() -> Unit)? = null, subTitle: String? = null, buttons: @Composable ColumnScope.() -> Unit = {}, @@ -62,6 +63,7 @@ fun FlowStepPage( } HeaderFooterPage( modifier = modifier, + isScrollable = isScrollable, topBar = { TopAppBar( navigationIcon = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/HeaderFooterPage.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/HeaderFooterPage.kt index 4dd00a67d9..53b47b7422 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/HeaderFooterPage.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/HeaderFooterPage.kt @@ -22,7 +22,9 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -39,6 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.Text * @param modifier Classical modifier. * @param paddingValues padding values to apply to the content. * @param containerColor color of the container. Set to [Color.Transparent] if you provide a background in the [modifier]. + * @param isScrollable if the whole content should be scrollable. * @param background optional background component. * @param topBar optional topBar. * @param header optional header. @@ -50,6 +53,7 @@ fun HeaderFooterPage( modifier: Modifier = Modifier, paddingValues: PaddingValues = PaddingValues(20.dp), containerColor: Color = MaterialTheme.colorScheme.background, + isScrollable: Boolean = false, background: @Composable () -> Unit = {}, topBar: @Composable () -> Unit = {}, header: @Composable () -> Unit = {}, @@ -63,25 +67,53 @@ fun HeaderFooterPage( ) { padding -> Box { background() - Column( - modifier = Modifier - .padding(paddingValues = paddingValues) - .padding(padding) - .consumeWindowInsets(padding) - ) { - // Header - header() - // Content + if (isScrollable) { + // Render in a LazyColumn + LazyColumn( + modifier = Modifier + .padding(paddingValues = paddingValues) + .padding(padding) + .consumeWindowInsets(padding) + .imePadding() + ) { + // Header + item { + header() + } + // Content + item { + content() + } + // Footer + item { + Box(modifier = Modifier.padding(horizontal = 16.dp)) { + footer() + } + } + } + } else { + // Render in a Column Column( modifier = Modifier - .weight(1f) - .fillMaxWidth(), + .padding(paddingValues = paddingValues) + .padding(padding) + .consumeWindowInsets(padding) + .imePadding() ) { - content() - } - // Footer - Box(modifier = Modifier.padding(horizontal = 16.dp)) { - footer() + // Header + header() + // Content + Column( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + ) { + content() + } + // Footer + Box(modifier = Modifier.padding(horizontal = 16.dp)) { + footer() + } } } } From cd9f3ad3fb39f1f731fd4f2cebea1e56235b7ded Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 15:54:45 +0200 Subject: [PATCH 05/13] Use receiver. --- .../impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt | 2 +- .../features/verifysession/impl/VerifySelfSessionViewTest.kt | 2 +- .../impl/components/markdown/MarkdownTextInputTest.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt index c42847a323..ef7d356d65 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt @@ -98,7 +98,7 @@ class SecureBackupEnterRecoveryKeyViewTest { onBackClick: () -> Unit = EnsureNeverCalled(), onCreateNewRecoveryKey: () -> Unit = EnsureNeverCalled(), ) { - rule.setContent { + setContent { SecureBackupEnterRecoveryKeyView( state = state, onSuccess = onDone, diff --git a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionViewTest.kt b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionViewTest.kt index 15a1ffedac..f19f3e1f29 100644 --- a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionViewTest.kt +++ b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionViewTest.kt @@ -218,7 +218,7 @@ class VerifySelfSessionViewTest { onEnterRecoveryKey: () -> Unit = EnsureNeverCalled(), onFinished: () -> Unit = EnsureNeverCalled(), ) { - rule.setContent { + setContent { VerifySelfSessionView( state = state, onEnterRecoveryKey = onEnterRecoveryKey, diff --git a/libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt b/libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt index dc2d197db8..bedd3c9c1e 100644 --- a/libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt +++ b/libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt @@ -183,7 +183,7 @@ class MarkdownTextInputTest { onTyping: (Boolean) -> Unit = {}, onSuggestionReceived: (Suggestion?) -> Unit = {}, ) { - rule.setContent { + setContent { val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus) MarkdownTextInput( state = state, From cc57652e55ffbbbf8239ab54b138c79bdcba72a3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 16:01:12 +0200 Subject: [PATCH 06/13] Fix UI test and add missing test. --- .../SecureBackupEnterRecoveryKeyViewTest.kt | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt index ef7d356d65..42b80441ce 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyViewTest.kt @@ -19,8 +19,12 @@ package io.element.android.features.securebackup.impl.enter import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performImeAction +import androidx.compose.ui.test.performTextInput import androidx.test.ext.junit.runners.AndroidJUnit4 import io.element.android.features.securebackup.impl.R +import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled @@ -33,6 +37,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.junit.runner.RunWith +import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) class SecureBackupEnterRecoveryKeyViewTest { @@ -61,6 +66,7 @@ class SecureBackupEnterRecoveryKeyViewTest { } @Test + @Config(qualifiers = "h1024dp") fun `tapping on Continue when key is valid - calls expected action`() { val recorder = EventsRecorder() rule.setSecureBackupEnterRecoveryKeyView( @@ -72,6 +78,31 @@ class SecureBackupEnterRecoveryKeyViewTest { } @Test + fun `entering a char emits the expected event`() { + val recorder = EventsRecorder() + val keyValue = aFormattedRecoveryKey() + rule.setSecureBackupEnterRecoveryKeyView( + aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder), + ) + rule.onNodeWithText(keyValue).performTextInput("X") + recorder.assertSingle( + SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("X$keyValue") + ) + } + + @Test + fun `validating from keyboard emits the expected event`() { + val recorder = EventsRecorder() + val keyValue = aFormattedRecoveryKey() + rule.setSecureBackupEnterRecoveryKeyView( + aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder), + ) + rule.onNodeWithText(keyValue).performImeAction() + recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit) + } + + @Test + @Config(qualifiers = "h1024dp") fun `tapping on Lost your recovery key - calls onCreateNewRecoveryKey`() { ensureCalledOnce { callback -> rule.setSecureBackupEnterRecoveryKeyView( From 352a4b55266f76c9e4519b9916afe63caa0c249f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 18 Jun 2024 14:35:04 +0000 Subject: [PATCH 07/13] Update screenshots --- ...w_null_ChangeServerView-Day-1_2_null_1,NEXUS_5,1.0,en].png | 3 +++ ...w_null_ChangeServerView-Day-1_2_null_2,NEXUS_5,1.0,en].png | 3 +++ ...null_ChangeServerView-Night-1_3_null_1,NEXUS_5,1.0,en].png | 3 +++ ...null_ChangeServerView-Night-1_3_null_2,NEXUS_5,1.0,en].png | 3 +++ ...kupEnterRecoveryKeyView-Day-3_4_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...kupEnterRecoveryKeyView-Day-3_4_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...kupEnterRecoveryKeyView-Day-3_4_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...kupEnterRecoveryKeyView-Day-3_4_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...pEnterRecoveryKeyView-Night-3_5_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...pEnterRecoveryKeyView-Night-3_5_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...pEnterRecoveryKeyView-Night-3_5_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...pEnterRecoveryKeyView-Night-3_5_null_3,NEXUS_5,1.0,en].png | 4 ++-- 12 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_1,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_2,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_1,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..f217b40329 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6eee7bae50007c89720f7a0f14512828a202db0a6c139690d09dd2e051af8ed +size 11766 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..ab2de8d465 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Day-1_2_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d053268a0b2e968a35c02ab58dc5f0a9ff8e9b3412a6c88f5bfeb94031bc9a +size 18742 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..cdd23ee8c2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a096a8e2170f14cf87063bf25c65b8a019531979b7702755bd86da84bb1a2eda +size 10257 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..24785de76a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.changeserver_ChangeServerView_null_ChangeServerView-Night-1_3_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fd3519872e9e0036da1cf158dc8c8c838545b281c9c5fa87c84a2220c066131 +size 16723 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_0,NEXUS_5,1.0,en].png index d80661e2f0..e17910c098 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d703bbf9fa2dd21d4b7e1dea3f9096520e04dddc61a66286f28e1be2b6deae41 -size 37724 +oid sha256:485585964998ee6bb7bb6ba208f2f465795a1b1ef59b3e44535b2d60ba9ef8a4 +size 37761 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_1,NEXUS_5,1.0,en].png index bd6b12d76a..39ab9a25a3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:278063037575311b7ad24f91c2403c5e9656871ab956938d163fa94a89a2b23e -size 49038 +oid sha256:95a05799a39675cfbb8c2df269131e5dd236c3298a1dadafe15b7c89a62be962 +size 49077 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_2,NEXUS_5,1.0,en].png index 8fe4cdc959..a1d02d23dc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eeca1217caff14f715fcc214dc7f2a01c5d022778c1d9331d41858b836df2abc -size 46971 +oid sha256:254973e1b41987fb6dd9db63b5acae4557467e2541867a4fb9448b88851e5fe4 +size 46993 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_3,NEXUS_5,1.0,en].png index 9c92289720..dfc236cd69 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-3_4_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c6277560b3b430a446fb4e87b3db59331e5e024798d85bf6be6672a6508c6ef -size 41076 +oid sha256:cb58ee8ee32d1e308b898980f27317193bff4b0e00f800037834b02793b34dce +size 41111 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_0,NEXUS_5,1.0,en].png index a098ebb4d1..52e79a83d6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:700e9c08e7407d2d81e1a090720885cc59b92ab95106258a646532a277cf2012 -size 36646 +oid sha256:2d2fc075202325aece0e74f962e5e6a387934d7782a1b39a9226c2b529ecf0b1 +size 36809 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_1,NEXUS_5,1.0,en].png index c8e86397c2..8b5ec130aa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db6b5ec486e460be8cc3df6d827ae04d67ba136d2cdf20b14d1c1ab08198136b -size 47557 +oid sha256:6909fcc10374f46d14ed628a4c1df0f4aba1fba874d2aa1b5554a74409dae861 +size 47737 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_2,NEXUS_5,1.0,en].png index 3523119ef1..ebd15db380 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf789850fac3937f98b7d0fc27f030fd0245212bc6087cb34e7d1aebae850e27 -size 46279 +oid sha256:48e95b0eac9a83ce6abf5d82e904faf4081496d399eed9f8e4d806393f042a14 +size 46286 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_3,NEXUS_5,1.0,en].png index e015951f67..0e175854a2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-3_5_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:549c3981541b71058c6608a9cffee28a6cb95b1eab819db5de86c43eed9961e3 -size 38319 +oid sha256:83c91d4e1bc3b9021c91d353b63a63c1893fdc79de57f91d8a6446b84bae657a +size 38441 From 420872fed9d3a9662cfbee85314c7a69b44e1f94 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 18 Jun 2024 15:09:37 +0200 Subject: [PATCH 08/13] Rust : handle api changes for 0.2.27 --- gradle/libs.versions.toml | 2 +- .../matrix/api/room/MatrixRoomInfo.kt | 2 -- .../matrix/impl/room/MatrixRoomInfoMapper.kt | 9 ++---- .../matrix/impl/room/RustMatrixRoom.kt | 4 +-- .../roomlist/RoomSummaryDetailsFactory.kt | 7 +++-- .../impl/roomlist/RoomSummaryListProcessor.kt | 8 ++---- .../impl/timeline/RoomTimelineExtensions.kt | 17 +++-------- .../matrix/impl/timeline/RustTimeline.kt | 28 +++++++++++++------ .../roomlist/RoomSummaryListProcessorTest.kt | 2 +- .../matrix/test/room/FakeMatrixRoom.kt | 3 -- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 64b60ca82e..13c2e02858 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.25" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.27" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt index 8379d30781..4fae22ad57 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt @@ -20,7 +20,6 @@ import androidx.compose.runtime.Immutable import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -41,7 +40,6 @@ data class MatrixRoomInfo( val canonicalAlias: RoomAlias?, val alternativeAliases: ImmutableList, val currentUserMembership: CurrentUserMembership, - val latestEvent: EventTimelineItem?, val inviter: RoomMember?, val activeMembersCount: Long, val invitedMembersCount: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt index 8063c67069..d01a7d1740 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt @@ -23,19 +23,15 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper -import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentMap -import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode -class MatrixRoomInfoMapper( - private val timelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(), -) { - fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.use { +class MatrixRoomInfoMapper { + fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.let { return MatrixRoomInfo( id = RoomId(it.id), name = it.displayName, @@ -50,7 +46,6 @@ class MatrixRoomInfoMapper( canonicalAlias = it.canonicalAlias?.let(::RoomAlias), alternativeAliases = it.alternativeAliases.toImmutableList(), currentUserMembership = it.membership.map(), - latestEvent = it.latestEvent?.use(timelineItemMapper::map), inviter = it.inviter?.let(RoomMemberMapper::map), activeMembersCount = it.activeMembersCount.toLong(), invitedMembersCount = it.invitedMembersCount.toLong(), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index f10938cc19..1a14c7a860 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -111,7 +111,7 @@ class RustMatrixRoom( override val roomInfoFlow: Flow = mxCallbackFlow { launch { - val initial = innerRoom.roomInfo().use(matrixRoomInfoMapper::map) + val initial = innerRoom.roomInfo().let(matrixRoomInfoMapper::map) channel.trySend(initial) } innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener { @@ -199,7 +199,7 @@ class RustMatrixRoom( } override val displayName: String - get() = runCatching { innerRoom.displayName() }.getOrDefault("") + get() = runCatching { innerRoom.displayName() ?: "" }.getOrDefault("") override val topic: String? get() = runCatching { innerRoom.topic() }.getOrDefault(null) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt index f9c62c2f6a..3ccc071316 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt @@ -23,12 +23,13 @@ import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotific import io.element.android.libraries.matrix.impl.room.map import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory -import org.matrix.rustcomponents.sdk.RoomInfo +import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.use class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) { - fun create(roomInfo: RoomInfo): RoomSummaryDetails { - val latestRoomMessage = roomInfo.latestEvent?.use { + suspend fun create(roomListItem: RoomListItem): RoomSummaryDetails { + val roomInfo = roomListItem.roomInfo() + val latestRoomMessage = roomListItem.latestEvent()?.use { roomMessageFactory.create(it) } return RoomSummaryDetails( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt index 35f301c87e..3cfd01f54c 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt @@ -120,11 +120,9 @@ class RoomSummaryListProcessor( private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary { val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> - roomListItem.roomInfo().use { roomInfo -> - RoomSummary.Filled( - details = roomSummaryDetailsFactory.create(roomInfo) - ) - } + RoomSummary.Filled( + details = roomSummaryDetailsFactory.create(roomListItem) + ) } ?: buildEmptyRoomSummary() roomSummariesByIdentifier[builtRoomSummary.identifier()] = builtRoomSummary return builtRoomSummary diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt index 2ce9d4d435..dc012f67b3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt @@ -17,7 +17,6 @@ package io.element.android.libraries.matrix.impl.timeline import io.element.android.libraries.matrix.impl.util.cancelAndDestroy -import io.element.android.libraries.matrix.impl.util.destroyAll import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.trySendBlocking @@ -28,7 +27,6 @@ import kotlinx.coroutines.flow.catch import org.matrix.rustcomponents.sdk.PaginationStatusListener import org.matrix.rustcomponents.sdk.Timeline import org.matrix.rustcomponents.sdk.TimelineDiff -import org.matrix.rustcomponents.sdk.TimelineItem import org.matrix.rustcomponents.sdk.TimelineListener import timber.log.Timber import uniffi.matrix_sdk_ui.LiveBackPaginationStatus @@ -47,7 +45,7 @@ internal fun Timeline.liveBackPaginationStatus(): Flow Timber.d(it, "liveBackPaginationStatus() failed") }.buffer(Channel.UNLIMITED) -internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List) -> Unit): Flow> = +internal fun Timeline.timelineDiffFlow(): Flow> = callbackFlow { val listener = object : TimelineListener { override fun onUpdate(diff: List) { @@ -55,16 +53,10 @@ internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List - postItems(initialList) - }.onEach { diffs -> - if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) { - onNewSyncedEvent() + inner.timelineDiffFlow() + .onEach { diffs -> + if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) { + onNewSyncedEvent() + } + postDiffs(diffs) } - postDiffs(diffs) - }.launchIn(this) + .launchIn(this) launch { fetchMembers() @@ -273,8 +274,19 @@ class RustTimeline( } private suspend fun postDiffs(diffs: List) { + val diffsToProcess = diffs.toMutableList() + if (!isInit.get()) { + val resetDiff = diffsToProcess.firstOrNull { it.change() == TimelineChange.RESET } + if (resetDiff != null) { + // Keep using the postItems logic so we can post the timelineItems asap. + postItems(resetDiff.reset() ?: emptyList()) + diffsToProcess.remove(resetDiff) + } + } initLatch.await() - timelineDiffProcessor.postDiffs(diffs) + if (diffsToProcess.isNotEmpty()) { + timelineDiffProcessor.postDiffs(diffsToProcess) + } } override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List): Result = withContext(dispatcher) { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 4ff46c2bc4..6f42553ced 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -170,7 +170,7 @@ class RoomSummaryListProcessorTest { override suspend fun applyInput(input: RoomListInput) = Unit - override suspend fun room(roomId: String): RoomListItem { + override fun room(roomId: String): RoomListItem { return RoomListItem(Pointer.NULL) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index d5dddf3b7e..5583f6b11e 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -45,7 +45,6 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -746,7 +745,6 @@ fun aRoomInfo( canonicalAlias: RoomAlias? = null, alternativeAliases: List = emptyList(), currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, - latestEvent: EventTimelineItem? = null, inviter: RoomMember? = null, activeMembersCount: Long = 1, invitedMembersCount: Long = 0, @@ -771,7 +769,6 @@ fun aRoomInfo( canonicalAlias = canonicalAlias, alternativeAliases = alternativeAliases.toImmutableList(), currentUserMembership = currentUserMembership, - latestEvent = latestEvent, inviter = inviter, activeMembersCount = activeMembersCount, invitedMembersCount = invitedMembersCount, From a8cd659b1f5cac5c65797cbcefc74ed787ec27ba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 18:04:30 +0200 Subject: [PATCH 09/13] Avoid restoring several MatrixClient --- .../api/auth/MatrixAuthenticationService.kt | 1 + .../firebase/FirebaseNewTokenHandler.kt | 8 ++-- .../DefaultFirebaseNewTokenHandlerTest.kt | 40 ++++++++----------- .../UnifiedPushNewGatewayHandler.kt | 8 ++-- ...DefaultUnifiedPushNewGatewayHandlerTest.kt | 12 +++--- 5 files changed, 32 insertions(+), 37 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt index c7d3e79144..9b96b96eec 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt @@ -31,6 +31,7 @@ interface MatrixAuthenticationService { /** * Restore a session from a [sessionId]. * Do not restore anything it the access token is not valid anymore. + * Generally this method should not be used directly, prefer using [MatrixClientProvider.getOrRestore] instead. */ suspend fun restoreSession(sessionId: SessionId): Result fun getHomeserverDetails(): StateFlow diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseNewTokenHandler.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseNewTokenHandler.kt index baddab1a0d..585f486004 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseNewTokenHandler.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseNewTokenHandler.kt @@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.AppScope -import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushstore.api.UserPushStoreFactory @@ -43,7 +43,7 @@ class DefaultFirebaseNewTokenHandler @Inject constructor( private val pusherSubscriber: PusherSubscriber, private val sessionStore: SessionStore, private val userPushStoreFactory: UserPushStoreFactory, - private val matrixAuthenticationService: MatrixAuthenticationService, + private val matrixClientProvider: MatrixClientProvider, private val firebaseStore: FirebaseStore, ) : FirebaseNewTokenHandler { override suspend fun handle(firebaseToken: String) { @@ -54,8 +54,8 @@ class DefaultFirebaseNewTokenHandler @Inject constructor( .forEach { sessionId -> val userDataStore = userPushStoreFactory.getOrCreate(sessionId) if (userDataStore.getPushProviderName() == FirebaseConfig.NAME) { - matrixAuthenticationService - .restoreSession(sessionId) + matrixClientProvider + .getOrRestore(sessionId) .onFailure { Timber.tag(loggerTag.value).e(it, "Failed to restore session $sessionId") } diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt index aca3ccf054..48dcfc263b 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt @@ -18,13 +18,13 @@ package io.element.android.libraries.pushproviders.firebase import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.FakeMatrixClient -import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService +import io.element.android.libraries.matrix.test.FakeMatrixClientProvider import io.element.android.libraries.push.test.FakePusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushstore.api.UserPushStoreFactory @@ -64,16 +64,14 @@ class DefaultFirebaseNewTokenHandlerTest { storeData(aSessionData(A_USER_ID_2)) storeData(aSessionData(A_USER_ID_3)) }, - matrixAuthenticationService = FakeMatrixAuthenticationService( - matrixClientResult = { sessionId -> - when (sessionId) { - A_USER_ID -> Result.success(aMatrixClient1) - A_USER_ID_2 -> Result.success(aMatrixClient2) - A_USER_ID_3 -> Result.success(aMatrixClient3) - else -> Result.failure(IllegalStateException()) - } + matrixClientProvider = FakeMatrixClientProvider { sessionId -> + when (sessionId) { + A_USER_ID -> Result.success(aMatrixClient1) + A_USER_ID_2 -> Result.success(aMatrixClient2) + A_USER_ID_3 -> Result.success(aMatrixClient3) + else -> Result.failure(IllegalStateException()) } - ), + }, userPushStoreFactory = FakeUserPushStoreFactory( userPushStore = { sessionId -> when (sessionId) { @@ -103,11 +101,9 @@ class DefaultFirebaseNewTokenHandlerTest { sessionStore = InMemoryMultiSessionsStore().apply { storeData(aSessionData(A_USER_ID)) }, - matrixAuthenticationService = FakeMatrixAuthenticationService( - matrixClientResult = { _ -> - Result.failure(IllegalStateException()) - } - ), + matrixClientProvider = FakeMatrixClientProvider { + Result.failure(IllegalStateException()) + }, userPushStoreFactory = FakeUserPushStoreFactory( userPushStore = { _ -> FakeUserPushStore(pushProviderName = FirebaseConfig.NAME) @@ -129,11 +125,9 @@ class DefaultFirebaseNewTokenHandlerTest { sessionStore = InMemoryMultiSessionsStore().apply { storeData(aSessionData(A_USER_ID)) }, - matrixAuthenticationService = FakeMatrixAuthenticationService( - matrixClientResult = { _ -> - Result.success(aMatrixClient1) - } - ), + matrixClientProvider = FakeMatrixClientProvider { + Result.success(aMatrixClient1) + }, userPushStoreFactory = FakeUserPushStoreFactory( userPushStore = { _ -> FakeUserPushStore(pushProviderName = FirebaseConfig.NAME) @@ -152,14 +146,14 @@ class DefaultFirebaseNewTokenHandlerTest { pusherSubscriber: PusherSubscriber = FakePusherSubscriber(), sessionStore: SessionStore = InMemorySessionStore(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), - matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(), + matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider(), firebaseStore: FirebaseStore = InMemoryFirebaseStore(), ): FirebaseNewTokenHandler { return DefaultFirebaseNewTokenHandler( pusherSubscriber = pusherSubscriber, sessionStore = sessionStore, userPushStoreFactory = userPushStoreFactory, - matrixAuthenticationService = matrixAuthenticationService, + matrixClientProvider = matrixClientProvider, firebaseStore = firebaseStore ) } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushNewGatewayHandler.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushNewGatewayHandler.kt index f839e6a03e..f91595bf5d 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushNewGatewayHandler.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushNewGatewayHandler.kt @@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.AppScope -import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret @@ -41,7 +41,7 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor( private val pusherSubscriber: PusherSubscriber, private val userPushStoreFactory: UserPushStoreFactory, private val pushClientSecret: PushClientSecret, - private val matrixAuthenticationService: MatrixAuthenticationService, + private val matrixClientProvider: MatrixClientProvider, ) : UnifiedPushNewGatewayHandler { override suspend fun handle(endpoint: String, pushGateway: String, clientSecret: String): Result { // Register the pusher for the session with this client secret, if is it using UnifiedPush. @@ -52,8 +52,8 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor( } val userDataStore = userPushStoreFactory.getOrCreate(userId) return if (userDataStore.getPushProviderName() == UnifiedPushConfig.NAME) { - matrixAuthenticationService - .restoreSession(userId) + matrixClientProvider + .getOrRestore(userId) .flatMap { client -> pusherSubscriber.registerPusher(client, endpoint, pushGateway) } diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushNewGatewayHandlerTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushNewGatewayHandlerTest.kt index 09637fcd21..1e2be4947c 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushNewGatewayHandlerTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushNewGatewayHandlerTest.kt @@ -18,11 +18,11 @@ package io.element.android.libraries.pushproviders.unifiedpush import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.test.A_SECRET import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.FakeMatrixClient -import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService +import io.element.android.libraries.matrix.test.FakeMatrixClientProvider import io.element.android.libraries.push.test.FakePusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushstore.api.UserPushStoreFactory @@ -86,7 +86,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest { pusherSubscriber = FakePusherSubscriber( registerPusherResult = { _, _, _ -> Result.failure(IllegalStateException("an error")) } ), - matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }), + matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) }, ) val result = defaultUnifiedPushNewGatewayHandler.handle( endpoint = "aEndpoint", @@ -114,7 +114,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest { pusherSubscriber = FakePusherSubscriber( registerPusherResult = lambda ), - matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }), + matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) }, ) val result = defaultUnifiedPushNewGatewayHandler.handle( endpoint = "aEndpoint", @@ -131,13 +131,13 @@ class DefaultUnifiedPushNewGatewayHandlerTest { pusherSubscriber: PusherSubscriber = FakePusherSubscriber(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), pushClientSecret: PushClientSecret = FakePushClientSecret(), - matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService() + matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider() ): DefaultUnifiedPushNewGatewayHandler { return DefaultUnifiedPushNewGatewayHandler( pusherSubscriber = pusherSubscriber, userPushStoreFactory = userPushStoreFactory, pushClientSecret = pushClientSecret, - matrixAuthenticationService = matrixAuthenticationService + matrixClientProvider = matrixClientProvider, ) } } From 4332357e76295f120434edccf863b4dbcd9c93d3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 18:13:23 +0200 Subject: [PATCH 10/13] Add import for doc. --- .../libraries/matrix/api/auth/MatrixAuthenticationService.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt index 9b96b96eec..591572f222 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt @@ -17,6 +17,7 @@ package io.element.android.libraries.matrix.api.auth import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep import io.element.android.libraries.matrix.api.core.SessionId From 874bf5b901d42de5d4632601088a37b813857d40 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 18 Jun 2024 18:33:04 +0200 Subject: [PATCH 11/13] Ensure that process recreation also use the restoreMutex --- .../kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt index 517becef2a..9828a3f312 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixClientsHolder.kt @@ -74,7 +74,7 @@ class MatrixClientsHolder @Inject constructor(private val authenticationService: // Not ideal but should only happens in case of process recreation. This ensure we restore all the active sessions before restoring the node graphs. runBlocking { sessionIds.forEach { sessionId -> - restore(sessionId) + getOrRestore(sessionId) } } } From 5420cd01ad6c2acc2d766c09845161d29e872fa4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 19 Jun 2024 09:10:41 +0200 Subject: [PATCH 12/13] Typo --- .../io/element/android/appnav/di/MatrixClientsHolderTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixClientsHolderTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixClientsHolderTest.kt index 4fb518b058..76e9475024 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixClientsHolderTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixClientsHolderTest.kt @@ -40,7 +40,7 @@ class MatrixClientsHolderTest { fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) - // Do it again to it the cache + // Do it again to hit the cache assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) } From 13b5170a7da9869767f144c15e033677d9474081 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 08:14:28 +0000 Subject: [PATCH 13/13] Update danger/danger-js action to v12.3.2 --- .github/workflows/danger.yml | 2 +- .github/workflows/quality.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index e51f737e87..4325a1591a 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -11,7 +11,7 @@ jobs: - run: | npm install --save-dev @babel/plugin-transform-flow-strip-types - name: Danger - uses: danger/danger-js@12.3.1 + uses: danger/danger-js@12.3.2 with: args: "--dangerfile ./tools/danger/dangerfile.js" env: diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 15092ad82c..7d0709de44 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -245,7 +245,7 @@ jobs: yarn add danger-plugin-lint-report --dev - name: Danger lint if: always() - uses: danger/danger-js@12.3.1 + uses: danger/danger-js@12.3.2 with: args: "--dangerfile ./tools/danger/dangerfile-lint.js" env: