From ce4c12ce74eb45978e04e53b9cfc3acc8ebb76dd Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 28 Aug 2023 16:45:42 +0100 Subject: [PATCH 001/127] Integrate emojibase - Integrate emojibase datasource - Use element category translations - Use Material emoji category logos --- app/build.gradle.kts | 2 +- .../element/android/x/ElementXApplication.kt | 2 - .../android/x/initializer/EmojiInitializer.kt | 29 ---------- features/messages/impl/build.gradle.kts | 2 +- .../messages/impl/MessagesStateProvider.kt | 3 + .../features/messages/impl/MessagesView.kt | 8 ++- .../CustomReactionBottomSheet.kt | 13 +++-- .../customreaction/CustomReactionEvents.kt | 3 +- .../customreaction/CustomReactionPresenter.kt | 34 +++++++++-- .../customreaction/CustomReactionState.kt | 3 + .../{ => customreaction}/EmojiPicker.kt | 27 +++++---- .../customreaction/EmojibaseExtensions.kt | 58 +++++++++++++++++++ .../CustomReactionPresenterTests.kt | 4 +- gradle/libs.versions.toml | 5 +- 14 files changed, 130 insertions(+), 63 deletions(-) delete mode 100644 app/src/main/kotlin/io/element/android/x/initializer/EmojiInitializer.kt rename features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/{ => customreaction}/EmojiPicker.kt (83%) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 19bb2ea84b..405054d837 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -220,7 +220,7 @@ dependencies { implementation(libs.network.okhttp.logging) implementation(libs.serialization.json) - implementation(libs.vanniktech.emoji) + implementation(libs.matrix.emojibase.bindings) implementation(libs.dagger) kapt(libs.dagger.compiler) diff --git a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt index da8592771c..542ae7090d 100644 --- a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt +++ b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt @@ -23,7 +23,6 @@ import io.element.android.x.di.AppComponent import io.element.android.x.di.DaggerAppComponent import io.element.android.x.info.logApplicationInfo import io.element.android.x.initializer.CrashInitializer -import io.element.android.x.initializer.EmojiInitializer import io.element.android.x.initializer.TracingInitializer class ElementXApplication : Application(), DaggerComponentOwner { @@ -39,7 +38,6 @@ class ElementXApplication : Application(), DaggerComponentOwner { AppInitializer.getInstance(this).apply { initializeComponent(CrashInitializer::class.java) initializeComponent(TracingInitializer::class.java) - initializeComponent(EmojiInitializer::class.java) } logApplicationInfo() } diff --git a/app/src/main/kotlin/io/element/android/x/initializer/EmojiInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/EmojiInitializer.kt deleted file mode 100644 index dd1e7455c6..0000000000 --- a/app/src/main/kotlin/io/element/android/x/initializer/EmojiInitializer.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 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.initializer - -import androidx.startup.Initializer -import com.vanniktech.emoji.EmojiManager -import com.vanniktech.emoji.google.GoogleEmojiProvider - -class EmojiInitializer : Initializer { - override fun create(context: android.content.Context) { - EmojiManager.install(GoogleEmojiProvider()) - } - - override fun dependencies(): MutableList>> = mutableListOf() -} diff --git a/features/messages/impl/build.gradle.kts b/features/messages/impl/build.gradle.kts index 948bac4c57..bd8cbc3a11 100644 --- a/features/messages/impl/build.gradle.kts +++ b/features/messages/impl/build.gradle.kts @@ -60,7 +60,7 @@ dependencies { implementation(libs.accompanist.systemui) implementation(libs.vanniktech.blurhash) implementation(libs.telephoto.zoomableimage) - implementation(libs.vanniktech.emoji) + implementation(libs.matrix.emojibase.bindings) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 7da67d468c..6541d8abc8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -16,7 +16,9 @@ package io.element.android.features.messages.impl +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.emojibasebindings.EmojibaseDatasource import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.timeline.aTimelineItemList @@ -67,6 +69,7 @@ fun aMessagesState() = MessagesState( actionListState = anActionListState(), customReactionState = CustomReactionState( selectedEventId = null, + emojiProvider = Async.Uninitialized, eventSink = {}, ), reactionSummaryState = ReactionSummaryState( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 34ac14af57..9190646ffc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -135,7 +135,8 @@ fun MessagesView( } fun onMoreReactionsClicked(event: TimelineItem.Event) { - state.customReactionState.eventSink(CustomReactionEvents.UpdateSelectedEvent(event.eventId)) + if (event.eventId == null) return + state.customReactionState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event.eventId)) } Scaffold( @@ -187,7 +188,8 @@ fun MessagesView( state = state.actionListState, onActionSelected = ::onActionSelected, onCustomReactionClicked = { event -> - state.customReactionState.eventSink(CustomReactionEvents.UpdateSelectedEvent(event.eventId)) + if (event.eventId == null) return@ActionListView + state.customReactionState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event.eventId)) }, onEmojiReactionClicked = ::onEmojiReactionClicked, ) @@ -197,7 +199,7 @@ fun MessagesView( onEmojiSelected = { emoji -> state.customReactionState.selectedEventId?.let { eventId -> state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId)) - state.customReactionState.eventSink(CustomReactionEvents.UpdateSelectedEvent(null)) + state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) } } ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt index 70c2a7dc10..3bfe42cecf 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt @@ -22,8 +22,7 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import com.vanniktech.emoji.Emoji -import io.element.android.features.messages.impl.timeline.components.EmojiPicker +import io.element.android.emojibasebindings.Emoji import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet import io.element.android.libraries.designsystem.theme.components.hide @@ -38,18 +37,19 @@ fun CustomReactionBottomSheet( val coroutineScope = rememberCoroutineScope() fun onDismiss() { - state.eventSink(CustomReactionEvents.UpdateSelectedEvent(null)) + state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) } fun onEmojiSelectedDismiss(emoji: Emoji) { sheetState.hide(coroutineScope) { - state.eventSink(CustomReactionEvents.UpdateSelectedEvent(null)) + state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) onEmojiSelected(emoji) } } - val isVisible = state.selectedEventId != null - if (isVisible) { + val emojiProvider = state.emojiProvider.dataOrNull() + val selectedEventId = state.selectedEventId + if (emojiProvider != null && selectedEventId != null) { ModalBottomSheet( onDismissRequest = ::onDismiss, sheetState = sheetState, @@ -57,6 +57,7 @@ fun CustomReactionBottomSheet( ) { EmojiPicker( onEmojiSelected = ::onEmojiSelectedDismiss, + emojiProvider = emojiProvider, modifier = Modifier.fillMaxSize() ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt index b7c210553e..1126474b8a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt @@ -19,5 +19,6 @@ package io.element.android.features.messages.impl.timeline.components.customreac import io.element.android.libraries.matrix.api.core.EventId sealed interface CustomReactionEvents { - data class UpdateSelectedEvent(val eventId: EventId?) : CustomReactionEvents + data class ShowCustomReactionSheet(val eventId: EventId) : CustomReactionEvents + object DismissCustomReactionSheet : CustomReactionEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index 0a23d42085..a000a780ae 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -20,9 +20,15 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext +import io.element.android.emojibasebindings.EmojibaseDatasource +import io.element.android.emojibasebindings.EmojibaseStore +import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.core.EventId +import kotlinx.coroutines.launch import javax.inject.Inject class CustomReactionPresenter @Inject constructor() : Presenter { @@ -30,13 +36,31 @@ class CustomReactionPresenter @Inject constructor() : Presenter(null) } - - fun handleEvents(event: CustomReactionEvents) { - when (event) { - is CustomReactionEvents.UpdateSelectedEvent -> selectedEventId = event.eventId + var emojiState: Async by remember { + mutableStateOf(Async.Uninitialized) + } + val localCoroutineScope = rememberCoroutineScope() + val context = LocalContext.current + fun handleShowCustomReactionSheet(eventId: EventId) { + selectedEventId = eventId + emojiState = Async.Loading() + localCoroutineScope.launch { + emojiState = Async.Success(EmojibaseDatasource().load(context)) } } - return CustomReactionState(selectedEventId = selectedEventId, eventSink = ::handleEvents) + fun handleDismissCustomReactionSheet() { + selectedEventId = null + emojiState = Async.Uninitialized + } + + fun handleEvents(event: CustomReactionEvents) { + when (event) { + is CustomReactionEvents.ShowCustomReactionSheet -> handleShowCustomReactionSheet(event.eventId) + is CustomReactionEvents.DismissCustomReactionSheet -> handleDismissCustomReactionSheet() + } + } + + return CustomReactionState(selectedEventId = selectedEventId, emojiProvider = emojiState, eventSink = ::handleEvents) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt index 6c0c7f3599..9641f2d31a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt @@ -16,9 +16,12 @@ package io.element.android.features.messages.impl.timeline.components.customreaction +import io.element.android.emojibasebindings.EmojibaseStore +import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.EventId data class CustomReactionState( val selectedEventId: EventId?, + val emojiProvider: Async, val eventSink: (CustomReactionEvents) -> Unit, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/EmojiPicker.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt similarity index 83% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/EmojiPicker.kt rename to features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt index 6e121685f2..1fa238d5ba 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/EmojiPicker.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.messages.impl.timeline.components +package io.element.android.features.messages.impl.timeline.components.customreaction import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable @@ -39,10 +39,14 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.vanniktech.emoji.Emoji -import com.vanniktech.emoji.google.GoogleEmojiProvider +import io.element.android.emojibasebindings.Emoji +import io.element.android.emojibasebindings.EmojibaseCategory +import io.element.android.emojibasebindings.EmojibaseDatasource +import io.element.android.emojibasebindings.EmojibaseStore import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.Icon @@ -54,23 +58,22 @@ import kotlinx.coroutines.launch @Composable fun EmojiPicker( onEmojiSelected: (Emoji) -> Unit, + emojiProvider: EmojibaseStore, modifier: Modifier = Modifier, ) { val coroutineScope = rememberCoroutineScope() - - val emojiProvider = remember { GoogleEmojiProvider() } val categories = remember { emojiProvider.categories } val pagerState = rememberPagerState() Column(modifier) { TabRow( selectedTabIndex = pagerState.currentPage, ) { - categories.forEachIndexed { index, category -> + EmojibaseCategory.values().forEachIndexed { index, category -> Tab( text = { Icon( - resourceId = emojiProvider.getIcon(category), - contentDescription = category.categoryNames["en"] + imageVector = category.icon, + contentDescription = stringResource(id = category.title) ) }, selected = pagerState.currentPage == index, @@ -82,18 +85,19 @@ fun EmojiPicker( } HorizontalPager( - pageCount = categories.size, + pageCount = EmojibaseCategory.values().size, state = pagerState, modifier = Modifier.fillMaxWidth(), ) { index -> - val category = categories[index] + val category = EmojibaseCategory.values()[index] + val emojis = categories[category] ?: listOf() LazyVerticalGrid( modifier = Modifier.fillMaxSize(), columns = GridCells.Adaptive(minSize = 40.dp), contentPadding = PaddingValues(vertical = 10.dp, horizontal = 16.dp), horizontalArrangement = Arrangement.SpaceEvenly, ) { - items(category.emojis, key = { it.unicode }) { item -> + items(emojis, key = { it.unicode }) { item -> Box( modifier = Modifier .size(40.dp) @@ -132,6 +136,7 @@ internal fun EmojiPickerDarkPreview() { private fun ContentToPreview() { EmojiPicker( onEmojiSelected = {}, + emojiProvider = EmojibaseDatasource().load(LocalContext.current), modifier = Modifier.fillMaxWidth() ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt new file mode 100644 index 0000000000..c6e54953e6 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 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.features.messages.impl.timeline.components.customreaction + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.EmojiEvents +import androidx.compose.material.icons.outlined.EmojiFlags +import androidx.compose.material.icons.outlined.EmojiFoodBeverage +import androidx.compose.material.icons.outlined.EmojiNature +import androidx.compose.material.icons.outlined.EmojiObjects +import androidx.compose.material.icons.outlined.EmojiPeople +import androidx.compose.material.icons.outlined.EmojiSymbols +import androidx.compose.material.icons.outlined.EmojiTransportation +import androidx.compose.ui.graphics.vector.ImageVector +import io.element.android.emojibasebindings.EmojibaseCategory +import io.element.android.libraries.ui.strings.R + +@get:StringRes +val EmojibaseCategory.title: Int get() = + when(this){ + EmojibaseCategory.People -> R.string.emoji_picker_category_people + EmojibaseCategory.Nature -> R.string.emoji_picker_category_nature + EmojibaseCategory.Foods -> R.string.emoji_picker_category_foods + EmojibaseCategory.Activity -> R.string.emoji_picker_category_activity + EmojibaseCategory.Places -> R.string.emoji_picker_category_places + EmojibaseCategory.Objects -> R.string.emoji_picker_category_objects + EmojibaseCategory.Symbols -> R.string.emoji_picker_category_symbols + EmojibaseCategory.Flags -> R.string.emoji_picker_category_flags + } + +val EmojibaseCategory.icon: ImageVector + get() = + when(this){ + EmojibaseCategory.People -> Icons.Outlined.EmojiPeople + EmojibaseCategory.Nature -> Icons.Outlined.EmojiNature + EmojibaseCategory.Foods -> Icons.Outlined.EmojiFoodBeverage + EmojibaseCategory.Activity -> Icons.Outlined.EmojiEvents + EmojibaseCategory.Places -> Icons.Outlined.EmojiTransportation + EmojibaseCategory.Objects -> Icons.Outlined.EmojiObjects + EmojibaseCategory.Symbols -> Icons.Outlined.EmojiSymbols + EmojibaseCategory.Flags -> Icons.Outlined.EmojiFlags + } + diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt index 1c40483ffe..0ea4ab79c8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt @@ -38,10 +38,10 @@ class CustomReactionPresenterTests { val initialState = awaitItem() assertThat(initialState.selectedEventId).isNull() - initialState.eventSink(CustomReactionEvents.UpdateSelectedEvent(AN_EVENT_ID)) + initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(AN_EVENT_ID)) assertThat(awaitItem().selectedEventId).isEqualTo(AN_EVENT_ID) - initialState.eventSink(CustomReactionEvents.UpdateSelectedEvent(null)) + initialState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) assertThat(awaitItem().selectedEventId).isNull() } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7f3540a2e8..c4f5c8ae4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -154,7 +154,6 @@ sqlite = "androidx.sqlite:sqlite:2.3.1" unifiedpush = "com.github.UnifiedPush:android-connector:2.1.1" otaliastudios_transcoder = "com.otaliastudios:transcoder:0.10.5" vanniktech_blurhash = "com.vanniktech:blurhash:0.1.0" -vanniktech_emoji = "com.vanniktech:emoji-google:0.16.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.0" maplibre = "org.maplibre.gl:android-sdk:10.2.0" @@ -166,6 +165,9 @@ posthog = "com.posthog.android:posthog:2.0.3" sentry = "io.sentry:sentry-android:6.28.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8" +# Emojibase +matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.0.5" + # Di inject = "javax.inject:javax.inject:1" dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } @@ -177,7 +179,6 @@ anvil_compiler_utils = { module = "com.squareup.anvil:compiler-utils", version.r google_autoservice = { module = "com.google.auto.service:auto-service", version.ref = "autoservice" } google_autoservice_annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoservice" } - # Miscellaneous # Add unused dependency to androidx.compose.compiler:compiler to let Renovate create PR to change the # value of `composecompiler` (which is used to set composeOptions.kotlinCompilerExtensionVersion. From a3e9f666140431c8dc7069de5a55cba278598974 Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 28 Aug 2023 18:11:17 +0100 Subject: [PATCH 002/127] lint --- .../features/messages/impl/MessagesStateProvider.kt | 2 -- .../customreaction/CustomReactionBottomSheet.kt | 2 +- .../components/customreaction/CustomReactionEvents.kt | 2 +- .../customreaction/CustomReactionPresenter.kt | 11 +++++++---- .../timeline/components/customreaction/EmojiPicker.kt | 9 ++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 3423830f08..ecc9b1746a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -16,9 +16,7 @@ package io.element.android.features.messages.impl -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.emojibasebindings.EmojibaseDatasource import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.timeline.aTimelineItemList diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt index bb02c36e31..05c2956316 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt @@ -57,9 +57,9 @@ fun CustomReactionBottomSheet( ) { EmojiPicker( onEmojiSelected = ::onEmojiSelectedDismiss, - modifier = Modifier.fillMaxSize(), emojiProvider = emojiProvider, selectedEmojis = state.selectedEmoji, + modifier = Modifier.fillMaxSize(), ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt index f9da2986d9..2458686a83 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionEvents.kt @@ -19,6 +19,6 @@ package io.element.android.features.messages.impl.timeline.components.customreac import io.element.android.features.messages.impl.timeline.model.TimelineItem sealed interface CustomReactionEvents { - data class ShowCustomReactionSheet(val event: TimelineItem.Event?) : CustomReactionEvents + data class ShowCustomReactionSheet(val event: TimelineItem.Event) : CustomReactionEvents object DismissCustomReactionSheet : CustomReactionEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index 0aa1d06059..4ab94f1656 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -27,10 +27,8 @@ import io.element.android.emojibasebindings.EmojibaseDatasource import io.element.android.emojibasebindings.EmojibaseStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.core.EventId import kotlinx.coroutines.launch import io.element.android.features.messages.impl.timeline.model.TimelineItem -import io.element.android.libraries.architecture.Presenter import kotlinx.collections.immutable.toImmutableSet import javax.inject.Inject @@ -59,11 +57,16 @@ class CustomReactionPresenter @Inject constructor() : Presenter handleShowCustomReactionSheet(event) + is CustomReactionEvents.ShowCustomReactionSheet -> handleShowCustomReactionSheet(event.event) is CustomReactionEvents.DismissCustomReactionSheet -> handleDismissCustomReactionSheet() } } val selectedEmoji = selectedEvent?.reactionsState?.reactions?.mapNotNull { if(it.isHighlighted) it.key else null }.orEmpty().toImmutableSet() - return CustomReactionState(selectedEventId = selectedEvent?.eventId, emojiProvider = emojiState, selectedEmoji = selectedEmoji, eventSink = ::handleEvents) + return CustomReactionState( + selectedEventId = selectedEvent?.eventId, + emojiProvider = emojiState, + selectedEmoji = selectedEmoji, + eventSink = ::handleEvents + ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt index c2259bdf09..edbd6aabc6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt @@ -63,13 +63,13 @@ import kotlinx.coroutines.launch @Composable fun EmojiPicker( onEmojiSelected: (Emoji) -> Unit, - modifier: Modifier = Modifier, emojiProvider: EmojibaseStore, selectedEmojis: ImmutableSet, + modifier: Modifier = Modifier, ) { val coroutineScope = rememberCoroutineScope() val categories = remember { emojiProvider.categories } - val pagerState = rememberPagerState(pageCount = { emojiProvider.categories.size }) + val pagerState = rememberPagerState(pageCount = { EmojibaseCategory.values().size }) Column(modifier) { TabRow( selectedTabIndex = pagerState.currentPage, @@ -91,7 +91,6 @@ fun EmojiPicker( } HorizontalPager( - pageCount = EmojibaseCategory.values().size, state = pagerState, modifier = Modifier.fillMaxWidth(), ) { index -> @@ -150,8 +149,8 @@ internal fun EmojiPickerDarkPreview() { private fun ContentToPreview() { EmojiPicker( onEmojiSelected = {}, - modifier = Modifier.fillMaxWidth(), emojiProvider = EmojibaseDatasource().load(LocalContext.current), - selectedEmojis = persistentSetOf("😀", "😄", "😃") + selectedEmojis = persistentSetOf("😀", "😄", "😃"), + modifier = Modifier.fillMaxWidth(), ) } From 6a9152160496a135c87dbe1b75c5ed100518f55a Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 28 Aug 2023 18:20:48 +0100 Subject: [PATCH 003/127] Use CommonStrings --- .../customreaction/EmojibaseExtensions.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt index c6e54953e6..fb111cce97 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseExtensions.kt @@ -28,19 +28,19 @@ import androidx.compose.material.icons.outlined.EmojiSymbols import androidx.compose.material.icons.outlined.EmojiTransportation import androidx.compose.ui.graphics.vector.ImageVector import io.element.android.emojibasebindings.EmojibaseCategory -import io.element.android.libraries.ui.strings.R +import io.element.android.libraries.ui.strings.CommonStrings @get:StringRes val EmojibaseCategory.title: Int get() = when(this){ - EmojibaseCategory.People -> R.string.emoji_picker_category_people - EmojibaseCategory.Nature -> R.string.emoji_picker_category_nature - EmojibaseCategory.Foods -> R.string.emoji_picker_category_foods - EmojibaseCategory.Activity -> R.string.emoji_picker_category_activity - EmojibaseCategory.Places -> R.string.emoji_picker_category_places - EmojibaseCategory.Objects -> R.string.emoji_picker_category_objects - EmojibaseCategory.Symbols -> R.string.emoji_picker_category_symbols - EmojibaseCategory.Flags -> R.string.emoji_picker_category_flags + EmojibaseCategory.People -> CommonStrings.emoji_picker_category_people + EmojibaseCategory.Nature -> CommonStrings.emoji_picker_category_nature + EmojibaseCategory.Foods -> CommonStrings.emoji_picker_category_foods + EmojibaseCategory.Activity -> CommonStrings.emoji_picker_category_activity + EmojibaseCategory.Places -> CommonStrings.emoji_picker_category_places + EmojibaseCategory.Objects -> CommonStrings.emoji_picker_category_objects + EmojibaseCategory.Symbols -> CommonStrings.emoji_picker_category_symbols + EmojibaseCategory.Flags -> CommonStrings.emoji_picker_category_flags } val EmojibaseCategory.icon: ImageVector From 1d57d4500c620919eb0ec97d12aaa20636cd66eb Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 28 Aug 2023 20:15:00 +0100 Subject: [PATCH 004/127] Fix test compilation. --- .../components/customreaction/CustomReactionPresenterTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt index 8246520d7c..9918a67296 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt @@ -57,7 +57,7 @@ class CustomReactionPresenterTests { assertThat(initialState.selectedEventId).isNull() val reactions = aTimelineItemReactions(count = 1, isHighlighted = true) val key = reactions.reactions.first().key - initialState.eventSink(CustomReactionEvents.UpdateSelectedEvent(aTimelineItemEvent(eventId = AN_EVENT_ID, timelineItemReactions = reactions))) + initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(aTimelineItemEvent(eventId = AN_EVENT_ID, timelineItemReactions = reactions))) val stateWithSelectedEmojis = awaitItem() assertThat(stateWithSelectedEmojis.selectedEventId).isEqualTo(AN_EVENT_ID) assertThat(stateWithSelectedEmojis.selectedEmoji).contains(key) From bbc7974442befcd162345d1d906627edfb1836e5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:04:36 +0200 Subject: [PATCH 005/127] Add documentation to explain how to install the application from a Github release. --- docs/install_from_github_release.md | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 docs/install_from_github_release.md diff --git a/docs/install_from_github_release.md b/docs/install_from_github_release.md new file mode 100644 index 0000000000..98fd6e4d30 --- /dev/null +++ b/docs/install_from_github_release.md @@ -0,0 +1,55 @@ +# Installing Element X Android from a Github Release. + +This document explain how to install Element X Android from a Github Release. + + + +* [Requirements](#requirements) +* [Steps](#steps) +* [I already have the application on my phone](#i-already-have-the-application-on-my-phone) + + + +## Requirements + +The Github release will contain an Android App Bundle (with `aab` extension) file, and not APKs like on the Element Android project. So there is some steps to perform to generate and signed the APKs from the App Bundle. The generated APKs will then be selected depending on your phone configuration to be installed on a device (emulator or real device). + +The easiest way to do that is to use the debug signature that is shared between the developers and stored in the project. So we recommend to checkout the project first. Android Studio is not required, you can use the command line. + +You will also need to install [bundletool](https://developer.android.com/studio/command-line/bundletool). On MacOS, you can run the following command: + +```bash +brew install bundletool +``` + +## Steps + +1. Open the GitHub release that you want to install from https://github.com/vector-im/element-x-android/releases; +2. Download the asset `app-release-signed.aab` +3. Navigate to the folder where you cloned the project and run the following command: +```bash +bundletool build-apks --bundle= --output=./tmp/elementx.apks \ + --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ + --overwrite +``` +For instance: +```bash +bundletool build-apks --bundle=./tmp/Element/0.1.5/app-release-signed.aab --output=./tmp/elementx.apks \ + --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ + --overwrite +``` +4. Run an Android emulator, or connect a real device to your computer. +5. Install the APKs on the device: +```bash +bundletool install-apks --apks=./tmp/elementx.apks +``` + +That's it, the application should be installed on your device, you can start it from the launcher icon. + +## I already have the application on my phone + +If the application was already installed on your phone, there are several cases: + +- it was installed from the PlayStore, you will have to uninstall it first, because the signature will not match. +- it was installed from a previous GitHub release, this is like an application upgrade, so no need to uninstall the existing app. +- it was installed from a more recent GitHub release, you will have to uninstall it first. From f44fa4190f7b9eb0c0b242118a6e8004bde41a89 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:06:17 +0200 Subject: [PATCH 006/127] Release script: do not bundle the minimal app when checking if the project compiles locally. --- tools/release/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release/release.sh b/tools/release/release.sh index 20005d2816..43d129fa26 100755 --- a/tools/release/release.sh +++ b/tools/release/release.sh @@ -143,7 +143,7 @@ git commit -a -m "Setting version for the release ${version}" printf "\n================================================================================\n" printf "Building the bundle locally first...\n" -./gradlew clean bundleRelease +./gradlew clean app:bundleRelease printf "\n================================================================================\n" printf "Running towncrier...\n" From b581cc932814168dbdbd9e18021e6a9a8b6da890 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:11:35 +0200 Subject: [PATCH 007/127] Release script: split APKs generation and APK deployment into 2 separate steps. --- tools/release/release.sh | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/release/release.sh b/tools/release/release.sh index 43d129fa26..72d75735fd 100755 --- a/tools/release/release.sh +++ b/tools/release/release.sh @@ -269,19 +269,26 @@ printf "\n====================================================================== printf "The file ${signedBundlePath} has been signed and can be uploaded to the PlayStore!\n" printf "\n================================================================================\n" -read -p "Do you want to install the application to your device? Make sure there is a connected device first. (yes/no) default to yes " doDeploy -doDeploy=${doDeploy:-yes} +read -p "Do you want to build the APKs from the app bundle? You need to do this step if you want to install the application to your device. (yes/no) default to yes " doBuildApks +doBuildApks=${doBuildApks:-yes} -if [ ${doDeploy} == "yes" ]; then +if [ ${doBuildApks} == "yes" ]; then printf "Building apks...\n" bundletool build-apks --bundle=${signedBundlePath} --output=${targetPath}/elementx.apks \ --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ --overwrite - printf "Installing apk for your device...\n" - bundletool install-apks --apks=${targetPath}/elementx.apks - read -p "Please run the application on your phone to check that the upgrade went well (no init sync, etc.). Press enter when it's done." + + read -p "Do you want to install the application to your device? Make sure there is one (and only one!) connected device first. (yes/no) default to yes " doDeploy + doDeploy=${doDeploy:-yes} + if [ ${doDeploy} == "yes" ]; then + printf "Installing apk for your device...\n" + bundletool install-apks --apks=${targetPath}/elementx.apks + read -p "Please run the application on your phone to check that the upgrade went well. Press enter when it's done." + else + printf "APK will not be deployed!\n" + fi else - printf "Apk will not be deployed!\n" + printf "APKs will not be generated!\n" fi printf "\n================================================================================\n" From 34a85c49569b4423978807211c86c8bd4b2b1cd5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:14:33 +0200 Subject: [PATCH 008/127] Release script: Add link to documentation to install the application from the GitHub release. --- tools/release/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release/release.sh b/tools/release/release.sh index 72d75735fd..6d812b42b7 100755 --- a/tools/release/release.sh +++ b/tools/release/release.sh @@ -303,7 +303,7 @@ read -p ". Press enter when it's done. " printf "\n================================================================================\n" printf "Message for the Android internal room:\n\n" -message="@room Element X Android ${version} is ready to be tested. You can get it from https://github.com/vector-im/element-x-android/releases/tag/v${version}. Please report any feedback here. Thanks!" +message="@room Element X Android ${version} is ready to be tested. You can get it from https://github.com/vector-im/element-x-android/releases/tag/v${version}. Installation instructions can be found [here](https://github.com/vector-im/element-x-android/blob/develop/docs/install_from_github_release.md). Please report any feedback. Thanks!" printf "${message}\n\n" if [[ -z "${elementBotToken}" ]]; then From 614e8fcff9cbc3e084a103f4c8549881b21b4d2e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:19:32 +0200 Subject: [PATCH 009/127] Release script: improve prompt messages. --- tools/release/release.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/release/release.sh b/tools/release/release.sh index 6d812b42b7..a5701ea5e1 100755 --- a/tools/release/release.sh +++ b/tools/release/release.sh @@ -150,7 +150,7 @@ printf "Running towncrier...\n" yes | towncrier build --version "v${version}" printf "\n================================================================================\n" -read -p "Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things. Do not commit your change. Press enter when it's done." +read -p "Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things. Do not commit your change. Press enter to continue. " # Get the changes to use it to create the GitHub release changelogUrlEncoded=`git diff CHANGES.md | grep ^+ | tail -n +2 | cut -c2- | jq -sRr @uri | sed s/\(/%28/g | sed s/\)/%29/g` @@ -168,7 +168,7 @@ fastlaneFile="4${versionMajor2Digits}${versionMinor2Digits}${versionPatch2Digits fastlanePathFile="./fastlane/metadata/android/en-US/changelogs/${fastlaneFile}" printf "Main changes in this version: TODO.\nFull changelog: https://github.com/vector-im/element-x-android/releases" > ${fastlanePathFile} -read -p "I have created the file ${fastlanePathFile}, please edit it and press enter when it's done." +read -p "I have created the file ${fastlanePathFile}, please edit it and press enter to continue. " git add ${fastlanePathFile} git commit -a -m "Adding fastlane file for version ${version}" @@ -200,7 +200,7 @@ sed "s/private const val versionPatch = .*/private const val versionPatch = ${ne rm ${versionsFileBak} printf "\n================================================================================\n" -read -p "I have updated the versions to prepare the next release, please check that the change are correct and press enter so I can commit." +read -p "I have updated the versions to prepare the next release, please check that the change are correct and press enter so I can commit. " printf "Committing...\n" git commit -a -m 'version++' @@ -263,7 +263,7 @@ printf "Version name: " bundletool dump manifest --bundle=${signedBundlePath} --xpath=/manifest/@android:versionName printf "\n" -read -p "Does it look correct? Press enter when it's done." +read -p "Does it look correct? Press enter to continue. " printf "\n================================================================================\n" printf "The file ${signedBundlePath} has been signed and can be uploaded to the PlayStore!\n" @@ -283,7 +283,7 @@ if [ ${doBuildApks} == "yes" ]; then if [ ${doDeploy} == "yes" ]; then printf "Installing apk for your device...\n" bundletool install-apks --apks=${targetPath}/elementx.apks - read -p "Please run the application on your phone to check that the upgrade went well. Press enter when it's done." + read -p "Please run the application on your phone to check that the upgrade went well. Press enter to continue. " else printf "APK will not be deployed!\n" fi @@ -299,7 +299,7 @@ printf "Then\n" printf " - copy paste the section of the file CHANGES.md for this release (if not there yet)\n" printf " - click on the 'Generate releases notes' button\n" printf " - Add the file ${signedBundlePath} to the GitHub release.\n" -read -p ". Press enter when it's done. " +read -p ". Press enter to continue. " printf "\n================================================================================\n" printf "Message for the Android internal room:\n\n" @@ -307,7 +307,7 @@ message="@room Element X Android ${version} is ready to be tested. You can get i printf "${message}\n\n" if [[ -z "${elementBotToken}" ]]; then - read -p "ELEMENT_BOT_MATRIX_TOKEN is not defined in the environment. Cannot send the message for you. Please send it manually, and press enter when it's done " + read -p "ELEMENT_BOT_MATRIX_TOKEN is not defined in the environment. Cannot send the message for you. Please send it manually, and press enter to continue. " else read -p "Send this message to the room (yes/no) default to yes? " doSend doSend=${doSend:-yes} From eb041277a9ef0dc8ae9ef30a5065188fa0b890ee Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Aug 2023 11:22:14 +0200 Subject: [PATCH 010/127] Grammar. --- docs/install_from_github_release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install_from_github_release.md b/docs/install_from_github_release.md index 98fd6e4d30..eec5586d82 100644 --- a/docs/install_from_github_release.md +++ b/docs/install_from_github_release.md @@ -1,6 +1,6 @@ # Installing Element X Android from a Github Release. -This document explain how to install Element X Android from a Github Release. +This document explains how to install Element X Android from a Github Release. From 7129a526b073fae55a061ba9102df5c4dd0efe84 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 30 Aug 2023 12:48:33 +0200 Subject: [PATCH 011/127] Iterate and reformulate after PR review. --- docs/install_from_github_release.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/install_from_github_release.md b/docs/install_from_github_release.md index eec5586d82..57363a617c 100644 --- a/docs/install_from_github_release.md +++ b/docs/install_from_github_release.md @@ -1,4 +1,4 @@ -# Installing Element X Android from a Github Release. +# Installing Element X Android from a Github Release This document explains how to install Element X Android from a Github Release. @@ -12,9 +12,18 @@ This document explains how to install Element X Android from a Github Release. ## Requirements -The Github release will contain an Android App Bundle (with `aab` extension) file, and not APKs like on the Element Android project. So there is some steps to perform to generate and signed the APKs from the App Bundle. The generated APKs will then be selected depending on your phone configuration to be installed on a device (emulator or real device). +The Github release will contain an Android App Bundle (with `aab` extension) file, unlike in the Element Android project where releases directly provide the APKs. So there are some steps to perform to generate and sign App Bundle APKs. An APK suitable for the targeted device will then be generated. -The easiest way to do that is to use the debug signature that is shared between the developers and stored in the project. So we recommend to checkout the project first. Android Studio is not required, you can use the command line. +The easiest way to do that is to use the debug signature that is shared between the developers and stored in the Element X Android project. So we recommend to clone the project first, to be able to use the debug signature it contains. But note that you can use any other signature. You don't need to install Android Studio, you will only need a shell terminal. + +You can clone the project by running: +```bash +git clone git@github.com:vector-im/element-x-android.git +``` +or +```bash +git clone https://github.com/vector-im/element-x-android.gi +``` You will also need to install [bundletool](https://developer.android.com/studio/command-line/bundletool). On MacOS, you can run the following command: @@ -24,7 +33,7 @@ brew install bundletool ## Steps -1. Open the GitHub release that you want to install from https://github.com/vector-im/element-x-android/releases; +1. Open the GitHub release that you want to install from https://github.com/vector-im/element-x-android/releases 2. Download the asset `app-release-signed.aab` 3. Navigate to the folder where you cloned the project and run the following command: ```bash @@ -38,7 +47,7 @@ bundletool build-apks --bundle=./tmp/Element/0.1.5/app-release-signed.aab --outp --ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \ --overwrite ``` -4. Run an Android emulator, or connect a real device to your computer. +4. Run an Android emulator, or connect a real device to your computer 5. Install the APKs on the device: ```bash bundletool install-apks --apks=./tmp/elementx.apks @@ -50,6 +59,6 @@ That's it, the application should be installed on your device, you can start it If the application was already installed on your phone, there are several cases: -- it was installed from the PlayStore, you will have to uninstall it first, because the signature will not match. +- it was installed from the PlayStore, you will have to uninstall it first because the signature will not match. - it was installed from a previous GitHub release, this is like an application upgrade, so no need to uninstall the existing app. - it was installed from a more recent GitHub release, you will have to uninstall it first. From a5d42f61faca024a206ffddeb8fc36e81b50423a Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 30 Aug 2023 12:47:31 +0100 Subject: [PATCH 012/127] Fix tests and improve structure of CustomReactionState - Fix tests - Improve structure of CustomReactionState --- .../io/element/android/x/di/AppModule.kt | 8 +++++ .../messages/impl/MessagesStateProvider.kt | 3 +- .../features/messages/impl/MessagesView.kt | 4 +-- .../CustomReactionBottomSheet.kt | 14 ++++---- .../customreaction/CustomReactionPresenter.kt | 34 +++++++++++-------- .../customreaction/CustomReactionState.kt | 20 +++++++++-- .../DefaultEmojibaseProvider.kt | 27 +++++++++++++++ .../components/customreaction/EmojiPicker.kt | 6 ++-- .../customreaction/EmojibaseProvider.kt | 23 +++++++++++++ .../messages/MessagesPresenterTest.kt | 3 +- .../CustomReactionPresenterTests.kt | 33 ++++++++++++------ .../customreaction/FakeEmojibaseProvider.kt | 26 ++++++++++++++ 12 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt create mode 100644 features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt diff --git a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt index a1d0b50522..f8ab5532b0 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt @@ -23,6 +23,8 @@ import androidx.preference.PreferenceManager import com.squareup.anvil.annotations.ContributesTo import dagger.Module import dagger.Provides +import io.element.android.features.messages.impl.timeline.components.customreaction.DefaultEmojibaseProvider +import io.element.android.features.messages.impl.timeline.components.customreaction.EmojibaseProvider import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType @@ -105,4 +107,10 @@ object AppModule { fun provideSnackbarDispatcher(): SnackbarDispatcher { return SnackbarDispatcher() } + + @Provides + @SingleIn(AppScope::class) + fun providesEmojibaseProvider(@ApplicationContext context: Context): EmojibaseProvider { + return DefaultEmojibaseProvider(context) + } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index ecc9b1746a..7eb1a0984e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -67,8 +67,7 @@ fun aMessagesState() = MessagesState( ), actionListState = anActionListState(), customReactionState = CustomReactionState( - selectedEventId = null, - emojiProvider = Async.Uninitialized, + target = CustomReactionState.Target.None, eventSink = {}, selectedEmoji = persistentSetOf(), ), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 5608711171..74dcb610af 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -200,11 +200,9 @@ fun MessagesView( CustomReactionBottomSheet( state = state.customReactionState, - onEmojiSelected = { emoji -> - state.customReactionState.selectedEventId?.let { eventId -> + onEmojiSelected = { eventId, emoji -> state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId)) state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) - } } ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt index 05c2956316..ed78993716 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt @@ -23,33 +23,35 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import io.element.android.emojibasebindings.Emoji +import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet import io.element.android.libraries.designsystem.theme.components.hide +import io.element.android.libraries.matrix.api.core.EventId @OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomReactionBottomSheet( state: CustomReactionState, - onEmojiSelected: (Emoji) -> Unit, + onEmojiSelected: (EventId, Emoji) -> Unit, modifier: Modifier = Modifier, ) { val sheetState = rememberModalBottomSheetState() val coroutineScope = rememberCoroutineScope() + val target = state.target as? CustomReactionState.Target.Success fun onDismiss() { state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) } fun onEmojiSelectedDismiss(emoji: Emoji) { + if (target?.event?.eventId == null) return sheetState.hide(coroutineScope) { state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) - onEmojiSelected(emoji) + onEmojiSelected(target.event.eventId, emoji) } } - val emojiProvider = state.emojiProvider.dataOrNull() - val selectedEventId = state.selectedEventId - if (emojiProvider != null && selectedEventId != null) { + if (target?.emojibaseStore != null && target.event.eventId != null) { ModalBottomSheet( onDismissRequest = ::onDismiss, sheetState = sheetState, @@ -57,7 +59,7 @@ fun CustomReactionBottomSheet( ) { EmojiPicker( onEmojiSelected = ::onEmojiSelectedDismiss, - emojiProvider = emojiProvider, + emojibaseStore = target.emojibaseStore, selectedEmojis = state.selectedEmoji, modifier = Modifier.fillMaxSize(), ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index 4ab94f1656..8a331438a5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -17,42 +17,46 @@ package io.element.android.features.messages.impl.timeline.components.customreaction import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue -import androidx.compose.ui.platform.LocalContext -import io.element.android.emojibasebindings.EmojibaseDatasource import io.element.android.emojibasebindings.EmojibaseStore +import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.launch import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.canReact import kotlinx.collections.immutable.toImmutableSet import javax.inject.Inject -class CustomReactionPresenter @Inject constructor() : Presenter { +class CustomReactionPresenter @Inject constructor( + private val emojibaseProvider: EmojibaseProvider +) : Presenter { @Composable override fun present(): CustomReactionState { - var selectedEvent by remember { mutableStateOf(null) } - var emojiState: Async by remember { - mutableStateOf(Async.Uninitialized) + val target: MutableState = remember { + mutableStateOf(CustomReactionState.Target.None) } + val localCoroutineScope = rememberCoroutineScope() - val context = LocalContext.current fun handleShowCustomReactionSheet(event: TimelineItem.Event) { - selectedEvent = event - emojiState = Async.Loading() + target.value = CustomReactionState.Target.Loading(event) localCoroutineScope.launch { - emojiState = Async.Success(EmojibaseDatasource().load(context)) + target.value = CustomReactionState.Target.Success( + event = event, + emojibaseStore = emojibaseProvider.loadEmojibase() + ) } } fun handleDismissCustomReactionSheet() { - selectedEvent = null - emojiState = Async.Uninitialized + target.value = CustomReactionState.Target.None } fun handleEvents(event: CustomReactionEvents) { @@ -61,10 +65,10 @@ class CustomReactionPresenter @Inject constructor() : Presenter handleDismissCustomReactionSheet() } } - val selectedEmoji = selectedEvent?.reactionsState?.reactions?.mapNotNull { if(it.isHighlighted) it.key else null }.orEmpty().toImmutableSet() + val event = (target.value as? CustomReactionState.Target.Success)?.event + val selectedEmoji = event?.reactionsState?.reactions?.mapNotNull { if(it.isHighlighted) it.key else null }.orEmpty().toImmutableSet() return CustomReactionState( - selectedEventId = selectedEvent?.eventId, - emojiProvider = emojiState, + target = target.value, selectedEmoji = selectedEmoji, eventSink = ::handleEvents ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt index 09d5392d32..400c34d6fa 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt @@ -17,13 +17,27 @@ package io.element.android.features.messages.impl.timeline.components.customreaction import io.element.android.emojibasebindings.EmojibaseStore +import io.element.android.features.messages.impl.actionlist.ActionListState +import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction +import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.EventId +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet data class CustomReactionState( - val selectedEventId: EventId?, - val emojiProvider: Async, + val target: Target, val selectedEmoji: ImmutableSet, val eventSink: (CustomReactionEvents) -> Unit, -) +) { + sealed interface Target { + + data object None : Target + data class Loading(val event: TimelineItem.Event) : Target + data class Success( + val event: TimelineItem.Event, + val emojibaseStore: EmojibaseStore, + ) : Target + } +} + diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt new file mode 100644 index 0000000000..2e66ea381e --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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.features.messages.impl.timeline.components.customreaction + +import android.content.Context +import io.element.android.emojibasebindings.EmojibaseDatasource +import io.element.android.emojibasebindings.EmojibaseStore + +class DefaultEmojibaseProvider(val context: Context) :EmojibaseProvider { + override fun loadEmojibase(): EmojibaseStore { + return EmojibaseDatasource().load(context) + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt index edbd6aabc6..1012d61020 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiPicker.kt @@ -63,12 +63,12 @@ import kotlinx.coroutines.launch @Composable fun EmojiPicker( onEmojiSelected: (Emoji) -> Unit, - emojiProvider: EmojibaseStore, + emojibaseStore: EmojibaseStore, selectedEmojis: ImmutableSet, modifier: Modifier = Modifier, ) { val coroutineScope = rememberCoroutineScope() - val categories = remember { emojiProvider.categories } + val categories = remember { emojibaseStore.categories } val pagerState = rememberPagerState(pageCount = { EmojibaseCategory.values().size }) Column(modifier) { TabRow( @@ -149,7 +149,7 @@ internal fun EmojiPickerDarkPreview() { private fun ContentToPreview() { EmojiPicker( onEmojiSelected = {}, - emojiProvider = EmojibaseDatasource().load(LocalContext.current), + emojibaseStore = EmojibaseDatasource().load(LocalContext.current), selectedEmojis = persistentSetOf("😀", "😄", "😃"), modifier = Modifier.fillMaxWidth(), ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt new file mode 100644 index 0000000000..39739538d2 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 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.features.messages.impl.timeline.components.customreaction + +import io.element.android.emojibasebindings.EmojibaseStore + +interface EmojibaseProvider { + fun loadEmojibase(): EmojibaseStore +} diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 2c542e0054..c9f9bec3f8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -41,6 +41,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent import io.element.android.features.messages.media.FakeLocalMediaFactory +import io.element.android.features.messages.timeline.components.customreaction.FakeEmojibaseProvider import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper @@ -584,7 +585,7 @@ class MessagesPresenterTest { ) val buildMeta = aBuildMeta() val actionListPresenter = ActionListPresenter(buildMeta = buildMeta) - val customReactionPresenter = CustomReactionPresenter() + val customReactionPresenter = CustomReactionPresenter(emojibaseProvider = FakeEmojibaseProvider()) val reactionSummaryPresenter = ReactionSummaryPresenter(room = matrixRoom) val retrySendMenuPresenter = RetrySendMenuPresenter(room = matrixRoom) return MessagesPresenter( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt index 9918a67296..bb77605132 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt @@ -24,27 +24,34 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemEvent import io.element.android.features.messages.impl.timeline.aTimelineItemReactions import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter +import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.libraries.matrix.test.AN_EVENT_ID import kotlinx.coroutines.test.runTest import org.junit.Test class CustomReactionPresenterTests { - private val presenter = CustomReactionPresenter() + private val presenter = CustomReactionPresenter(emojibaseProvider = FakeEmojibaseProvider()) @Test fun `present - handle selecting and de-selecting an event`() = runTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitItem() - assertThat(initialState.selectedEventId).isNull() - initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(aTimelineItemEvent(eventId = AN_EVENT_ID))) - assertThat(awaitItem().selectedEventId).isEqualTo(AN_EVENT_ID) + val event = aTimelineItemEvent(eventId = AN_EVENT_ID) + val initialState = awaitItem() + assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None) + + initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) + + assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event)) + + val eventId = (awaitItem().target as? CustomReactionState.Target.Success)?.event?.eventId + assertThat(eventId).isEqualTo(AN_EVENT_ID) initialState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) - assertThat(awaitItem().selectedEventId).isNull() + assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.None) } } @@ -53,13 +60,19 @@ class CustomReactionPresenterTests { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitItem() - assertThat(initialState.selectedEventId).isNull() val reactions = aTimelineItemReactions(count = 1, isHighlighted = true) + val event = aTimelineItemEvent(eventId = AN_EVENT_ID, timelineItemReactions = reactions) + val initialState = awaitItem() + assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None) + val key = reactions.reactions.first().key - initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(aTimelineItemEvent(eventId = AN_EVENT_ID, timelineItemReactions = reactions))) + initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) + + assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event)) + val stateWithSelectedEmojis = awaitItem() - assertThat(stateWithSelectedEmojis.selectedEventId).isEqualTo(AN_EVENT_ID) + val eventId = (stateWithSelectedEmojis.target as? CustomReactionState.Target.Success)?.event?.eventId + assertThat(eventId).isEqualTo(AN_EVENT_ID) assertThat(stateWithSelectedEmojis.selectedEmoji).contains(key) } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt new file mode 100644 index 0000000000..434212030a --- /dev/null +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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.features.messages.timeline.components.customreaction + +import io.element.android.emojibasebindings.EmojibaseStore +import io.element.android.features.messages.impl.timeline.components.customreaction.EmojibaseProvider + +class FakeEmojibaseProvider: EmojibaseProvider { + override fun loadEmojibase(): EmojibaseStore { + return EmojibaseStore(mapOf()) + } +} From 10060c4476695f3c0835a224ef5c7c088d143f17 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 30 Aug 2023 12:55:50 +0100 Subject: [PATCH 013/127] lint --- .../components/customreaction/CustomReactionBottomSheet.kt | 1 - .../components/customreaction/CustomReactionPresenter.kt | 7 ------- .../components/customreaction/CustomReactionState.kt | 5 ----- 3 files changed, 13 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt index ed78993716..3fe739a592 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionBottomSheet.kt @@ -23,7 +23,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import io.element.android.emojibasebindings.Emoji -import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet import io.element.android.libraries.designsystem.theme.components.hide import io.element.android.libraries.matrix.api.core.EventId diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index 8a331438a5..6831ca7dfa 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -18,19 +18,12 @@ package io.element.android.features.messages.impl.timeline.components.customreac import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import io.element.android.emojibasebindings.EmojibaseStore -import io.element.android.features.messages.impl.actionlist.ActionListState -import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.launch import io.element.android.features.messages.impl.timeline.model.TimelineItem -import io.element.android.features.messages.impl.timeline.model.event.canReact import kotlinx.collections.immutable.toImmutableSet import javax.inject.Inject diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt index 400c34d6fa..f6f7d2b0f9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionState.kt @@ -17,12 +17,7 @@ package io.element.android.features.messages.impl.timeline.components.customreaction import io.element.android.emojibasebindings.EmojibaseStore -import io.element.android.features.messages.impl.actionlist.ActionListState -import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.timeline.model.TimelineItem -import io.element.android.libraries.architecture.Async -import io.element.android.libraries.matrix.api.core.EventId -import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet data class CustomReactionState( From 81f7cd5c60426f2e8b4307a10f3eda380957bb31 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 30 Aug 2023 12:38:04 +0000 Subject: [PATCH 014/127] Update screenshots --- ...tomreaction_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png | 3 +++ ...omreaction_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png | 3 +++ ....components_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png | 3 --- ...components_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png | 3 --- 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..aaab9d35c1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ea42394330d37a0aa5ba8940e023fc4454d902caf6d265adec0e11c8a34d85f +size 187744 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..65a27f228d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fb074cd58034c90010dc437fc01d6ea77a2a22aa07bc1d4cf0c1730b543b41a +size 186707 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 8838c1cbf2..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerDark_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd761ca4ff5a70770869780c2575006ed8bd187ed4b3f197ffe1e4ea18d8390b -size 189559 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 80a5da9cd1..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_EmojiPickerLight_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8c6e3f139ca634c47c45fbeeaccf3e7e903fb8f83a88fdf8d7247455e76e4a9 -size 188653 From 1d3d1fe48072e5a9333198687018f806433bddb2 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 30 Aug 2023 19:02:37 +0200 Subject: [PATCH 015/127] Fix the orientation of sent images (#1190) * Fix the orientation of sent images --------- Co-authored-by: Benoit Marty --- changelog.d/1135.bugfix | 1 + .../libraries/androidutils/bitmap/Bitmap.kt | 19 +++++++------------ .../mediaupload/AndroidMediaPreProcessor.kt | 7 +++++++ .../libraries/mediaupload/ImageCompressor.kt | 11 +++++++---- 4 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 changelog.d/1135.bugfix diff --git a/changelog.d/1135.bugfix b/changelog.d/1135.bugfix new file mode 100644 index 0000000000..2b963c7732 --- /dev/null +++ b/changelog.d/1135.bugfix @@ -0,0 +1 @@ +Fix the orientation of sent images. diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/bitmap/Bitmap.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/bitmap/Bitmap.kt index 6f8aa76d03..c3b7e3110e 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/bitmap/Bitmap.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/bitmap/Bitmap.kt @@ -22,7 +22,6 @@ import android.graphics.Matrix import androidx.core.graphics.scale import androidx.exifinterface.media.ExifInterface import java.io.File -import java.io.InputStream import kotlin.math.min fun File.writeBitmap(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int) { @@ -32,13 +31,6 @@ fun File.writeBitmap(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int } } -/** - * Reads the EXIF metadata from the [inputStream] and rotates the current [Bitmap] to match it. - * @return The resulting [Bitmap] or `null` if no metadata was found. - */ -fun Bitmap.rotateToMetadataOrientation(inputStream: InputStream): Result = - runCatching { rotateToMetadataOrientation(this, ExifInterface(inputStream)) } - /** * Scales the current [Bitmap] to fit the ([maxWidth], [maxHeight]) bounds while keeping aspect ratio. * @throws IllegalStateException if [maxWidth] or [maxHeight] <= 0. @@ -77,8 +69,11 @@ fun BitmapFactory.Options.calculateInSampleSize(desiredWidth: Int, desiredHeight return inSampleSize } -private fun rotateToMetadataOrientation(bitmap: Bitmap, exifInterface: ExifInterface): Bitmap { - val orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) +/** + * Decodes the [inputStream] into a [Bitmap] and applies the needed rotation based on [orientation]. + * This orientation value must be one of `ExifInterface.ORIENTATION_*` constants. + */ +fun Bitmap.rotateToMetadataOrientation(orientation: Int): Bitmap { val matrix = Matrix() when (orientation) { ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f) @@ -94,8 +89,8 @@ private fun rotateToMetadataOrientation(bitmap: Bitmap, exifInterface: ExifInter matrix.preRotate(90f) matrix.preScale(-1f, 1f) } - else -> return bitmap + else -> return this } - return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true) } diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt index 8ff40fae39..9fc160252b 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt @@ -119,10 +119,17 @@ class AndroidMediaPreProcessor @Inject constructor( private suspend fun processImage(uri: Uri, mimeType: String, shouldBeCompressed: Boolean): MediaUploadInfo { suspend fun processImageWithCompression(): MediaUploadInfo { + // Read the orientation metadata from its own stream. Trying to reuse this stream for compression will fail. + val orientation = contentResolver.openInputStream(uri).use { input -> + val exifInterface = input?.let { ExifInterface(it) } + exifInterface?.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED) + } ?: ExifInterface.ORIENTATION_UNDEFINED + val compressionResult = contentResolver.openInputStream(uri).use { input -> imageCompressor.compressToTmpFile( inputStream = requireNotNull(input), resizeMode = ResizeMode.Approximate(IMAGE_SCALE_REF_SIZE, IMAGE_SCALE_REF_SIZE), + orientation = orientation, ).getOrThrow() } val thumbnailResult: ThumbnailResult = thumbnailFactory.createImageThumbnail(compressionResult.file) diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/ImageCompressor.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/ImageCompressor.kt index ab30f67b65..a619a27bd9 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/ImageCompressor.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/ImageCompressor.kt @@ -19,6 +19,7 @@ package io.element.android.libraries.mediaupload import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory +import androidx.exifinterface.media.ExifInterface import io.element.android.libraries.androidutils.bitmap.calculateInSampleSize import io.element.android.libraries.androidutils.bitmap.resizeToMax import io.element.android.libraries.androidutils.bitmap.rotateToMetadataOrientation @@ -37,17 +38,18 @@ class ImageCompressor @Inject constructor( /** * Decodes the [inputStream] into a [Bitmap] and applies the needed transformations (rotation, scale) based on [resizeMode], then writes it into a - * temporary file using the passed [format] and [desiredQuality]. + * temporary file using the passed [format], [orientation] and [desiredQuality]. * @return a [Result] containing the resulting [ImageCompressionResult] with the temporary [File] and some metadata. */ suspend fun compressToTmpFile( inputStream: InputStream, resizeMode: ResizeMode, format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG, + orientation: Int = ExifInterface.ORIENTATION_UNDEFINED, desiredQuality: Int = 80, ): Result = withContext(Dispatchers.IO) { runCatching { - val compressedBitmap = compressToBitmap(inputStream, resizeMode).getOrThrow() + val compressedBitmap = compressToBitmap(inputStream, resizeMode, orientation).getOrThrow() // Encode bitmap to the destination temporary file val tmpFile = context.createTmpFile(extension = "jpeg") tmpFile.outputStream().use { @@ -63,19 +65,20 @@ class ImageCompressor @Inject constructor( } /** - * Decodes the [inputStream] into a [Bitmap] and applies the needed transformations (rotation, scale) based on [resizeMode]. + * Decodes the [inputStream] into a [Bitmap] and applies the needed transformations (rotation, scale) based on [resizeMode] and [orientation]. * @return a [Result] containing the resulting [Bitmap]. */ fun compressToBitmap( inputStream: InputStream, resizeMode: ResizeMode, + orientation: Int, ): Result = runCatching { BufferedInputStream(inputStream).use { input -> val options = BitmapFactory.Options() calculateDecodingScale(input, resizeMode, options) val decodedBitmap = BitmapFactory.decodeStream(input, null, options) ?: error("Decoding Bitmap from InputStream failed") - val rotatedBitmap = decodedBitmap.rotateToMetadataOrientation(input).getOrThrow() + val rotatedBitmap = decodedBitmap.rotateToMetadataOrientation(orientation) if (resizeMode is ResizeMode.Strict) { rotatedBitmap.resizeToMax(resizeMode.maxWidth, resizeMode.maxHeight) } else { From 50869d7b28e2bdc238f677e5aa088380486bd321 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Thu, 31 Aug 2023 12:08:21 +0200 Subject: [PATCH 016/127] Focus on question field when opening screen. (#1194) --- .../poll/impl/create/CreatePollView.kt | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt index 3e3ec4eb16..ceb9513545 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt @@ -25,12 +25,19 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.poll.impl.R @@ -68,6 +75,10 @@ fun CreatePollView( onSubmitClicked = { state.eventSink(CreatePollEvents.NavBack) }, onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) } ) + val questionFocusRequester = remember { FocusRequester() } + LaunchedEffect(Unit) { + questionFocusRequester.requestFocus() + } Scaffold( modifier = modifier, topBar = { @@ -113,10 +124,13 @@ fun CreatePollView( onValueChange = { state.eventSink(CreatePollEvents.SetQuestion(it)) }, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .focusRequester(questionFocusRequester) + .fillMaxWidth(), placeholder = { Text(text = stringResource(id = R.string.screen_create_poll_question_hint)) }, + keyboardOptions = keyboardOptions, ) } ) @@ -133,6 +147,7 @@ fun CreatePollView( placeholder = { Text(text = stringResource(id = R.string.screen_create_poll_answer_hint, index + 1)) }, + keyboardOptions = keyboardOptions, ) }, trailingContent = ListItemContent.Custom { @@ -185,3 +200,8 @@ internal fun CreatePollViewPreview( state = state, ) } + +private val keyboardOptions = KeyboardOptions.Default.copy( + capitalization = KeyboardCapitalization.Sentences, + imeAction = ImeAction.Next, +) From c0a4ca16a25f6b99391bf2c2bca32ae622dfbc6a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:35:31 +0200 Subject: [PATCH 017/127] Update dagger to v2.48 (#1193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d52d1e0df..863d4812b8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -48,7 +48,7 @@ sqldelight = "1.5.5" telephoto = "0.6.0-SNAPSHOT" # DI -dagger = "2.47" +dagger = "2.48" anvil = "2.4.7-1-8" # Auto service From ecf2d0692863e6d08d2aaa27d296d3e98dd281aa Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 31 Aug 2023 11:37:08 +0100 Subject: [PATCH 018/127] Fix colon aligment and load emojis lazily. - Fix colon aligment - Load emojis lazily. --- .../components/customreaction/CustomReactionPresenter.kt | 2 +- .../components/customreaction/DefaultEmojibaseProvider.kt | 8 +++++--- .../components/customreaction/EmojibaseProvider.kt | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index 6831ca7dfa..b048383b1f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -43,7 +43,7 @@ class CustomReactionPresenter @Inject constructor( localCoroutineScope.launch { target.value = CustomReactionState.Target.Success( event = event, - emojibaseStore = emojibaseProvider.loadEmojibase() + emojibaseStore = emojibaseProvider.emojibaseStore ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt index 2e66ea381e..a68d6f0d4e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/DefaultEmojibaseProvider.kt @@ -20,8 +20,10 @@ import android.content.Context import io.element.android.emojibasebindings.EmojibaseDatasource import io.element.android.emojibasebindings.EmojibaseStore -class DefaultEmojibaseProvider(val context: Context) :EmojibaseProvider { - override fun loadEmojibase(): EmojibaseStore { - return EmojibaseDatasource().load(context) +class DefaultEmojibaseProvider(val context: Context): EmojibaseProvider { + + override val emojibaseStore: EmojibaseStore by lazy { + EmojibaseDatasource().load(context) } + } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt index 39739538d2..6a4f48a806 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojibaseProvider.kt @@ -19,5 +19,5 @@ package io.element.android.features.messages.impl.timeline.components.customreac import io.element.android.emojibasebindings.EmojibaseStore interface EmojibaseProvider { - fun loadEmojibase(): EmojibaseStore + val emojibaseStore: EmojibaseStore } From b16faeceba66b721fa0c7b15a2955138066cda52 Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 31 Aug 2023 11:41:06 +0100 Subject: [PATCH 019/127] Fix FakeEmojibaseProvider --- .../components/customreaction/FakeEmojibaseProvider.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt index 434212030a..7bf993e2a4 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/FakeEmojibaseProvider.kt @@ -20,7 +20,6 @@ import io.element.android.emojibasebindings.EmojibaseStore import io.element.android.features.messages.impl.timeline.components.customreaction.EmojibaseProvider class FakeEmojibaseProvider: EmojibaseProvider { - override fun loadEmojibase(): EmojibaseStore { - return EmojibaseStore(mapOf()) - } + override val emojibaseStore: EmojibaseStore + get() = EmojibaseStore(mapOf()) } From d4ae0ec226faf0c96f3bd69f49f19953781b7e87 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:54:01 +0000 Subject: [PATCH 020/127] Update mobile-dev-inc/action-maestro-cloud action to v1.5.0 --- .github/workflows/maestro.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maestro.yml b/.github/workflows/maestro.yml index 74fb1cfc83..46ee84896f 100644 --- a/.github/workflows/maestro.yml +++ b/.github/workflows/maestro.yml @@ -40,7 +40,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} - - uses: mobile-dev-inc/action-maestro-cloud@v1.4.1 + - uses: mobile-dev-inc/action-maestro-cloud@v1.5.0 with: api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }} # Doc says (https://github.com/mobile-dev-inc/action-maestro-cloud#android): From 47a0ecb3b8196323c1b8e187acbe88a986b0d2ee Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Thu, 31 Aug 2023 12:58:37 +0200 Subject: [PATCH 021/127] Protect `TimelineItemAspectRatioBox` against `Float.NaN` (#1201) * Protect `TimelineItemAspectRatioBox` against infinite values. --- changelog.d/1995.bugfix | 1 + .../factories/event/TimelineItemContentMessageFactory.kt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1995.bugfix diff --git a/changelog.d/1995.bugfix b/changelog.d/1995.bugfix new file mode 100644 index 0000000000..acec25add0 --- /dev/null +++ b/changelog.d/1995.bugfix @@ -0,0 +1 @@ +Crash with `aspectRatio` modifier when `Float.NaN` was used as input. diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index 9da31ee6a7..040969e092 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -132,10 +132,12 @@ class TimelineItemContentMessageFactory @Inject constructor( } private fun aspectRatioOf(width: Long?, height: Long?): Float? { - return if (height != null && width != null) { + val result = if (height != null && width != null) { width.toFloat() / height.toFloat() } else { null } + + return result?.takeIf { it.isFinite() } } } From 199f578e4a795687f3dbb8e13f8f37daed32baef Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Thu, 31 Aug 2023 13:37:20 +0200 Subject: [PATCH 022/127] Re-enable `SyncService.withEncryptionSync` to improve decryption of notifications (#1199) * Re-enable `SyncService.withEncryptionSync` to improve decryption of notifications. * Add feature flag --- changelog.d/1198.bugfix | 1 + .../impl/developer/DeveloperSettingsPresenter.kt | 10 ++++++++-- .../android/libraries/featureflag/api/FeatureFlags.kt | 6 ++++++ .../featureflag/impl/BuildtimeFeatureFlagProvider.kt | 1 + libraries/matrix/impl/build.gradle.kts | 1 + .../libraries/matrix/impl/RustMatrixClientFactory.kt | 10 +++++++++- samples/minimal/build.gradle.kts | 1 + .../io/element/android/samples/minimal/MainActivity.kt | 4 +++- 8 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 changelog.d/1198.bugfix diff --git a/changelog.d/1198.bugfix b/changelog.d/1198.bugfix new file mode 100644 index 0000000000..6ef69c4eff --- /dev/null +++ b/changelog.d/1198.bugfix @@ -0,0 +1 @@ +Re-enable `SyncService.withEncryptionSync` to improve decryption of notifications. diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index 010e17bd35..5f50fde309 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -83,7 +83,8 @@ class DeveloperSettingsPresenter @Inject constructor( features, enabledFeatures, event.feature, - event.isEnabled + event.isEnabled, + triggerClearCache = { handleEvents(DeveloperSettingsEvents.ClearCache) } ) DeveloperSettingsEvents.ClearCache -> coroutineScope.clearCache(clearCacheAction) } @@ -122,12 +123,17 @@ class DeveloperSettingsPresenter @Inject constructor( features: SnapshotStateMap, enabledFeatures: SnapshotStateMap, featureUiModel: FeatureUiModel, - enabled: Boolean + enabled: Boolean, + triggerClearCache: () -> Unit, ) = launch { val feature = features[featureUiModel.key] ?: return@launch if (featureFlagService.setFeatureEnabled(feature, enabled)) { enabledFeatures[featureUiModel.key] = enabled } + + if (featureUiModel.key == FeatureFlags.UseEncryptionSync.key) { + triggerClearCache() + } } private fun CoroutineScope.computeCacheSize(cacheSize: MutableState>) = launch { diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index e1f4b740b0..08ac0ae039 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -31,5 +31,11 @@ enum class FeatureFlags( title = "Polls", description = "Create poll and render poll events in the timeline", defaultValue = false, + ), + UseEncryptionSync( + key = "feature.useencryptionsync", + title = "Use encryption sync", + description = "Use the encryption sync API for decrypting notifications.", + defaultValue = true, ) } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt index 83913cbac5..5640d108a6 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt @@ -31,6 +31,7 @@ class BuildtimeFeatureFlagProvider @Inject constructor() : when (feature) { FeatureFlags.LocationSharing -> true FeatureFlags.Polls -> false + FeatureFlags.UseEncryptionSync -> true } } else { false diff --git a/libraries/matrix/impl/build.gradle.kts b/libraries/matrix/impl/build.gradle.kts index b2a21f26df..a2b616f989 100644 --- a/libraries/matrix/impl/build.gradle.kts +++ b/libraries/matrix/impl/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.network) implementation(projects.services.toolbox.api) + implementation(projects.libraries.featureflag.api) api(projects.libraries.matrix.api) implementation(libs.dagger) implementation(projects.libraries.core) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index bb80032230..3615115bb4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -19,6 +19,8 @@ package io.element.android.libraries.matrix.impl import android.content.Context import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.network.useragent.UserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionData import io.element.android.libraries.sessionstorage.api.SessionStore @@ -39,6 +41,7 @@ class RustMatrixClientFactory @Inject constructor( private val sessionStore: SessionStore, private val userAgentProvider: UserAgentProvider, private val clock: SystemClock, + private val featureFlagsService: FeatureFlagService, ) { suspend fun create(sessionData: SessionData): RustMatrixClient = withContext(coroutineDispatchers.io) { @@ -53,7 +56,12 @@ class RustMatrixClientFactory @Inject constructor( client.restoreSession(sessionData.toSession()) - val syncService = client.syncService().finish() + val syncService = client.syncService().apply { + if (featureFlagsService.isFeatureEnabled(FeatureFlags.UseEncryptionSync)) { + withEncryptionSync(withCrossProcessLock = false, appIdentifier = null) + } + } + .finish() RustMatrixClient( client = client, diff --git a/samples/minimal/build.gradle.kts b/samples/minimal/build.gradle.kts index 8063ac9b0a..1473bd7f93 100644 --- a/samples/minimal/build.gradle.kts +++ b/samples/minimal/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { implementation(projects.features.login.impl) implementation(projects.features.networkmonitor.impl) implementation(projects.services.toolbox.impl) + implementation(projects.libraries.featureflag.impl) implementation(libs.coroutines.core) coreLibraryDesugaring(libs.android.desugar) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index a915e70046..94cd28f021 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.core.view.WindowCompat +import io.element.android.libraries.featureflag.impl.DefaultFeatureFlagService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.impl.RustMatrixClientFactory import io.element.android.libraries.matrix.impl.auth.RustMatrixAuthenticationService @@ -54,7 +55,8 @@ class MainActivity : ComponentActivity() { coroutineDispatchers = Singleton.coroutineDispatchers, sessionStore = sessionStore, userAgentProvider = userAgentProvider, - clock = DefaultSystemClock() + clock = DefaultSystemClock(), + featureFlagsService = DefaultFeatureFlagService(emptySet()) ) ) } From 3a920f1a9dab02fbfdff9220377a404c4ba1307b Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Thu, 31 Aug 2023 14:39:11 +0200 Subject: [PATCH 023/127] Poll end (#1182) - Adds an "End Poll" item in the action list long press menu. - Shows only on remote polls that have not ended yet and only if the user is the creator or has redact powers. Closes https://github.com/vector-im/element-meta/issues/2026 --- .../messages/impl/MessagesPresenter.kt | 6 ++ .../impl/actionlist/ActionListPresenter.kt | 12 +++- .../actionlist/ActionListStateProvider.kt | 18 ++++++ .../actionlist/model/TimelineItemAction.kt | 1 + .../TimelineItemLocationContentProvider.kt | 33 +++++++++++ .../messages/MessagesPresenterTest.kt | 19 +++++++ .../actionlist/ActionListPresenterTest.kt | 56 +++++++++---------- .../poll/impl/create/CreatePollView.kt | 2 +- .../impl/src/main/res/values/localazy.xml | 2 +- .../libraries/designsystem/VectorIcons.kt | 1 + .../src/main/res/drawable/ic_done_24.xml | 10 ++++ .../src/main/res/values/localazy.xml | 1 + ...etContent-D-0_1_null_8,NEXUS_5,1.0,en].png | 3 + ...etContent-N-0_2_null_8,NEXUS_5,1.0,en].png | 3 + 14 files changed, 134 insertions(+), 33 deletions(-) create mode 100644 libraries/designsystem/src/main/res/drawable/ic_done_24.xml create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 8a374471e3..5f67fd1f7c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -202,6 +202,7 @@ class MessagesPresenter @AssistedInject constructor( TimelineItemAction.Developer -> handleShowDebugInfoAction(targetEvent) TimelineItemAction.Forward -> handleForwardAction(targetEvent) TimelineItemAction.ReportContent -> handleReportAction(targetEvent) + TimelineItemAction.EndPoll -> handleEndPollAction(targetEvent) } } @@ -310,6 +311,11 @@ class MessagesPresenter @AssistedInject constructor( navigator.onReportContentClicked(event.eventId, event.senderId) } + private suspend fun handleEndPollAction(event: TimelineItem.Event) { + event.eventId?.let { room.endPoll(it, "The poll with event id: $it has ended.") } + // TODO Polls: Send poll end analytic + } + private suspend fun handleCopyContents(event: TimelineItem.Event) { val content = when (event.content) { is TimelineItemTextBasedContent -> event.content.body diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index e654365bcd..f5e28818c9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -99,6 +99,16 @@ class ActionListPresenter @Inject constructor( } is TimelineItemPollContent -> { buildList { + val isMineOrCanRedact = timelineItem.isMine || userCanRedact + + // TODO Poll: Reply to poll + // if (timelineItem.isRemote) { + // // Can only reply or forward messages already uploaded to the server + // add(TimelineItemAction.Reply) + // } + if (!timelineItem.content.isEnded && timelineItem.isRemote && isMineOrCanRedact) { + add(TimelineItemAction.EndPoll) + } if (timelineItem.content.canBeCopied()) { add(TimelineItemAction.Copy) } @@ -108,7 +118,7 @@ class ActionListPresenter @Inject constructor( if (!timelineItem.isMine) { add(TimelineItemAction.ReportContent) } - if (timelineItem.isMine || userCanRedact) { + if (isMineOrCanRedact) { add(TimelineItemAction.Redact) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt index 09213d64b3..755d4c36e1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt @@ -23,6 +23,7 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemReactions import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemLocationContent +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVideoContent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -83,6 +84,15 @@ open class ActionListStateProvider : PreviewParameterProvider { ), displayEmojiReactions = false, ), + anActionListState().copy( + target = ActionListState.Target.Success( + event = aTimelineItemEvent(content = aTimelineItemPollContent()).copy( + reactionsState = reactionsState + ), + actions = aTimelineItemPollActionList(), + ), + displayEmojiReactions = false, + ), ) } } @@ -104,3 +114,11 @@ fun aTimelineItemActionList(): ImmutableList { TimelineItemAction.Developer, ) } +fun aTimelineItemPollActionList(): ImmutableList { + return persistentListOf( + TimelineItemAction.Reply, + TimelineItemAction.EndPoll, + TimelineItemAction.Developer, + TimelineItemAction.Redact, + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt index b6141218eb..8dc48f892e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt @@ -35,4 +35,5 @@ sealed class TimelineItemAction( data object Edit : TimelineItemAction(CommonStrings.action_edit, VectorIcons.Edit) data object Developer : TimelineItemAction(CommonStrings.action_view_source, VectorIcons.DeveloperMode) data object ReportContent : TimelineItemAction(CommonStrings.action_report_content, VectorIcons.ReportContent, destructive = true) + data object EndPoll : TimelineItemAction(CommonStrings.action_end_poll, VectorIcons.EndPoll) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt index a21f262071..7ad79f19e8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt @@ -18,6 +18,10 @@ package io.element.android.features.messages.impl.timeline.model.event import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location +import io.element.android.features.poll.api.PollAnswerItem +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.poll.PollAnswer +import io.element.android.libraries.matrix.api.poll.PollKind open class TimelineItemLocationContentProvider : PreviewParameterProvider { override val values: Sequence @@ -36,3 +40,32 @@ fun aTimelineItemLocationContent(description: String? = null) = TimelineItemLoca ), description = description, ) + +fun aTimelineItemPollContent( + isEnded: Boolean = false, +) = TimelineItemPollContent( + eventId = EventId("\$anEventId"), + question = "Some question?", + answerItems = listOf( + PollAnswerItem( + answer = PollAnswer("id_1", "Answer1"), + isSelected = false, + isEnabled = false, + isWinner = false, + isDisclosed = false, + votesCount = 0, + percentage = 0.0f, + ), + PollAnswerItem( + answer = PollAnswer("id_2", "Answer2"), + isSelected = false, + isEnabled = false, + isWinner = false, + isDisclosed = false, + votesCount = 0, + percentage = 0.0f, + ), + ), + pollKind = PollKind.Disclosed, + isEnded = isEnded, +) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 2c542e0054..f5d0185789 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -72,6 +72,7 @@ import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilTimeout import io.element.android.tests.testutils.testCoroutineDispatchers +import io.element.android.tests.testutils.waitForPredicate import io.mockk.mockk import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -559,6 +560,24 @@ class MessagesPresenterTest { } } + @Test + fun `present - handle poll end`() = runTest { + val room = FakeMatrixRoom() + val presenter = createMessagePresenter(matrixRoom = room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EndPoll, aMessageEvent())) + waitForPredicate { room.endPollInvocations.size == 1 } + cancelAndIgnoreRemainingEvents() + assertThat(room.endPollInvocations.size).isEqualTo(1) + assertThat(room.endPollInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID) + assertThat(room.endPollInvocations.first().text).isEqualTo("The poll with event id: \$anEventId has ended.") + // TODO Polls: Test poll end analytic + } + } + private fun TestScope.createMessagePresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(), matrixRoom: MatrixRoom = FakeMatrixRoom(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt index 111b3a370d..a4ff484ff3 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt @@ -26,15 +26,11 @@ import io.element.android.features.messages.impl.actionlist.ActionListPresenter import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.timeline.aTimelineItemEvent -import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemStateEventContent -import io.element.android.features.poll.api.PollAnswerItem -import io.element.android.libraries.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.poll.PollAnswer -import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.core.aBuildMeta import kotlinx.collections.immutable.persistentListOf @@ -384,34 +380,34 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = true, - content = TimelineItemPollContent( - eventId = EventId("\$anEventId"), - question = "Some question?", - answerItems = listOf( - PollAnswerItem( - answer = PollAnswer("id_1", "Answer1"), - isSelected = false, - isEnabled = false, - isWinner = false, - isDisclosed = false, - votesCount = 0, - percentage = 0.0f, - ), - PollAnswerItem( - answer = PollAnswer("id_2", "Answer2"), - isSelected = false, - isEnabled = false, - isWinner = false, - isDisclosed = false, - votesCount = 0, - percentage = 0.0f, - ), - ), - pollKind = PollKind.Disclosed, - isEnded = false, + content = aTimelineItemPollContent(), + ) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + messageEvent, + persistentListOf( + TimelineItemAction.EndPoll, + TimelineItemAction.Redact, + ) ) ) + assertThat(successState.displayEmojiReactions).isTrue() + } + } + @Test + fun `present - compute for ended poll message`() = runTest { + val presenter = anActionListPresenter(isBuildDebuggable = false) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = true, + content = aTimelineItemPollContent(isEnded = true), + ) initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) val successState = awaitItem() assertThat(successState.target).isEqualTo( diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt index ceb9513545..8e3de07574 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt @@ -71,7 +71,7 @@ fun CreatePollView( val navBack = { state.eventSink(CreatePollEvents.ConfirmNavBack) } BackHandler(onBack = navBack) if (state.showConfirmation) ConfirmationDialog( - content = stringResource(id = R.string.screen_create_poll_confirmation), + content = stringResource(id = R.string.screen_create_poll_discard_confirmation), onSubmitClicked = { state.eventSink(CreatePollEvents.NavBack) }, onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) } ) diff --git a/features/poll/impl/src/main/res/values/localazy.xml b/features/poll/impl/src/main/res/values/localazy.xml index 846b247108..876dd0ee44 100644 --- a/features/poll/impl/src/main/res/values/localazy.xml +++ b/features/poll/impl/src/main/res/values/localazy.xml @@ -4,7 +4,7 @@ "Show results only after poll ends" "Anonymous Poll" "Option %1$d" - "Are you sure you would like to go back?" + "Are you sure you would like to go back?" "Question or topic" "What is the poll about?" "Create Poll" diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt index 47b951baa2..51755ef966 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt @@ -27,4 +27,5 @@ object VectorIcons { val ReportContent = R.drawable.ic_report_content val Groups = R.drawable.ic_groups val Share = R.drawable.ic_share + val EndPoll = R.drawable.ic_done_24 } diff --git a/libraries/designsystem/src/main/res/drawable/ic_done_24.xml b/libraries/designsystem/src/main/res/drawable/ic_done_24.xml new file mode 100644 index 0000000000..280f0bd804 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_done_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 4f25e8f07b..95ae43dd21 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -61,6 +61,7 @@ "Take photo" "View Source" "Yes" + "End poll" "About" "Acceptable use policy" "Analytics" diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..6ac8e597c5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b0cc63408163b06093d0c8d238eb9451bf526af518c8f09c53a96b33d72c10f +size 23135 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..11192bb213 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7026daf71085ac6c62b66f93c1002afd1f5bb28446aa896fac8b11f2750ac80c +size 22317 From 582705139edbe7127d5ddb1aadee2fa6e6072e40 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Tue, 29 Aug 2023 16:45:14 +0200 Subject: [PATCH 024/127] Poll: Maestro tests --- .maestro/tests/roomList/timeline/messages/poll.yaml | 13 +++++++++++++ .maestro/tests/roomList/timeline/timeline.yaml | 1 + 2 files changed, 14 insertions(+) create mode 100644 .maestro/tests/roomList/timeline/messages/poll.yaml diff --git a/.maestro/tests/roomList/timeline/messages/poll.yaml b/.maestro/tests/roomList/timeline/messages/poll.yaml new file mode 100644 index 0000000000..65495dda60 --- /dev/null +++ b/.maestro/tests/roomList/timeline/messages/poll.yaml @@ -0,0 +1,13 @@ +appId: ${APP_ID} +--- +- takeScreenshot: build/maestro/530-Timeline +- tapOn: "Add attachment" +- tapOn: "Poll" +- tapOn: "What is the poll about?" +- inputText: "I am a poll" +- tapOn: "Option 1" +- inputText: "Answer 1" +- tapOn: "Option 2" +- inputText: "Answer 2" +- tapOn: "Create" +- takeScreenshot: build/maestro/531-Timeline diff --git a/.maestro/tests/roomList/timeline/timeline.yaml b/.maestro/tests/roomList/timeline/timeline.yaml index bec566985d..1acb10a9aa 100644 --- a/.maestro/tests/roomList/timeline/timeline.yaml +++ b/.maestro/tests/roomList/timeline/timeline.yaml @@ -5,5 +5,6 @@ appId: ${APP_ID} - takeScreenshot: build/maestro/500-Timeline - runFlow: messages/text.yaml - runFlow: messages/location.yaml +- runFlow: messages/poll.yaml - back - runFlow: ../../assertions/assertHomeDisplayed.yaml From 33683abf5914df026b37993f12b03fc4d0486f23 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Thu, 31 Aug 2023 15:17:11 +0200 Subject: [PATCH 025/127] Enable polls (#1196) Enable the Polls feature. Allows to create, view, vote and end polls. --- changelog.d/1196.feature | 1 + .../io/element/android/libraries/featureflag/api/FeatureFlags.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 changelog.d/1196.feature diff --git a/changelog.d/1196.feature b/changelog.d/1196.feature new file mode 100644 index 0000000000..fe1eb354f9 --- /dev/null +++ b/changelog.d/1196.feature @@ -0,0 +1 @@ +Enable the Polls feature. Allows to create, view, vote and end polls. diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 08ac0ae039..312745a4df 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -30,7 +30,6 @@ enum class FeatureFlags( key = "feature.polls", title = "Polls", description = "Create poll and render poll events in the timeline", - defaultValue = false, ), UseEncryptionSync( key = "feature.useencryptionsync", From 09871c712d3b01f803095e96c8bc8b191d150455 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 31 Aug 2023 14:17:14 +0100 Subject: [PATCH 026/127] Update Localazy readme. --- tools/localazy/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/localazy/README.md b/tools/localazy/README.md index b0b5c7e980..2da7afd8bb 100644 --- a/tools/localazy/README.md +++ b/tools/localazy/README.md @@ -26,13 +26,15 @@ Never edit manually the files `localazy.xml` or `translations.xml`!. For code clarity and in order to download strings to the correct module, here are some naming rules to follow as much as possible: -- Keys for common strings, i.e. strings that can be used at multiple places must start by `action_` if this is a verb, or `common_` if not; -- Keys for common accessibility strings must start by `a11y_`. Example: `a11y_hide_password`; +- Keys for common strings, i.e. strings that can be used at multiple places must start by `action.` if this is a verb, or `common.` if not; +- Keys for common accessibility strings must start by `a11y.`. Example: `a11y.hide_password`; +- Keys for common strings should be named to match the string. Example: `action.copy_link` for the string `Copy link`; +- When creating common strings, make sure to enable "Use dot (.) to create nested keys"; - Keys for strings used in a single screen must start with `screen_` followed by the screen name, followed by a free name. Example: `screen_onboarding_welcome_title`; - Keys can have `_title` or `_subtitle` suffixes. Example: `screen_onboarding_welcome_title`, `screen_change_server_subtitle`; - For dialogs, keys can have `_dialog_title`, `_dialog_content`, and `_dialog_submit` suffixes. Example: `screen_signout_confirmation_dialog_title`, `screen_signout_confirmation_dialog_content`, `screen_signout_confirmation_dialog_submit`; -- `a11y_` pattern can be used for strings that are only used for accessibility. Example: `a11y_hide_password`, `screen_roomlist_a11y_create_message`; -- Strings for error message can start by `error_`, or contain `_error_` if used in a specific screen only. Example: `error_some_messages_have_not_been_sent`, `screen_change_server_error_invalid_homeserver`. +- `a11y.` pattern can be used for strings that are only used for accessibility. Example: `a11y.hide_password`, `screen_roomlist_a11y_create_message`; +- Strings for error message can start by `error_`, or contain `_error_` if used in a specific screen only. Example: `error_some_messages_have_not_been_sent`, `screen_change_server_error_invalid_homeserver`; *Note*: those rules applies for `strings` and for `plurals`. From 00828b671442769ff781b4f8f45149adc52024b3 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Thu, 31 Aug 2023 15:40:51 +0200 Subject: [PATCH 027/127] New icon for "poll end" in both action menu and timeline item. (#1203) - Also fixes preview of action list (reply is included as it will soon be added). --- .../actionlist/ActionListStateProvider.kt | 4 +++- .../features/poll/api/PollContentView.kt | 24 +++++++++++++------ .../libraries/designsystem/VectorIcons.kt | 2 +- .../src/main/res/drawable/ic_done_24.xml | 10 -------- .../src/main/res/drawable/ic_poll_end.xml | 14 +++++++++++ ...etContent-D-0_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-N-0_2_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...ontentEnded-D-2_2_null,NEXUS_5,1.0,en].png | 4 ++-- ...ontentEnded-N-2_3_null,NEXUS_5,1.0,en].png | 4 ++-- 9 files changed, 43 insertions(+), 27 deletions(-) delete mode 100644 libraries/designsystem/src/main/res/drawable/ic_done_24.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_poll_end.xml diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt index 755d4c36e1..bb9c851288 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt @@ -116,9 +116,11 @@ fun aTimelineItemActionList(): ImmutableList { } fun aTimelineItemPollActionList(): ImmutableList { return persistentListOf( - TimelineItemAction.Reply, TimelineItemAction.EndPoll, + TimelineItemAction.Reply, + TimelineItemAction.Copy, TimelineItemAction.Developer, + TimelineItemAction.ReportContent, TimelineItemAction.Redact, ) } diff --git a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt index 438c14456c..9301630b73 100644 --- a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt +++ b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.VectorIcons import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.Icon @@ -62,7 +63,7 @@ fun PollContentView( .fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(16.dp), ) { - PollTitle(title = question) + PollTitle(title = question, isPollEnded = isPollEnded) PollAnswers(answerItems = answerItems, onAnswerSelected = ::onAnswerSelected) @@ -76,17 +77,26 @@ fun PollContentView( @Composable internal fun PollTitle( title: String, + isPollEnded: Boolean, modifier: Modifier = Modifier ) { Row( modifier = modifier, horizontalArrangement = Arrangement.spacedBy(12.dp), ) { - Icon( - modifier = Modifier.size(22.dp), - imageVector = Icons.Outlined.Poll, - contentDescription = null - ) + if (isPollEnded) { + Icon( + resourceId = VectorIcons.EndPoll, + contentDescription = null, + modifier = Modifier.size(22.dp) + ) + } else { + Icon( + imageVector = Icons.Outlined.Poll, + contentDescription = null, + modifier = Modifier.size(22.dp) + ) + } Text( text = title, style = ElementTheme.typography.fontBodyLgMedium @@ -170,7 +180,7 @@ internal fun PollContentEndedPreview() = ElementPreview { question = "What type of food should we have at the party?", answerItems = aPollAnswerItemList(isEnded = true), pollKind = PollKind.Disclosed, - isPollEnded = false, + isPollEnded = true, onAnswerSelected = { _, _ -> }, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt index 51755ef966..4f06b3ebcb 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt @@ -27,5 +27,5 @@ object VectorIcons { val ReportContent = R.drawable.ic_report_content val Groups = R.drawable.ic_groups val Share = R.drawable.ic_share - val EndPoll = R.drawable.ic_done_24 + val EndPoll = R.drawable.ic_poll_end } diff --git a/libraries/designsystem/src/main/res/drawable/ic_done_24.xml b/libraries/designsystem/src/main/res/drawable/ic_done_24.xml deleted file mode 100644 index 280f0bd804..0000000000 --- a/libraries/designsystem/src/main/res/drawable/ic_done_24.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml b/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml new file mode 100644 index 0000000000..21d895e613 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml @@ -0,0 +1,14 @@ + + + + diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png index 6ac8e597c5..cb2e25b07f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b0cc63408163b06093d0c8d238eb9451bf526af518c8f09c53a96b33d72c10f -size 23135 +oid sha256:3598515dc84276014c2f3827f533c808a2683191a67e7a68191501bb848b8293 +size 28326 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png index 11192bb213..0311150ab0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7026daf71085ac6c62b66f93c1002afd1f5bb28446aa896fac8b11f2750ac80c -size 22317 +oid sha256:d00152b1ff92d93564af11537dcb8d77116e943cfa2b45dee2c66260284b8807 +size 26875 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png index f148a727ae..140c07a3ca 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a9ccbbc0a208ac398f07f0070a43d0ca5ab67ef322b274b641270a9c21a4a60 -size 48972 +oid sha256:434c4f6dc4ee4c66291eca2ff1a8ab2471aaf521dbbf0d32f53f277ea6519c07 +size 49107 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png index df2a5c30b9..0b32e49a00 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5736eb1d232b841d62f9d96070fc9b2993453652f5d7c448b6a819db9543615e -size 45756 +oid sha256:63685437c43543115e8f509919ef179d70a620c012c8a46ebf6682dcfe9820c6 +size 45890 From eef5aa19490a786f90476a958543e208856de6b3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Aug 2023 15:41:48 +0200 Subject: [PATCH 028/127] fix typo in git url. Co-authored-by: Florian Renaud --- docs/install_from_github_release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install_from_github_release.md b/docs/install_from_github_release.md index 57363a617c..de395f737a 100644 --- a/docs/install_from_github_release.md +++ b/docs/install_from_github_release.md @@ -22,7 +22,7 @@ git clone git@github.com:vector-im/element-x-android.git ``` or ```bash -git clone https://github.com/vector-im/element-x-android.gi +git clone https://github.com/vector-im/element-x-android.git ``` You will also need to install [bundletool](https://developer.android.com/studio/command-line/bundletool). On MacOS, you can run the following command: From d7760003cf8d9beec0c64fcc241b230d50cd84ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Aug 2023 17:41:00 +0200 Subject: [PATCH 029/127] Remove the log, was causing a crash. kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Function 'handleEvents' (JVM signature: present$handleEvents(Landroidx/compose/runtime/MutableState;Lkotlin/jvm/internal/Ref$ObjectRef;Lio/element/android/libraries/permissions/api/PermissionsEvents;)V) not resolved in class kotlin.jvm.internal.Intrinsics$Kotlin: no members found at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findFunctionDescriptor(KDeclarationContainerImpl.kt:131) at kotlin.reflect.jvm.internal.KFunctionImpl$descriptor$2.invoke(KFunctionImpl.kt:56) at kotlin.reflect.jvm.internal.KFunctionImpl$descriptor$2.invoke(KFunctionImpl.kt:55) at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93) at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) at kotlin.reflect.jvm.internal.KFunctionImpl.getDescriptor(KFunctionImpl.kt:55) at kotlin.reflect.jvm.internal.KFunctionImpl.toString(KFunctionImpl.kt:185) at kotlin.jvm.internal.FunctionReference.toString(FunctionReference.java:130) at java.lang.String.valueOf(String.java:4092) at java.lang.StringBuilder.append(StringBuilder.java:179) at io.element.android.libraries.permissions.api.PermissionsState.toString at java.lang.String.valueOf(String.java:4092) at java.lang.StringBuilder.append(StringBuilder.java:179) at io.element.android.libraries.permissions.impl.DefaultPermissionsPresenter.present(DefaultPermissionsPresenter.kt:128) --- .../libraries/permissions/impl/DefaultPermissionsPresenter.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt index 50012f01b7..f98ab1fb9d 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt @@ -124,9 +124,7 @@ class DefaultPermissionsPresenter @AssistedInject constructor( permissionAlreadyAsked = isAlreadyAsked, permissionAlreadyDenied = isAlreadyDenied, eventSink = ::handleEvents - ).also { - Timber.tag(loggerTag.value).d("New state: $it") - } + ) } /* From 9b1a30ac8ba84d1410c7b7870610b2207892641a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 07:00:16 +0000 Subject: [PATCH 030/127] Update dependency org.jetbrains.kotlinx:kotlinx-datetime to v0.4.1 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 549ee745ea..a890f4f46c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,7 +36,7 @@ test_core = "1.5.0" #other coil = "2.4.0" -datetime = "0.4.0" +datetime = "0.4.1" serialization_json = "1.6.0" showkase = "1.0.0-beta18" jsoup = "1.16.1" From 3b5fbc659d03f1de7d9f04ad8149b6f3636bc601 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 1 Sep 2023 10:14:35 +0200 Subject: [PATCH 031/127] Fix nightly builds after emojibase integration (#1208) --- app/proguard-rules.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 949ccfce40..e75bf28da3 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -32,3 +32,6 @@ -dontwarn org.conscrypt.** -dontwarn org.bouncycastle.** -dontwarn org.openjsse.** + +# Moshi from EmojiBase +-dontwarn com.google.devtools.ksp.processing.SymbolProcessorProvider From a32e5df1ab7497c2aef4218a32c9d9b9b84834bb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 1 Sep 2023 16:26:39 +0200 Subject: [PATCH 032/127] Developer setting: add entry point to configure the Tracing. Developer setting: add screen to configure log level. Give the custom trace filter to the SDK. --- .../x/initializer/TracingInitializer.kt | 8 +- .../preferences/impl/PreferencesFlowNode.kt | 14 +- .../impl/developer/DeveloperSettingsNode.kt | 10 + .../impl/developer/DeveloperSettingsView.kt | 8 + .../tracing/ConfigureTracingEvents.kt | 25 ++ .../developer/tracing/ConfigureTracingNode.kt | 45 ++++ .../tracing/ConfigureTracingPresenter.kt | 53 ++++ .../tracing/ConfigureTracingState.kt | 25 ++ .../tracing/ConfigureTracingStateProvider.kt | 37 +++ .../developer/tracing/ConfigureTracingView.kt | 247 ++++++++++++++++++ .../tracing/TargetLogLevelMapBuilder.kt | 43 +++ .../tracing/TracingConfigurationStore.kt | 60 +++++ .../tracing/ConfigureTracingPresenterTest.kt | 104 ++++++++ .../InMemoryTracingConfigurationStore.kt | 44 ++++ .../api/tracing/TracingFilterConfiguration.kt | 45 ++-- 15 files changed, 746 insertions(+), 22 deletions(-) create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt create mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt create mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt diff --git a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt index 068d439994..7b93812d35 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt @@ -17,7 +17,10 @@ package io.element.android.x.initializer import android.content.Context +import androidx.preference.PreferenceManager import androidx.startup.Initializer +import io.element.android.features.preferences.impl.developer.tracing.SharedPrefTracingConfigurationStore +import io.element.android.features.preferences.impl.developer.tracing.TargetLogLevelMapBuilder import io.element.android.libraries.architecture.bindings import io.element.android.libraries.matrix.api.tracing.TracingConfiguration import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations @@ -34,8 +37,11 @@ class TracingInitializer : Initializer { val bugReporter = appBindings.bugReporter() Timber.plant(tracingService.createTimberTree()) val tracingConfiguration = if (BuildConfig.DEBUG) { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + val store = SharedPrefTracingConfigurationStore(prefs) + val builder = TargetLogLevelMapBuilder(store) TracingConfiguration( - filterConfiguration = TracingFilterConfigurations.debug, + filterConfiguration = TracingFilterConfigurations.custom(builder.getCurrentMap()), writesToLogcat = true, writesToFilesConfiguration = WriteToFilesConfiguration.Disabled ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index 7e95e0035c..872520105f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -33,6 +33,7 @@ import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.preferences.impl.about.AboutNode import io.element.android.features.preferences.impl.analytics.AnalyticsSettingsNode import io.element.android.features.preferences.impl.developer.DeveloperSettingsNode +import io.element.android.features.preferences.impl.developer.tracing.ConfigureTracingNode import io.element.android.features.preferences.impl.root.PreferencesRootNode import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler @@ -60,6 +61,9 @@ class PreferencesFlowNode @AssistedInject constructor( @Parcelize data object DeveloperSettings : NavTarget + @Parcelize + data object ConfigureTracing : NavTarget + @Parcelize data object AnalyticsSettings : NavTarget @@ -94,7 +98,15 @@ class PreferencesFlowNode @AssistedInject constructor( createNode(buildContext, plugins = listOf(callback)) } NavTarget.DeveloperSettings -> { - createNode(buildContext) + val callback = object : DeveloperSettingsNode.Callback { + override fun openConfigureTracing() { + backstack.push(NavTarget.ConfigureTracing) + } + } + createNode(buildContext, listOf(callback)) + } + NavTarget.ConfigureTracing -> { + createNode(buildContext) } NavTarget.About -> { createNode(buildContext) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt index d5af758dec..96339e7bb4 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt @@ -24,6 +24,7 @@ import com.airbnb.android.showkase.models.Showkase import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.core.plugin.plugins import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode @@ -37,6 +38,14 @@ class DeveloperSettingsNode @AssistedInject constructor( private val presenter: DeveloperSettingsPresenter, ) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun openConfigureTracing() + } + + private fun onOpenConfigureTracing() { + plugins().forEach { it.openConfigureTracing() } + } + @Composable override fun View(modifier: Modifier) { val activity = LocalContext.current as Activity @@ -50,6 +59,7 @@ class DeveloperSettingsNode @AssistedInject constructor( state = state, modifier = modifier, onOpenShowkase = ::openShowkase, + onOpenConfigureTracing = ::onOpenConfigureTracing, onBackPressed = ::navigateUp ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt index 23ea4faf86..684587220b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt @@ -35,6 +35,7 @@ import io.element.android.libraries.ui.strings.CommonStrings fun DeveloperSettingsView( state: DeveloperSettingsState, onOpenShowkase: () -> Unit, + onOpenConfigureTracing: () -> Unit, onBackPressed: () -> Unit, modifier: Modifier = Modifier, ) { @@ -47,6 +48,12 @@ fun DeveloperSettingsView( PreferenceCategory(title = "Feature flags") { FeatureListContent(state) } + PreferenceCategory(title = "Rust SDK") { + PreferenceText( + title = "Configure tracing", + onClick = onOpenConfigureTracing, + ) + } PreferenceCategory(title = "Showkase") { PreferenceText( title = "Open Showkase browser", @@ -109,6 +116,7 @@ private fun ContentToPreview(state: DeveloperSettingsState) { DeveloperSettingsView( state = state, onOpenShowkase = {}, + onOpenConfigureTracing = {}, onBackPressed = {} ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt new file mode 100644 index 0000000000..2d73ea0726 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target + +sealed interface ConfigureTracingEvents { + data class UpdateFilter(val target: Target, val logLevel: LogLevel) : ConfigureTracingEvents + data object ResetFilters : ConfigureTracingEvents +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt new file mode 100644 index 0000000000..7c58058798 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.di.AppScope + +@ContributesNode(AppScope::class) +class ConfigureTracingNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: ConfigureTracingPresenter, +) : Node(buildContext, plugins = plugins) { + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + ConfigureTracingView( + state = state, + onBackPressed = ::navigateUp, + modifier = modifier + ) + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt new file mode 100644 index 0000000000..6ad0529597 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +class ConfigureTracingPresenter @Inject constructor( + private val tracingConfigurationStore: TracingConfigurationStore, + private val targetLogLevelMapBuilder: TargetLogLevelMapBuilder, +) : Presenter { + + @Composable + override fun present(): ConfigureTracingState { + val modifiedMap = remember { mutableStateOf(targetLogLevelMapBuilder.getCurrentMap()) } + + fun handleEvents(event: ConfigureTracingEvents) { + when (event) { + is ConfigureTracingEvents.UpdateFilter -> { + modifiedMap.value = modifiedMap.value.toMutableMap() + .apply { this[event.target] = event.logLevel } + tracingConfigurationStore.storeLogLevel(event.target, event.logLevel) + } + ConfigureTracingEvents.ResetFilters -> { + modifiedMap.value = targetLogLevelMapBuilder.getDefaultMap() + tracingConfigurationStore.reset() + } + } + } + + return ConfigureTracingState( + targetsToLogLevel = modifiedMap.value, + eventSink = ::handleEvents + ) + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt new file mode 100644 index 0000000000..f8433a68fb --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target + +data class ConfigureTracingState( + val targetsToLogLevel: Map, + val eventSink: (ConfigureTracingEvents) -> Unit +) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt new file mode 100644 index 0000000000..06bacb8e74 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target + +open class ConfigureTracingStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aConfigureTracingState(), + ) +} + +fun aConfigureTracingState() = ConfigureTracingState( + targetsToLogLevel = mapOf( + Target.COMMON to LogLevel.INFO, + Target.MATRIX_SDK_FFI to LogLevel.WARN, + Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.ERROR, + ), + eventSink = {} +) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt new file mode 100644 index 0000000000..bf311e7e22 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBars +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.ArrowDropUp +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.outlined.Delete +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.list.ListItemContent +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.theme.aliasScreenTitle +import io.element.android.libraries.designsystem.theme.components.DropdownMenu +import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.IconButton +import io.element.android.libraries.designsystem.theme.components.ListItem +import io.element.android.libraries.designsystem.theme.components.Scaffold +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target +import io.element.android.libraries.theme.ElementTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ConfigureTracingView( + state: ConfigureTracingState, + onBackPressed: () -> Unit, + modifier: Modifier = Modifier, +) { + var showMenu by remember { mutableStateOf(false) } + Scaffold( + modifier = modifier + .fillMaxSize() + .systemBarsPadding() + .imePadding(), + contentWindowInsets = WindowInsets.statusBars, + topBar = { + TopAppBar( + modifier = modifier, + navigationIcon = { + BackButton(onClick = onBackPressed) + }, + title = { + Text( + text = "Configure tracing", + style = ElementTheme.typography.aliasScreenTitle, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + actions = { + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon( + imageVector = Icons.Default.MoreVert, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + DropdownMenuItem( + onClick = { + showMenu = false + state.eventSink.invoke(ConfigureTracingEvents.ResetFilters) + }, + text = { Text("Reset to default") }, + leadingIcon = { + Icon( + Icons.Outlined.Delete, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + ) + } + } + ) + }, + content = { + Column( + modifier = Modifier + .padding(it) + .consumeWindowInsets(it) + .verticalScroll(state = rememberScrollState()) + ) { + CrateListContent(state) + ListItem( + headlineContent = { + Text( + text = "Kill and restart the app for the change to take effect.", + style = ElementTheme.typography.fontHeadingSmMedium, + ) + }, + ) + } + } + ) +} + +@Composable +fun CrateListContent( + state: ConfigureTracingState, + modifier: Modifier = Modifier +) { + fun onLogLevelChange(target: Target, logLevel: LogLevel) { + state.eventSink(ConfigureTracingEvents.UpdateFilter(target, logLevel)) + } + + TargetAndLogLevelListView( + modifier = modifier, + data = state.targetsToLogLevel, + onLogLevelChange = ::onLogLevelChange, + ) +} + +@Composable +private fun TargetAndLogLevelListView( + data: Map, + onLogLevelChange: (Target, LogLevel) -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + ) { + data.forEach { item -> + fun onLogLevelChange(logLevel: LogLevel) { + onLogLevelChange(item.key, logLevel) + } + + TargetAndLogLevelView( + target = item.key, + logLevel = item.value, + onLogLevelChange = ::onLogLevelChange + ) + } + } +} + +@Composable +fun TargetAndLogLevelView( + target: Target, + logLevel: LogLevel, + onLogLevelChange: (LogLevel) -> Unit, + modifier: Modifier = Modifier +) { + ListItem( + modifier = modifier, + headlineContent = { Text(text = target.filter.takeIf { it.isNotEmpty() } ?: "(common)") }, + trailingContent = ListItemContent.Custom { + LogLevelDropdownMenu( + logLevel = logLevel, + onLogLevelChange = onLogLevelChange, + ) + }, + ) +} + +@Composable +fun LogLevelDropdownMenu( + logLevel: LogLevel, + onLogLevelChange: (LogLevel) -> Unit, + modifier: Modifier = Modifier, +) { + var expanded by remember { mutableStateOf(false) } + DropdownMenuItem( + modifier = modifier.widthIn(max = 120.dp), + text = { Text(text = logLevel.filter) }, + onClick = { expanded = !expanded }, + trailingIcon = { + if (expanded) { + Icon(Icons.Default.ArrowDropUp, contentDescription = null) + } else { + Icon(Icons.Default.ArrowDropDown, contentDescription = null) + } + }, + ) + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + ) { + LogLevel.values().forEach { logLevel -> + DropdownMenuItem( + text = { + Text(text = logLevel.filter) + }, + onClick = { + expanded = false + onLogLevelChange(logLevel) + } + ) + } + } +} + +@DayNightPreviews +@Composable +internal fun ConfigureTracingViewPreview( + @PreviewParameter(ConfigureTracingStateProvider::class) state: ConfigureTracingState +) = ElementPreview { + ConfigureTracingView( + state = state, + onBackPressed = {}, + ) +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt new file mode 100644 index 0000000000..c70d573430 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target +import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations +import javax.inject.Inject + +class TargetLogLevelMapBuilder @Inject constructor( + private val tracingConfigurationStore: TracingConfigurationStore, +) { + private val defaultConfig = TracingFilterConfigurations.debug + + fun getDefaultMap(): Map { + return Target.entries.associateWith { target -> + defaultConfig.getLogLevel(target) + ?: LogLevel.INFO + } + } + + fun getCurrentMap(): Map { + return Target.entries.associateWith { target -> + tracingConfigurationStore.getLogLevel(target) + ?: defaultConfig.getLogLevel(target) + ?: LogLevel.INFO + } + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt new file mode 100644 index 0000000000..582231eb50 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.DefaultPreferences +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target +import javax.inject.Inject + +interface TracingConfigurationStore { + fun getLogLevel(target: Target): LogLevel? + fun storeLogLevel(target: Target, logLevel: LogLevel) + fun reset() +} + +@ContributesBinding(AppScope::class) +class SharedPrefTracingConfigurationStore @Inject constructor( + @DefaultPreferences private val sharedPreferences: SharedPreferences +) : TracingConfigurationStore { + override fun getLogLevel(target: Target): LogLevel? { + return sharedPreferences.getString("$KEY_PREFIX${target.name}", null) + ?.let { LogLevel.valueOf(it) } + } + + override fun storeLogLevel(target: Target, logLevel: LogLevel) { + sharedPreferences.edit { + putString("$KEY_PREFIX${target.name}", logLevel.name) + } + } + + override fun reset() { + sharedPreferences.edit { + sharedPreferences.all.keys.filter { it.startsWith(KEY_PREFIX) }.forEach { + remove(it) + } + } + } + + companion object { + private const val KEY_PREFIX = "tracing_log_level_" + } +} diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt new file mode 100644 index 0000000000..979713427e --- /dev/null +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import app.cash.molecule.RecompositionMode +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target +import io.element.android.tests.testutils.waitForPredicate +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class ConfigureTracingPresenterTest { + @Test + fun `present - initial state`() = runTest { + val store = InMemoryTracingConfigurationStore() + val presenter = ConfigureTracingPresenter( + store, + TargetLogLevelMapBuilder(store), + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.targetsToLogLevel).isNotEmpty() + assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) + } + } + + @Test + fun `present - store is taken into account`() = runTest { + val store = InMemoryTracingConfigurationStore() + store.givenLogLevel(LogLevel.ERROR) + val presenter = ConfigureTracingPresenter( + store, + TargetLogLevelMapBuilder(store), + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.targetsToLogLevel).isNotEmpty() + assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.ERROR) + } + } + + @Test + fun `present - change a value`() = runTest { + val store = InMemoryTracingConfigurationStore() + val presenter = ConfigureTracingPresenter( + store, + TargetLogLevelMapBuilder(store), + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) + initialState.eventSink.invoke(ConfigureTracingEvents.UpdateFilter(Target.MATRIX_SDK_CRYPTO, LogLevel.WARN)) + val finalState = awaitItem() + assertThat(finalState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.WARN) + waitForPredicate { store.hasStoreLogLevelBeenCalled } + } + } + + @Test + fun `present - reset`() = runTest { + val store = InMemoryTracingConfigurationStore() + val presenter = ConfigureTracingPresenter( + store, + TargetLogLevelMapBuilder(store), + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) + initialState.eventSink.invoke(ConfigureTracingEvents.UpdateFilter(Target.MATRIX_SDK_CRYPTO, LogLevel.WARN)) + val finalState = awaitItem() + assertThat(finalState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.WARN) + waitForPredicate { store.hasStoreLogLevelBeenCalled } + finalState.eventSink.invoke(ConfigureTracingEvents.ResetFilters) + val resetState = awaitItem() + assertThat(resetState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) + waitForPredicate { store.hasResetBeenCalled } + } + } +} diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt new file mode 100644 index 0000000000..1d17a1227b --- /dev/null +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl.developer.tracing + +import io.element.android.libraries.matrix.api.tracing.LogLevel +import io.element.android.libraries.matrix.api.tracing.Target + +class InMemoryTracingConfigurationStore : TracingConfigurationStore { + var hasResetBeenCalled = false + private set + var hasStoreLogLevelBeenCalled = false + private set + private var logLevel: LogLevel? = null + + fun givenLogLevel(logLevel: LogLevel?) { + this.logLevel = logLevel + } + + override fun getLogLevel(target: Target): LogLevel? { + return logLevel + } + + override fun storeLogLevel(target: Target, logLevel: LogLevel) { + hasStoreLogLevelBeenCalled = true + } + + override fun reset() { + hasResetBeenCalled = true + } +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt index 596b611296..d34911644e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt @@ -21,22 +21,27 @@ data class TracingFilterConfiguration( ) { // Order should matters - private val targetsToLogLevel: MutableMap = mutableMapOf( - Target.COMMON to LogLevel.Info, - Target.HYPER to LogLevel.Warn, - Target.MATRIX_SDK_CRYPTO to LogLevel.Debug, - Target.MATRIX_SDK_HTTP_CLIENT to LogLevel.Debug, - Target.MATRIX_SDK_SLIDING_SYNC to LogLevel.Trace, - Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.Trace, - Target.MATRIX_SDK_UI_TIMELINE to LogLevel.Info, + private val targetsToLogLevel: Map = mapOf( + Target.COMMON to LogLevel.INFO, + Target.HYPER to LogLevel.WARN, + Target.MATRIX_SDK_CRYPTO to LogLevel.DEBUG, + Target.MATRIX_SDK_HTTP_CLIENT to LogLevel.DEBUG, + Target.MATRIX_SDK_SLIDING_SYNC to LogLevel.TRACE, + Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.TRACE, + Target.MATRIX_SDK_UI_TIMELINE to LogLevel.INFO, ) + fun getLogLevel(target: Target): LogLevel? { + return overrides[target] ?: targetsToLogLevel[target] + } + val filter: String get() { + val fullMap = targetsToLogLevel.toMutableMap() overrides.forEach { (target, logLevel) -> - targetsToLogLevel[target] = logLevel + fullMap[target] = logLevel } - return targetsToLogLevel.map { + return fullMap.map { if (it.key.filter.isEmpty()) { it.value.filter } else { @@ -59,25 +64,25 @@ enum class Target(open val filter: String) { MATRIX_SDK_UI_TIMELINE("matrix_sdk_ui::timeline"), } -sealed class LogLevel(val filter: String) { - data object Warn : LogLevel("warn") - data object Trace : LogLevel("trace") - data object Info : LogLevel("info") - data object Debug : LogLevel("debug") - data object Error : LogLevel("error") +enum class LogLevel(open val filter: String) { + ERROR("error"), + WARN("warn"), + INFO("info"), + DEBUG("debug"), + TRACE("trace"), } object TracingFilterConfigurations { val release = TracingFilterConfiguration( overrides = mapOf( - Target.COMMON to LogLevel.Info, - Target.ELEMENT to LogLevel.Debug + Target.COMMON to LogLevel.INFO, + Target.ELEMENT to LogLevel.DEBUG ), ) val debug = TracingFilterConfiguration( overrides = mapOf( - Target.COMMON to LogLevel.Info, - Target.ELEMENT to LogLevel.Trace + Target.COMMON to LogLevel.INFO, + Target.ELEMENT to LogLevel.TRACE ) ) From 55f3b935c36663af084f3c2bfb59575ea258d150 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 1 Sep 2023 14:39:03 +0000 Subject: [PATCH 033/127] Update screenshots --- ...null_ConfigureTracingView-D-0_1_null_0,NEXUS_5,1.0,en].png | 3 +++ ...null_ConfigureTracingView-N-0_2_null_0,NEXUS_5,1.0,en].png | 3 +++ ...ull_DeveloperSettingsViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ull_DeveloperSettingsViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ll_DeveloperSettingsViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ll_DeveloperSettingsViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- 6 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-D-0_1_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-N-0_2_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-D-0_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-D-0_1_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..acf8d934bb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-D-0_1_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e55b03652dc0149cdc2623fa81b678a68a8080f57043c1f71cc99565e44c98e0 +size 35025 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-N-0_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-N-0_2_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2a8c0680e3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer.tracing_null_ConfigureTracingView-N-0_2_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e38e363ecdec4e70699204a83a01ac3e4a840f20f1ebc84bd014b49e0e52c77b +size 31291 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_0,NEXUS_5,1.0,en].png index 29125d81e3..9dbdf12053 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ecff1b486e8aca39a5b7c81139e1132829d9baded8888977eeaa88fd1a6e5f2 -size 49665 +oid sha256:e6b1bfbd1d8c29347433e0c8a1037ea219b0935f9a74196f4c96952d144417e9 +size 48845 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_1,NEXUS_5,1.0,en].png index 29125d81e3..9dbdf12053 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ecff1b486e8aca39a5b7c81139e1132829d9baded8888977eeaa88fd1a6e5f2 -size 49665 +oid sha256:e6b1bfbd1d8c29347433e0c8a1037ea219b0935f9a74196f4c96952d144417e9 +size 48845 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_0,NEXUS_5,1.0,en].png index be5e358d49..c1ebd00c8e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a2123c483c9609b3341c762907e1eb5f50052faa3731454ff0953cdb862809c -size 54357 +oid sha256:6814348aebbbb561fe42ae5e7c5ae9bec77cc7838b41adbc5158954b338fb0d1 +size 53755 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_1,NEXUS_5,1.0,en].png index be5e358d49..c1ebd00c8e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.developer_null_DeveloperSettingsViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a2123c483c9609b3341c762907e1eb5f50052faa3731454ff0953cdb862809c -size 54357 +oid sha256:6814348aebbbb561fe42ae5e7c5ae9bec77cc7838b41adbc5158954b338fb0d1 +size 53755 From 2cb82bd97b33505b7d4faac94163174dc41f9cf2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 16:42:27 +0200 Subject: [PATCH 034/127] Update plugin sonarqube to v4.3.1.3277 (#1210) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a890f4f46c..99e61a7ee4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -203,6 +203,6 @@ dependencygraph = { id = "com.savvasdalkitsis.module-dependency-graph", version. dependencycheck = { id = "org.owasp.dependencycheck", version.ref = "dependencycheck" } dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyanalysis" } paparazzi = "app.cash.paparazzi:1.3.1" -sonarqube = "org.sonarqube:4.2.1.3168" +sonarqube = "org.sonarqube:4.3.1.3277" kover = "org.jetbrains.kotlinx.kover:0.6.1" sqldelight = { id = "com.squareup.sqldelight", version.ref = "sqldelight" } From 73b5ce5fe36ddea3ebc536510f14ccfaaf0e88ef Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 1 Sep 2023 17:39:46 +0200 Subject: [PATCH 035/127] Fix detekted issues. --- .../tracing/ConfigureTracingPresenter.kt | 3 +- .../tracing/ConfigureTracingState.kt | 3 +- .../tracing/ConfigureTracingStateProvider.kt | 3 +- .../developer/tracing/ConfigureTracingView.kt | 57 ++++++++++--------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt index 6ad0529597..b0d2243c70 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import io.element.android.libraries.architecture.Presenter +import kotlinx.collections.immutable.toImmutableMap import javax.inject.Inject class ConfigureTracingPresenter @Inject constructor( @@ -46,7 +47,7 @@ class ConfigureTracingPresenter @Inject constructor( } return ConfigureTracingState( - targetsToLogLevel = modifiedMap.value, + targetsToLogLevel = modifiedMap.value.toImmutableMap(), eventSink = ::handleEvents ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt index f8433a68fb..bc36a6ede3 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt @@ -18,8 +18,9 @@ package io.element.android.features.preferences.impl.developer.tracing import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.matrix.api.tracing.Target +import kotlinx.collections.immutable.ImmutableMap data class ConfigureTracingState( - val targetsToLogLevel: Map, + val targetsToLogLevel: ImmutableMap, val eventSink: (ConfigureTracingEvents) -> Unit ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt index 06bacb8e74..fe2cfa44a9 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt @@ -19,6 +19,7 @@ package io.element.android.features.preferences.impl.developer.tracing import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.matrix.api.tracing.Target +import kotlinx.collections.immutable.persistentMapOf open class ConfigureTracingStateProvider : PreviewParameterProvider { override val values: Sequence @@ -28,7 +29,7 @@ open class ConfigureTracingStateProvider : PreviewParameterProvider, + data: ImmutableMap, onLogLevelChange: (Target, LogLevel) -> Unit, modifier: Modifier = Modifier, ) { @@ -205,32 +206,34 @@ fun LogLevelDropdownMenu( modifier: Modifier = Modifier, ) { var expanded by remember { mutableStateOf(false) } - DropdownMenuItem( - modifier = modifier.widthIn(max = 120.dp), - text = { Text(text = logLevel.filter) }, - onClick = { expanded = !expanded }, - trailingIcon = { - if (expanded) { - Icon(Icons.Default.ArrowDropUp, contentDescription = null) - } else { - Icon(Icons.Default.ArrowDropDown, contentDescription = null) - } - }, - ) - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - ) { - LogLevel.values().forEach { logLevel -> - DropdownMenuItem( - text = { - Text(text = logLevel.filter) - }, - onClick = { - expanded = false - onLogLevelChange(logLevel) + Box(modifier = modifier) { + DropdownMenuItem( + modifier = Modifier.widthIn(max = 120.dp), + text = { Text(text = logLevel.filter) }, + onClick = { expanded = !expanded }, + trailingIcon = { + if (expanded) { + Icon(Icons.Default.ArrowDropUp, contentDescription = null) + } else { + Icon(Icons.Default.ArrowDropDown, contentDescription = null) } - ) + }, + ) + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + ) { + LogLevel.values().forEach { logLevel -> + DropdownMenuItem( + text = { + Text(text = logLevel.filter) + }, + onClick = { + expanded = false + onLogLevelChange(logLevel) + } + ) + } } } } From bf3d803db9e338e203cfefa311c9f331c25c5f32 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:15:14 +0000 Subject: [PATCH 036/127] Update dependency io.element.android:emojibase-bindings to v1.1.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 99e61a7ee4..841e53b75d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -167,7 +167,7 @@ sentry = "io.sentry:sentry-android:6.28.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8" # Emojibase -matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.0.5" +matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.1.3" # Di inject = "javax.inject:javax.inject:1" From cd88be67aeab8c31f5ea1adbe480ca007c88aa0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 4 Sep 2023 11:41:22 +0200 Subject: [PATCH 037/127] Revert exception in proguard --- app/proguard-rules.pro | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index e75bf28da3..949ccfce40 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -32,6 +32,3 @@ -dontwarn org.conscrypt.** -dontwarn org.bouncycastle.** -dontwarn org.openjsse.** - -# Moshi from EmojiBase --dontwarn com.google.devtools.ksp.processing.SymbolProcessorProvider From 82f6f358a7987e46a38189e78f96455b94f2b6ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 12:50:37 +0200 Subject: [PATCH 038/127] Ensure the sync is started when receiving a Push, to ensure that the encryption loop is running. Fixes notification with endecrypted content (#1178) --- .../android/appnav/LoggedInFlowNode.kt | 5 ++- .../matrix/api/sync/StartSyncReason.kt | 25 ++++++++++++ .../libraries/matrix/api/sync/SyncService.kt | 4 +- .../matrix/impl/sync/RustSyncService.kt | 40 ++++++++++++++----- .../matrix/test/sync/FakeSyncService.kt | 5 ++- .../notifications/NotifiableEventResolver.kt | 12 ++++++ 6 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 5006218bda..c3a79acb81 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -60,6 +60,7 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.MAIN_SPACE import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.push.api.notifications.NotificationDrawerManager import io.element.android.services.appnavstate.api.AppNavigationStateService @@ -124,7 +125,7 @@ class LoggedInFlowNode @AssistedInject constructor( onStop = { //Counterpart startSync is done in observeSyncStateAndNetworkStatus method. coroutineScope.launch { - syncService.stopSync() + syncService.stopSync(StartSyncReason.AppInForeground) } }, onDestroy = { @@ -150,7 +151,7 @@ class LoggedInFlowNode @AssistedInject constructor( .collect { (syncState, networkStatus) -> Timber.d("Sync state: $syncState, network status: $networkStatus") if (syncState != SyncState.Running && networkStatus == NetworkStatus.Online) { - syncService.startSync() + syncService.startSync(StartSyncReason.AppInForeground) } } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt new file mode 100644 index 0000000000..4a6b44949e --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.api.sync + +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.RoomId + +sealed interface StartSyncReason { + data object AppInForeground : StartSyncReason + data class Notification(val roomId: RoomId, val eventId: EventId) : StartSyncReason +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt index 994b35edc4..03a8402b32 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt @@ -22,12 +22,12 @@ interface SyncService { /** * Tries to start the sync. If already syncing it has no effect. */ - suspend fun startSync(): Result + suspend fun startSync(reason: StartSyncReason): Result /** * Tries to stop the sync. If service is not syncing it has no effect. */ - suspend fun stopSync(): Result + suspend fun stopSync(reason: StartSyncReason): Result /** * Flow of [SyncState]. Will be updated as soon as the current [SyncState] changes. diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt index 932da42afb..b0a9fb31ec 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt @@ -16,6 +16,7 @@ package io.element.android.libraries.matrix.impl.sync +import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import kotlinx.coroutines.CoroutineScope @@ -25,6 +26,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import org.matrix.rustcomponents.sdk.SyncServiceInterface import org.matrix.rustcomponents.sdk.SyncServiceState import timber.log.Timber @@ -33,19 +36,36 @@ class RustSyncService( private val innerSyncService: SyncServiceInterface, sessionCoroutineScope: CoroutineScope ) : SyncService { + private val mutex = Mutex() + private val startSyncReasonSet = mutableSetOf() - override suspend fun startSync() = runCatching { - Timber.i("Start sync") - innerSyncService.start() - }.onFailure { - Timber.d("Start sync failed: $it") + override suspend fun startSync(reason: StartSyncReason): Result { + return mutex.withLock { + startSyncReasonSet.add(reason) + runCatching { + Timber.d("Start sync") + innerSyncService.start() + }.onFailure { + Timber.e("Start sync failed: $it") + } + } } - override suspend fun stopSync() = runCatching { - Timber.i("Stop sync") - innerSyncService.stop() - }.onFailure { - Timber.d("Stop sync failed: $it") + override suspend fun stopSync(reason: StartSyncReason): Result { + return mutex.withLock { + startSyncReasonSet.remove(reason) + if (startSyncReasonSet.isEmpty()) { + runCatching { + Timber.d("Stop sync") + innerSyncService.stop() + }.onFailure { + Timber.e("Stop sync failed: $it") + } + } else { + Timber.d("Stop sync skipped, still $startSyncReasonSet") + Result.success(Unit) + } + } } override val syncState: StateFlow = diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt index 4e618deb9a..87a54a2571 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt @@ -16,6 +16,7 @@ package io.element.android.libraries.matrix.test.sync +import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import kotlinx.coroutines.flow.MutableStateFlow @@ -29,12 +30,12 @@ class FakeSyncService : SyncService { syncStateFlow.value = SyncState.Error } - override suspend fun startSync(): Result { + override suspend fun startSync(reason: StartSyncReason): Result { syncStateFlow.value = SyncState.Running return Result.success(Unit) } - override suspend fun stopSync(): Result { + override suspend fun stopSync(reason: StartSyncReason): Result { syncStateFlow.value = SyncState.Terminated return Result.success(Unit) } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt index e5af7785db..ce3d09f013 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt @@ -26,6 +26,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -44,6 +45,7 @@ import io.element.android.libraries.push.impl.notifications.model.NotifiableMess import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.toolbox.api.strings.StringProvider import io.element.android.services.toolbox.api.systemclock.SystemClock +import kotlinx.coroutines.delay import timber.log.Timber import javax.inject.Inject @@ -65,6 +67,14 @@ class NotifiableEventResolver @Inject constructor( // Restore session val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null val notificationService = client.notificationService() + + // Restart the sync service to ensure that the crypto sync handle the toDevice Events. + client.syncService().startSync(StartSyncReason.Notification(roomId, eventId)) + // Wait for toDevice Event to be processed + // FIXME This delay can be removed when the Rust SDK will handle internal retry to get + // clear notification content. + delay(300) + val notificationData = notificationService.getNotification( userId = sessionId, roomId = roomId, @@ -73,6 +83,8 @@ class NotifiableEventResolver @Inject constructor( Timber.tag(loggerTag.value).e(it, "Unable to resolve event: $eventId.") }.getOrNull() + client.syncService().stopSync(StartSyncReason.Notification(roomId, eventId)) + // TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event return notificationData?.asNotifiableEvent(sessionId) } From 948844a901b5fef198cbbf857cfab957ad7fa350 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 12:53:24 +0200 Subject: [PATCH 039/127] changelog. --- changelog.d/1178.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1178.bugfix diff --git a/changelog.d/1178.bugfix b/changelog.d/1178.bugfix new file mode 100644 index 0000000000..2268ca8561 --- /dev/null +++ b/changelog.d/1178.bugfix @@ -0,0 +1 @@ +Ensure notification for Event from encrypted room get decrypted content. From 4766e0cc8f7b897a39284087da8dad5c4f267a85 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 14:23:03 +0200 Subject: [PATCH 040/127] Fix compilation of sample app. --- .../io/element/android/samples/minimal/RoomListScreen.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt index faaccc9b8e..bb90425a48 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt @@ -39,6 +39,7 @@ import io.element.android.libraries.eventformatter.impl.StateContentFormatter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomMembershipObserver +import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.services.toolbox.impl.strings.AndroidStringProvider import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -109,12 +110,12 @@ class RoomListScreen( DisposableEffect(Unit) { Timber.w("Start sync!") runBlocking { - matrixClient.syncService().startSync() + matrixClient.syncService().startSync(StartSyncReason.AppInForeground) } onDispose { Timber.w("Stop sync!") runBlocking { - matrixClient.syncService().stopSync() + matrixClient.syncService().stopSync(StartSyncReason.AppInForeground) } } } From ff3fd793ff6c899d40424c6ebfbd6af55cbca3d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:50:03 +0000 Subject: [PATCH 041/127] Update actions/checkout action to v4 --- .github/workflows/build.yml | 2 +- .github/workflows/danger.yml | 2 +- .github/workflows/gradle-wrapper-update.yml | 2 +- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/maestro.yml | 2 +- .github/workflows/nightly.yml | 2 +- .github/workflows/nightlyReports.yml | 2 +- .github/workflows/quality.yml | 4 ++-- .github/workflows/release.yml | 2 +- .github/workflows/sonar.yml | 2 +- .github/workflows/sync-localazy.yml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1df2119bf9..709d7ccd58 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: group: ${{ github.ref == 'refs/heads/develop' && format('build-develop-{0}-{1}', matrix.variant, github.sha) || format('build-{0}-{1}', matrix.variant, github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 8551cb44c0..e2aa8e1266 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest name: Danger main check steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - run: | npm install --save-dev @babel/plugin-transform-flow-strip-types - name: Danger diff --git a/.github/workflows/gradle-wrapper-update.yml b/.github/workflows/gradle-wrapper-update.yml index 33a12d3c54..f9e998b1a0 100644 --- a/.github/workflows/gradle-wrapper-update.yml +++ b/.github/workflows/gradle-wrapper-update.yml @@ -8,7 +8,7 @@ jobs: update-gradle-wrapper: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Update Gradle Wrapper uses: gradle-update/update-gradle-wrapper-action@v1 # Skip in forks diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 271c5399f6..bf1ca46700 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -11,5 +11,5 @@ jobs: runs-on: ubuntu-latest # No concurrency required, this is a prerequisite to other actions and should run every time. steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - uses: gradle/wrapper-validation-action@v1 diff --git a/.github/workflows/maestro.yml b/.github/workflows/maestro.yml index 46ee84896f..6f6edd9a31 100644 --- a/.github/workflows/maestro.yml +++ b/.github/workflows/maestro.yml @@ -24,7 +24,7 @@ jobs: group: ${{ format('maestro-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 85c9ed1422..e2b027aebe 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository == 'vector-im/element-x-android' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index 65f3cbb53c..c1d73117b9 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -55,7 +55,7 @@ jobs: name: Dependency analysis runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 9c0aac7aef..fad3b13cb2 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -17,7 +17,7 @@ jobs: name: Search for forbidden patterns runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Run code quality check suite run: ./tools/check/check_code_quality.sh @@ -29,7 +29,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-develop-{0}', github.sha) || format('check-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e535a1467..b701b7d69e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: group: ${{ github.ref == 'refs/head/main' && format('build-release-main-{0}', github.sha) }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 42846c2cd5..3a37e9ead1 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -21,7 +21,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('sonar-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('sonar-develop-{0}', github.sha) || format('sonar-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index 3d63f8b542..e4242aa634 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -11,7 +11,7 @@ jobs: # Skip in forks if: github.repository == 'vector-im/element-x-android' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: From a0ff636d0b9f487b07bd108f36b2ae6002bb864a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 15:55:38 +0200 Subject: [PATCH 042/127] Exclude some groups related to analytics to be included. #1191 --- changelog.d/1191.misc | 1 + libraries/pushproviders/firebase/build.gradle.kts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1191.misc diff --git a/changelog.d/1191.misc b/changelog.d/1191.misc new file mode 100644 index 0000000000..0b91374f77 --- /dev/null +++ b/changelog.d/1191.misc @@ -0,0 +1 @@ +Exclude some groups related to analytics to be included. diff --git a/libraries/pushproviders/firebase/build.gradle.kts b/libraries/pushproviders/firebase/build.gradle.kts index 96faa3197b..cdb55b1119 100644 --- a/libraries/pushproviders/firebase/build.gradle.kts +++ b/libraries/pushproviders/firebase/build.gradle.kts @@ -38,7 +38,11 @@ dependencies { implementation(projects.libraries.pushproviders.api) api(platform(libs.google.firebase.bom)) - api("com.google.firebase:firebase-messaging-ktx") + api("com.google.firebase:firebase-messaging-ktx") { + exclude(group = "com.google.firebase", module = "firebase-core") + exclude(group = "com.google.firebase", module = "firebase-analytics") + exclude(group = "com.google.firebase", module = "firebase-measurement-connector") + } testImplementation(libs.test.junit) testImplementation(libs.test.truth) From e15430e9b666b2739fc215315fe4037dd8f3101d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 16:13:27 +0200 Subject: [PATCH 043/127] Changelog for version 0.1.6 --- CHANGES.md | 23 +++++++++++++++++++++++ changelog.d/1135.bugfix | 1 - changelog.d/1143.feature | 1 - changelog.d/1168.bugfix | 1 - changelog.d/1177.bugfix | 1 - changelog.d/1178.bugfix | 1 - changelog.d/1187.misc | 1 - changelog.d/1196.feature | 1 - changelog.d/1198.bugfix | 1 - changelog.d/1995.bugfix | 1 - changelog.d/928.bugfix | 1 - 11 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 changelog.d/1135.bugfix delete mode 100644 changelog.d/1143.feature delete mode 100644 changelog.d/1168.bugfix delete mode 100644 changelog.d/1177.bugfix delete mode 100644 changelog.d/1178.bugfix delete mode 100644 changelog.d/1187.misc delete mode 100644 changelog.d/1196.feature delete mode 100644 changelog.d/1198.bugfix delete mode 100644 changelog.d/1995.bugfix delete mode 100644 changelog.d/928.bugfix diff --git a/CHANGES.md b/CHANGES.md index c9e3ad2d33..4cca4c7212 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,26 @@ +Changes in Element X v0.1.6 (2023-09-04) +======================================== + +Features ✨ +---------- + - Enable the Polls feature. Allows to create, view, vote and end polls. ([#1196](https://github.com/vector-im/element-x-android/issues/1196)) +- Create poll. ([#1143](https://github.com/vector-im/element-x-android/issues/1143)) + +Bugfixes 🐛 +---------- +- Ensure notification for Event from encrypted room get decrypted content. ([#1178](https://github.com/vector-im/element-x-android/issues/1178)) + - Make sure Snackbars are only displayed once. ([#928](https://github.com/vector-im/element-x-android/issues/928)) + - Fix the orientation of sent images. ([#1135](https://github.com/vector-im/element-x-android/issues/1135)) + - Bug reporter crashes when 'send logs' is disabled. ([#1168](https://github.com/vector-im/element-x-android/issues/1168)) + - Add missing link to the terms on the analytics setting screen. ([#1177](https://github.com/vector-im/element-x-android/issues/1177)) + - Re-enable `SyncService.withEncryptionSync` to improve decryption of notifications. ([#1198](https://github.com/vector-im/element-x-android/issues/1198)) + - Crash with `aspectRatio` modifier when `Float.NaN` was used as input. ([#1995](https://github.com/vector-im/element-x-android/issues/1995)) + +Other changes +------------- + - Remove unnecessary year in copyright mention. ([#1187](https://github.com/vector-im/element-x-android/issues/1187)) + + Changes in Element X v0.1.5 (2023-08-28) ======================================== diff --git a/changelog.d/1135.bugfix b/changelog.d/1135.bugfix deleted file mode 100644 index 2b963c7732..0000000000 --- a/changelog.d/1135.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix the orientation of sent images. diff --git a/changelog.d/1143.feature b/changelog.d/1143.feature deleted file mode 100644 index 84a86f4f25..0000000000 --- a/changelog.d/1143.feature +++ /dev/null @@ -1 +0,0 @@ -Create poll. diff --git a/changelog.d/1168.bugfix b/changelog.d/1168.bugfix deleted file mode 100644 index f7f959ac0a..0000000000 --- a/changelog.d/1168.bugfix +++ /dev/null @@ -1 +0,0 @@ -Bug reporter crashes when 'send logs' is disabled. diff --git a/changelog.d/1177.bugfix b/changelog.d/1177.bugfix deleted file mode 100644 index edbf2e9006..0000000000 --- a/changelog.d/1177.bugfix +++ /dev/null @@ -1 +0,0 @@ -Add missing link to the terms on the analytics setting screen. diff --git a/changelog.d/1178.bugfix b/changelog.d/1178.bugfix deleted file mode 100644 index 2268ca8561..0000000000 --- a/changelog.d/1178.bugfix +++ /dev/null @@ -1 +0,0 @@ -Ensure notification for Event from encrypted room get decrypted content. diff --git a/changelog.d/1187.misc b/changelog.d/1187.misc deleted file mode 100644 index 301e3a6fc4..0000000000 --- a/changelog.d/1187.misc +++ /dev/null @@ -1 +0,0 @@ -Remove unnecessary year in copyright mention. diff --git a/changelog.d/1196.feature b/changelog.d/1196.feature deleted file mode 100644 index fe1eb354f9..0000000000 --- a/changelog.d/1196.feature +++ /dev/null @@ -1 +0,0 @@ -Enable the Polls feature. Allows to create, view, vote and end polls. diff --git a/changelog.d/1198.bugfix b/changelog.d/1198.bugfix deleted file mode 100644 index 6ef69c4eff..0000000000 --- a/changelog.d/1198.bugfix +++ /dev/null @@ -1 +0,0 @@ -Re-enable `SyncService.withEncryptionSync` to improve decryption of notifications. diff --git a/changelog.d/1995.bugfix b/changelog.d/1995.bugfix deleted file mode 100644 index acec25add0..0000000000 --- a/changelog.d/1995.bugfix +++ /dev/null @@ -1 +0,0 @@ -Crash with `aspectRatio` modifier when `Float.NaN` was used as input. diff --git a/changelog.d/928.bugfix b/changelog.d/928.bugfix deleted file mode 100644 index 98a4cd34e0..0000000000 --- a/changelog.d/928.bugfix +++ /dev/null @@ -1 +0,0 @@ -Make sure Snackbars are only displayed once. From fa8979126961c28947ac000ff72ddb1e210370f5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 16:13:48 +0200 Subject: [PATCH 044/127] Adding fastlane file for version 0.1.6 --- fastlane/metadata/android/en-US/changelogs/40001060.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40001060.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40001060.txt b/fastlane/metadata/android/en-US/changelogs/40001060.txt new file mode 100644 index 0000000000..ff4f86ce7e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40001060.txt @@ -0,0 +1,2 @@ +Main changes in this version: bugfixes. +Full changelog: https://github.com/vector-im/element-x-android/releases From fe9c7b3d432f7ae32b053b2e60cfcf75476ed8dc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Sep 2023 16:14:45 +0200 Subject: [PATCH 045/127] version++ --- plugins/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index 0e9d807014..98ebdc5f6f 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -56,7 +56,7 @@ private const val versionMinor = 1 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -private const val versionPatch = 6 +private const val versionPatch = 7 object Versions { val versionCode = 4_000_000 + versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch From 74b2ddebfd04f35dd765aa46a45655f11419dde9 Mon Sep 17 00:00:00 2001 From: jmartinesp Date: Tue, 5 Sep 2023 06:37:36 +0000 Subject: [PATCH 046/127] Sync Strings from Localazy --- .../src/main/res/values-cs/translations.xml | 2 +- .../src/main/res/values-ro/translations.xml | 11 +++ .../src/main/res/values-ro/translations.xml | 5 +- .../src/main/res/values-ru/translations.xml | 1 + .../src/main/res/values-cs/translations.xml | 5 -- .../src/main/res/values-fr/translations.xml | 4 -- .../src/main/res/values-ro/translations.xml | 20 ++++++ .../src/main/res/values-ru/translations.xml | 5 -- .../src/main/res/values-sk/translations.xml | 5 -- .../main/res/values-zh-rTW/translations.xml | 3 - .../impl/src/main/res/values/localazy.xml | 4 +- .../src/main/res/values-cs/translations.xml | 10 +++ .../src/main/res/values-ro/translations.xml | 12 ++++ .../src/main/res/values-ru/translations.xml | 10 +++ .../impl/src/main/res/values/localazy.xml | 3 +- .../src/main/res/values-ro/translations.xml | 3 +- .../src/main/res/values-ro/translations.xml | 7 +- .../src/main/res/values-ro/translations.xml | 6 +- .../src/main/res/values-cs/translations.xml | 14 ---- .../src/main/res/values-de/translations.xml | 14 ---- .../src/main/res/values-es/translations.xml | 17 ----- .../src/main/res/values-fr/translations.xml | 17 ----- .../src/main/res/values-it/translations.xml | 17 ----- .../src/main/res/values-ro/translations.xml | 15 +--- .../src/main/res/values-ru/translations.xml | 14 ---- .../src/main/res/values-sk/translations.xml | 14 ---- .../main/res/values-zh-rTW/translations.xml | 13 ---- .../src/main/res/values/localazy.xml | 14 ---- .../src/main/res/values-cs/translations.xml | 15 ++++ .../src/main/res/values-de/translations.xml | 14 ++++ .../src/main/res/values-es/translations.xml | 14 ++++ .../src/main/res/values-fr/translations.xml | 14 ++++ .../src/main/res/values-it/translations.xml | 14 ++++ .../src/main/res/values-ro/translations.xml | 69 ++++++++++++++++++- .../src/main/res/values-ru/translations.xml | 14 ++++ .../src/main/res/values-sk/translations.xml | 14 ++++ .../main/res/values-zh-rTW/translations.xml | 13 ++++ .../src/main/res/values/localazy.xml | 24 ++++++- 38 files changed, 287 insertions(+), 183 deletions(-) create mode 100644 features/ftue/impl/src/main/res/values-ro/translations.xml create mode 100644 features/poll/impl/src/main/res/values-cs/translations.xml create mode 100644 features/poll/impl/src/main/res/values-ro/translations.xml create mode 100644 features/poll/impl/src/main/res/values-ru/translations.xml delete mode 100644 libraries/textcomposer/src/main/res/values-es/translations.xml delete mode 100644 libraries/textcomposer/src/main/res/values-fr/translations.xml delete mode 100644 libraries/textcomposer/src/main/res/values-it/translations.xml diff --git a/features/ftue/impl/src/main/res/values-cs/translations.xml b/features/ftue/impl/src/main/res/values-cs/translations.xml index f1734c9c75..724f3793cd 100644 --- a/features/ftue/impl/src/main/res/values-cs/translations.xml +++ b/features/ftue/impl/src/main/res/values-cs/translations.xml @@ -1,6 +1,6 @@ - "Toto je jednorázový proces, děkujeme za čekání." + "Jedná se o jednorázový proces, prosíme o strpení." "Nastavení vašeho účtu" "Hovory, hlasování, vyhledávání a další budou přidány koncem tohoto roku." "Historie zpráv šifrovaných místností nebude v této aktualizaci k dispozici." diff --git a/features/ftue/impl/src/main/res/values-ro/translations.xml b/features/ftue/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..f932256318 --- /dev/null +++ b/features/ftue/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,11 @@ + + + "Acesta este un proces care se desfășoară o singură dată, vă mulțumim pentru așteptare." + "Contul dumneavoastră se configurează" + "Apelurile, sondajele, căutare și multe altele vor fi adăugate în cursul acestui an." + "Istoricul mesajelor pentru camerele criptate nu va fi disponibil în această actualizare." + "Ne-ar plăcea să auzim de la dumneavoastră, spuneți-ne ce părere aveți prin intermediul paginii de setări." + "Să începem!" + "Iată ce trebuie să știți:" + "Bun venit la%1$s!" + diff --git a/features/login/impl/src/main/res/values-ro/translations.xml b/features/login/impl/src/main/res/values-ro/translations.xml index 0c58c45d03..e780269a39 100644 --- a/features/login/impl/src/main/res/values-ro/translations.xml +++ b/features/login/impl/src/main/res/values-ro/translations.xml @@ -5,10 +5,11 @@ "Introduceţi un termen de căutare sau o adresă de domeniu." "Căutați o companie, o comunitate sau un server privat." "Găsiți un furnizor de cont" - "Aici vor trăi conversațiile - la fel cum ați folosi un furnizor de e-mail pentru a vă păstra e-mailurile." + "Aici vor trăi conversațiile dumneavoastră - la fel cum ați folosi un furnizor de e-mail pentru a vă păstra e-mailurile." "Sunteți pe cale să vă conectați la %s" - "Aici vor trăi conversațiile - la fel cum ați folosi un furnizor de e-mail pentru a vă păstra e-mailurile." + "Aici vor trăi conversațiile dumneavoastră - la fel cum ați folosi un furnizor de e-mail pentru a vă păstra e-mailurile." "Sunteți pe cale să creați un cont pe %s" + "Matrix.org este un server mare și gratuit din rețeaua publică Matrix pentru comunicații sigure și descentralizate, administrat de Fundația Matrix.org." "Altul" "Utilizați un alt furnizor de cont, cum ar fi propriul server privat sau un cont de serviciu." "Schimbați furnizorul contului" diff --git a/features/login/impl/src/main/res/values-ru/translations.xml b/features/login/impl/src/main/res/values-ru/translations.xml index 242ec4bb2c..3ecb8a52d0 100644 --- a/features/login/impl/src/main/res/values-ru/translations.xml +++ b/features/login/impl/src/main/res/values-ru/translations.xml @@ -9,6 +9,7 @@ "Вы собираетесь войти в %s" "Здесь будут храниться ваши разговоры - точно так же, как вы используете почтового провайдера для хранения своих писем." "Вы собираетесь создать учетную запись на %s" + "Matrix.org — это большой бесплатный сервер в общедоступной сети Matrix для безопасной децентрализованной связи, управляемый Matrix.org Foundation." "Другое" "Используйте другого поставщика учетных записей, например, собственный частный сервер или рабочую учетную запись." "Сменить поставщика учетной записи" diff --git a/features/messages/impl/src/main/res/values-cs/translations.xml b/features/messages/impl/src/main/res/values-cs/translations.xml index 7ca02ef21c..1543101f6d 100644 --- a/features/messages/impl/src/main/res/values-cs/translations.xml +++ b/features/messages/impl/src/main/res/values-cs/translations.xml @@ -5,11 +5,6 @@ "%1$d změny místnosti" "%1$d změn místnosti" - - "%1$d další" - "%1$d další" - "%1$d dalších" - "Fotoaparát" "Vyfotit" "Natočit video" diff --git a/features/messages/impl/src/main/res/values-fr/translations.xml b/features/messages/impl/src/main/res/values-fr/translations.xml index 5f9f0223aa..e88ddc43cb 100644 --- a/features/messages/impl/src/main/res/values-fr/translations.xml +++ b/features/messages/impl/src/main/res/values-fr/translations.xml @@ -4,10 +4,6 @@ "%1$d changement dans la conversation" "%1$d changements dans la conversation" - - "%1$d de plus" - "%1$d de plus" - "Appareil photo" "Prendre une photo" "Enregistrer une vidéo" diff --git a/features/messages/impl/src/main/res/values-ro/translations.xml b/features/messages/impl/src/main/res/values-ro/translations.xml index 54774ca172..c351eb29cb 100644 --- a/features/messages/impl/src/main/res/values-ro/translations.xml +++ b/features/messages/impl/src/main/res/values-ro/translations.xml @@ -11,13 +11,33 @@ "Atașament" "Bibliotecă foto și video" "Locație" + "Sondaj" + "Formatarea textului" + "Istoricul mesajelor este momentan indisponibil în această cameră" "Nu am putut găsi detaliile utilizatorului" "Doriți să îi invitați înapoi?" "Sunteți singur în această cameră" "Mesaj copiat" "Nu aveți permisiunea de a posta în această cameră" + "Permiteți setări personalizate" + "Activarea acestei opțiuni va anula setările implicite." + "Anunțați-mă în acestă cameră pentru" + "Îl puteți schimba în %1$s." + "Setări generale" + "Setare implicită" + "Stergeți setarea personalizată" + "A apărut o eroare la încărcarea setărilor pentry notificari." + "Nu s-a reușit restaurarea modului implicit, vă rugăm să încercați din nou." + "Nu s-a reușit setarea modului, vă rugăm să încercați din nou." + "Toate mesajele" + "Numai mențiuni și cuvinte cheie" + "În această cameră, anunțați-mă pentru" + "Afișați mai puțin" + "Afișați mai mult" "Trimiteți din nou" "Mesajul dvs. nu a putut fi trimis" + "Adăugați emoji" + "Afișați mai puțin" "Procesarea datelor media a eșuat, vă rugăm să încercați din nou." "Ștergeți" diff --git a/features/messages/impl/src/main/res/values-ru/translations.xml b/features/messages/impl/src/main/res/values-ru/translations.xml index 33147f8ea2..8c96074f1b 100644 --- a/features/messages/impl/src/main/res/values-ru/translations.xml +++ b/features/messages/impl/src/main/res/values-ru/translations.xml @@ -5,11 +5,6 @@ "%1$d изменения в комнате" "%1$d изменений в комнате" - - "И ещё %1$d" - "И ещё %1$d" - "И ещё %1$d" - "Камера" "Сделать фото" "Записать видео" diff --git a/features/messages/impl/src/main/res/values-sk/translations.xml b/features/messages/impl/src/main/res/values-sk/translations.xml index 03a32f847f..2390e1e25e 100644 --- a/features/messages/impl/src/main/res/values-sk/translations.xml +++ b/features/messages/impl/src/main/res/values-sk/translations.xml @@ -5,11 +5,6 @@ "%1$d zmeny miestnosti" "%1$d zmien miestnosti" - - "%1$d ďalší" - "%1$d ďalšie" - "%1$d ďalších" - "Kamera" "Odfotiť" "Nahrať video" diff --git a/features/messages/impl/src/main/res/values-zh-rTW/translations.xml b/features/messages/impl/src/main/res/values-zh-rTW/translations.xml index 88f97cd2bf..ac4725896e 100644 --- a/features/messages/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/messages/impl/src/main/res/values-zh-rTW/translations.xml @@ -3,9 +3,6 @@ "%1$d 個聊天室變更" - - "還有 %1$d 個" - "照相機" "拍照" "錄影" diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index 105cb1fc7b..81cd4933e4 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -4,9 +4,6 @@ "%1$d room change" "%1$d room changes" - - "%1$d more" - "Camera" "Take photo" "Record a video" @@ -14,6 +11,7 @@ "Photo & Video Library" "Location" "Poll" + "Text Formatting" "Message history is currently unavailable in this room" "Could not retrieve user details" "Would you like to invite them back?" diff --git a/features/poll/impl/src/main/res/values-cs/translations.xml b/features/poll/impl/src/main/res/values-cs/translations.xml new file mode 100644 index 0000000000..d199df993f --- /dev/null +++ b/features/poll/impl/src/main/res/values-cs/translations.xml @@ -0,0 +1,10 @@ + + + "Přidat volbu" + "Zobrazit výsledky až po skončení hlasování" + "Anonymní hlasování" + "Volba %1$d" + "Otázka nebo téma" + "Čeho se hlasování týká?" + "Vytvořit hlasování" + diff --git a/features/poll/impl/src/main/res/values-ro/translations.xml b/features/poll/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..b552a68024 --- /dev/null +++ b/features/poll/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,12 @@ + + + "Adăugați o opțiune" + "Afișați rezultatele numai după încheierea sondajului" + "Sondaj anonim" + "Opțiune %1$d" + "Sunteți sigur că doriți să renunțați la acest sondaj?" + "Renunțați la sondaj" + "Întrebare sau subiect" + "Despre ce este sondajul?" + "Creați un sondaj" + diff --git a/features/poll/impl/src/main/res/values-ru/translations.xml b/features/poll/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..f1a518b0e7 --- /dev/null +++ b/features/poll/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,10 @@ + + + "Добавить опцию" + "Показывать результаты только после окончания опроса" + "Анонимный опрос" + "Настройка %1$d" + "Вопрос или тема" + "Тема опроса?" + "Создать опрос" + diff --git a/features/poll/impl/src/main/res/values/localazy.xml b/features/poll/impl/src/main/res/values/localazy.xml index 876dd0ee44..4c80a4ce45 100644 --- a/features/poll/impl/src/main/res/values/localazy.xml +++ b/features/poll/impl/src/main/res/values/localazy.xml @@ -4,7 +4,8 @@ "Show results only after poll ends" "Anonymous Poll" "Option %1$d" - "Are you sure you would like to go back?" + "Are you sure you want to discard this poll?" + "Discard Poll" "Question or topic" "What is the poll about?" "Create Poll" diff --git a/features/rageshake/impl/src/main/res/values-ro/translations.xml b/features/rageshake/impl/src/main/res/values-ro/translations.xml index db0398c0db..e82c06826e 100644 --- a/features/rageshake/impl/src/main/res/values-ro/translations.xml +++ b/features/rageshake/impl/src/main/res/values-ro/translations.xml @@ -2,12 +2,13 @@ "Atașați o captură de ecran" "Puteți să mă contactați dacă aveți întrebări suplimentare" + "Contactați-mă" "Editați captura de ecran" "Vă rugăm să descrieți eroarea. Ce ați făcut? Ce vă aşteptați să se întâmple? Ce s-a întâmplat de fapt. Vă rugam să intrați în cât mai multe detalii cu putință." "Descrieți eroarea…" "Dacă posibil, vă rugăm să scrieți descrierea în engleză." "Trimiteți log-uri" - "Trimiteți log-uri pentru a ajuta" + "Permiteți log-uri" "Trimiteți captură de ecran" "Pentru a verifica că lucrurile funcționează conform așteptărilor, log-uri vor fi trimise împreună cu mesajul. Acestea vor fi private. Pentru a trimite doar mesajul, dezactivați această setare." "%1$s s-a blocat ultima dată când a fost folosit. Doriți să ne trimiteți un raport?" diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index c20cdab3f9..a2be94aee9 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -12,8 +12,13 @@ "Nu s-a putut actualiza camera" "Mesajele sunt securizate cu încuietori. Doar dumneavoastră și destinatarii aveți cheile unice pentru a le debloca." "Criptarea mesajelor este activată" + "A apărut o eroare la încărcarea setărilor pentru notificari." + "Dezactivarea notificarilor pentru această cameră a eșuat, încercați din nou." + "Activarea notificarilor pentru această cameră a eșuat, încercați din nou." "Invitați persoane" - "Notificare" + "Personalizat" + "Implicit" + "Notificări" "Numele camerei" "Partajați camera" "Se actualizează camera…" diff --git a/features/roomlist/impl/src/main/res/values-ro/translations.xml b/features/roomlist/impl/src/main/res/values-ro/translations.xml index b8ffc57090..e1f43a02ca 100644 --- a/features/roomlist/impl/src/main/res/values-ro/translations.xml +++ b/features/roomlist/impl/src/main/res/values-ro/translations.xml @@ -1,7 +1,9 @@ "Creați o conversație sau o cameră nouă" + "Începeți prin a trimite mesaje cuiva." + "Nu există încă discuții." "Toate conversatiile" - "Se pare că folosiți un dispozitiv nou. Verificați-vă identitatea pentru acces la mesajele dumneavoastră criptate." - "Accesați istoricul mesajelor" + "Se pare că folosiți un dispozitiv nou. Verificați-vă identitatea cu un alt dispozitiv pentru a accesa mesajele dumneavoastră criptate." + "Verificați că sunteți dumneavoastră" diff --git a/libraries/textcomposer/src/main/res/values-cs/translations.xml b/libraries/textcomposer/src/main/res/values-cs/translations.xml index c37f419ec4..dbac717093 100644 --- a/libraries/textcomposer/src/main/res/values-cs/translations.xml +++ b/libraries/textcomposer/src/main/res/values-cs/translations.xml @@ -1,18 +1,4 @@ "Přidat přílohu" - "Přepnout seznam s odrážkami" - "Přepnout blok kódu" - "Zpráva…" - "Použít tučný text" - "Použít kurzívu" - "Použít přeškrtnutí" - "Použít podtržení" - "Přepnout režim celé obrazovky" - "Odsazení" - "Použít formát inline kódu" - "Nastavit odkaz" - "Přepnout číslovaný seznam" - "Přepnout citaci" - "Zrušit odsazení" diff --git a/libraries/textcomposer/src/main/res/values-de/translations.xml b/libraries/textcomposer/src/main/res/values-de/translations.xml index dea872d7c0..6b75a1c9a7 100644 --- a/libraries/textcomposer/src/main/res/values-de/translations.xml +++ b/libraries/textcomposer/src/main/res/values-de/translations.xml @@ -1,18 +1,4 @@ "Anhang hinzufügen" - "Aufzählungsliste ein-/ausschalten" - "Codeblock umschalten" - "Nachricht…" - "Fettformatierung anwenden" - "Kursivformat anwenden" - "Durchgestrichenes Format anwenden" - "Unterstreichungsformat anwenden" - "Vollbildmodus umschalten" - "Einrücken" - "Inline-Codeformat anwenden" - "Link setzen" - "Nummerierte Liste ein-/ausschalten" - "Zitat umschalten" - "Einrücken aufheben" diff --git a/libraries/textcomposer/src/main/res/values-es/translations.xml b/libraries/textcomposer/src/main/res/values-es/translations.xml deleted file mode 100644 index 606e3bde8e..0000000000 --- a/libraries/textcomposer/src/main/res/values-es/translations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - "Lista de puntos" - "Bloque de código" - "Mensaje…" - "Aplicar formato negrita" - "Aplicar formato cursiva" - "Aplicar formato tachado" - "Aplicar formato de subrayado" - "Pantalla completa" - "Añadir sangría" - "Código" - "Enlazar" - "Lista numérica" - "Cita" - "Quitar sangría" - diff --git a/libraries/textcomposer/src/main/res/values-fr/translations.xml b/libraries/textcomposer/src/main/res/values-fr/translations.xml deleted file mode 100644 index 4b239c0f93..0000000000 --- a/libraries/textcomposer/src/main/res/values-fr/translations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - "Afficher une liste à puces" - "Afficher le bloc de code" - "Envoyer un message…" - "Appliquer le format gras" - "Appliquer le format italique" - "Appliquer le format barré" - "Appliquer le format souligné" - "Afficher en mode plein écran" - "Décaler vers la droite" - "Appliquer le formatage de code en ligne" - "Définir un lien" - "Afficher une liste numérotée" - "Afficher une citation" - "Décaler vers la gauche" - diff --git a/libraries/textcomposer/src/main/res/values-it/translations.xml b/libraries/textcomposer/src/main/res/values-it/translations.xml deleted file mode 100644 index e3034e8dfe..0000000000 --- a/libraries/textcomposer/src/main/res/values-it/translations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - "Attiva/disattiva l\'elenco puntato" - "Attiva/disattiva il blocco di codice" - "Messaggio…" - "Applica il formato in grassetto" - "Applicare il formato corsivo" - "Applica il formato barrato" - "Applicare il formato di sottolineatura" - "Attiva/disattiva la modalità a schermo intero" - "Rientro a destra" - "Applicare il formato del codice in linea" - "Imposta collegamento" - "Attiva/disattiva elenco numerato" - "Attiva/disattiva citazione" - "Rientro a sinistra" - diff --git a/libraries/textcomposer/src/main/res/values-ro/translations.xml b/libraries/textcomposer/src/main/res/values-ro/translations.xml index a7e1a7135c..25f0b025ca 100644 --- a/libraries/textcomposer/src/main/res/values-ro/translations.xml +++ b/libraries/textcomposer/src/main/res/values-ro/translations.xml @@ -1,17 +1,4 @@ - "Comutați lista cu puncte" - "Comutați blocul de cod" - "Mesaj…" - "Aplicați formatul aldin" - "Aplicați formatul italic" - "Aplicați formatul barat" - "Aplică formatul de subliniere" - "Comutați modul ecran complet" - "Indentare" - "Aplicați formatul de cod inline" - "Setați linkul" - "Comutați lista numerotată" - "Aplicați citatul" - "Dez-identare" + "Adăugați un atașament" diff --git a/libraries/textcomposer/src/main/res/values-ru/translations.xml b/libraries/textcomposer/src/main/res/values-ru/translations.xml index 9f7324f086..318cf9dadd 100644 --- a/libraries/textcomposer/src/main/res/values-ru/translations.xml +++ b/libraries/textcomposer/src/main/res/values-ru/translations.xml @@ -1,18 +1,4 @@ "Прикрепить файл" - "Переключить список маркеров" - "Переключить блок кода" - "Сообщение" - "Применить жирный шрифт" - "Применить курсивный формат" - "Применить формат зачеркивания" - "Применить формат подчеркивания" - "Переключение полноэкранного режима" - "Отступ" - "Применить встроенный формат кода" - "Установить ссылку" - "Переключить нумерованный список" - "Переключить цитату" - "Без отступа" diff --git a/libraries/textcomposer/src/main/res/values-sk/translations.xml b/libraries/textcomposer/src/main/res/values-sk/translations.xml index 26ac1df436..9d1daf99b6 100644 --- a/libraries/textcomposer/src/main/res/values-sk/translations.xml +++ b/libraries/textcomposer/src/main/res/values-sk/translations.xml @@ -1,18 +1,4 @@ "Pridať prílohu" - "Prepnúť zoznam odrážok" - "Prepnúť blok kódu" - "Správa…" - "Použiť tučný formát" - "Použiť formát kurzívy" - "Použiť formát prečiarknutia" - "Použiť formát podčiarknutia" - "Prepnúť režim celej obrazovky" - "Odsadenie" - "Použiť formát riadkového kódu" - "Nastaviť odkaz" - "Prepnúť číslovaný zoznam" - "Prepnúť citáciu" - "Zrušiť odsadenie" diff --git a/libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml b/libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml index 93777d4ca5..5aeda1b9e2 100644 --- a/libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml @@ -1,17 +1,4 @@ "新增附件" - "切換項目編號" - "切換程式碼區塊" - "訊息" - "套用粗體" - "套用斜體" - "套用刪除線" - "套用底線" - "切換全螢幕模式" - "增加縮排" - "設定連結" - "切換數字編號" - "切換引用" - "減少縮排" diff --git a/libraries/textcomposer/src/main/res/values/localazy.xml b/libraries/textcomposer/src/main/res/values/localazy.xml index 0bd53c3bee..11af785e8c 100644 --- a/libraries/textcomposer/src/main/res/values/localazy.xml +++ b/libraries/textcomposer/src/main/res/values/localazy.xml @@ -1,18 +1,4 @@ "Add attachment" - "Toggle bullet list" - "Toggle code block" - "Message…" - "Apply bold format" - "Apply italic format" - "Apply strikethrough format" - "Apply underline format" - "Toggle full screen mode" - "Indent" - "Apply inline code format" - "Set link" - "Toggle numbered list" - "Toggle quote" - "Unindent" diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index 1ace446132..bbb68b53e8 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -23,6 +23,7 @@ "Hotovo" "Upravit" "Povolit" + "Ukončit hlasování" "Zapomněli jste heslo?" "Přeposlat" "Pozvat" @@ -171,6 +172,20 @@ "Zdá se, že jste frustrovaně třásli telefonem. Chcete otevřít obrazovku pro nahlášení chyby?" "Tato zpráva bude nahlášena správci vašeho domovského serveru. Nebude si moci přečíst žádné šifrované zprávy." "Důvod nahlášení tohoto obsahu" + "Přepnout seznam s odrážkami" + "Přepnout blok kódu" + "Zpráva…" + "Použít tučný text" + "Použít kurzívu" + "Použít přeškrtnutí" + "Použít podtržení" + "Přepnout režim celé obrazovky" + "Odsazení" + "Použít formát inline kódu" + "Nastavit odkaz" + "Přepnout číslovaný seznam" + "Přepnout citaci" + "Zrušit odsazení" "Toto je začátek %1$s." "Toto je začátek této konverzace." "Nové" diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index 00979596a9..7aa02bddae 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -169,6 +169,20 @@ "Du scheinst frustriert das Telefon zu schütteln. Möchtest du den Fehlerberichtsbildschirm öffnen?" "Diese Nachricht wird an deinen Heimserver-Admin gemeldet. Er wird nicht in der Lage sein, verschlüsselte Nachrichten zu lesen." "Grund für die Meldung dieses Inhalts" + "Aufzählungsliste ein-/ausschalten" + "Codeblock umschalten" + "Nachricht…" + "Fettformatierung anwenden" + "Kursivformat anwenden" + "Durchgestrichenes Format anwenden" + "Unterstreichungsformat anwenden" + "Vollbildmodus umschalten" + "Einrücken" + "Inline-Codeformat anwenden" + "Link setzen" + "Nummerierte Liste ein-/ausschalten" + "Zitat umschalten" + "Einrücken aufheben" "Dies ist der Anfang von %1$s." "Dies ist der Beginn dieser Konversation." "Neu" diff --git a/libraries/ui-strings/src/main/res/values-es/translations.xml b/libraries/ui-strings/src/main/res/values-es/translations.xml index fa8a80f953..b56e1dfc7c 100644 --- a/libraries/ui-strings/src/main/res/values-es/translations.xml +++ b/libraries/ui-strings/src/main/res/values-es/translations.xml @@ -120,6 +120,20 @@ "Parece que sacudes el teléfono con frustración. ¿Quieres abrir la pantalla de informe de errores?" "Este mensaje se notificará al administrador de su homeserver. No podrán leer ningún mensaje cifrado." "Motivo para denunciar este contenido" + "Lista de puntos" + "Bloque de código" + "Mensaje…" + "Aplicar formato negrita" + "Aplicar formato cursiva" + "Aplicar formato tachado" + "Aplicar formato de subrayado" + "Pantalla completa" + "Añadir sangría" + "Código" + "Enlazar" + "Lista numérica" + "Cita" + "Quitar sangría" "Este es el principio de %1$s." "Este es el principio de esta conversación." "Nuevos" diff --git a/libraries/ui-strings/src/main/res/values-fr/translations.xml b/libraries/ui-strings/src/main/res/values-fr/translations.xml index e7020bc47b..745bde6497 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -158,6 +158,20 @@ "Vous semblez secouer le téléphone de frustration. Voulez-vous ouvrir le formulaire de rapport de problème ?" "Ce message sera signalé à l’administrateur de votre serveur d\'accueil. Ils ne pourront lire aucun message chiffré." "Raison du signalement de ce contenu" + "Afficher une liste à puces" + "Afficher le bloc de code" + "Envoyer un message…" + "Appliquer le format gras" + "Appliquer le format italique" + "Appliquer le format barré" + "Appliquer le format souligné" + "Afficher en mode plein écran" + "Décaler vers la droite" + "Appliquer le formatage de code en ligne" + "Définir un lien" + "Afficher une liste numérotée" + "Afficher une citation" + "Décaler vers la gauche" "Ceci est le début de %1$s." "Ceci est le début de cette conversation." "Nouveau" diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index b15d570dfc..740fe81b55 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -120,6 +120,20 @@ "Sembra che tu stia scuotendo il telefono per la frustrazione. Vuoi aprire la schermata di segnalazione dei problemi?" "Questo messaggio verrà segnalato all\'amministratore dell\'homeserver. Questi non sarà in grado di leggere i messaggi criptati." "Motivo della segnalazione di questo contenuto" + "Attiva/disattiva l\'elenco puntato" + "Attiva/disattiva il blocco di codice" + "Messaggio…" + "Applica il formato in grassetto" + "Applicare il formato corsivo" + "Applica il formato barrato" + "Applicare il formato di sottolineatura" + "Attiva/disattiva la modalità a schermo intero" + "Rientro a destra" + "Applicare il formato del codice in linea" + "Imposta collegamento" + "Attiva/disattiva elenco numerato" + "Attiva/disattiva citazione" + "Rientro a sinistra" "Questo è l\'inizio di %1$s." "Questo è l\'inizio della conversazione." "Nuovo" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index d90a7a6cfc..d96abca3cc 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -1,6 +1,8 @@ "Ascundeți parola" + "Doar mențiuni" + "Notificări dezactivate" "Trimiteți fișiere" "Afișați parola" "Meniu utilizator" @@ -23,6 +25,7 @@ "Efectuat" "Editați" "Activați" + "Închideți sondajul" "Ați uitat parola?" "Redirecționați" "Invitați" @@ -40,6 +43,7 @@ "Deschideți cu" "Raspuns rapid" "Citat" + "Reacționați" "Ștergeți" "Răspundeți" "Raportați o eroare" @@ -94,6 +98,9 @@ "Parola" "Persoane" "Permalink" + "Voturi finale: %1$s" + "Total voturi: %1$s" + "Rezultatele vor fi afișate după încheierea sondajului" "Politica de confidențialitate" "Reacții" "Se actualizează" @@ -116,11 +123,12 @@ "Succes" "Sugestii" "Se sincronizează…" + "Text" "Notificări despre software de la terți" "Subiect" "Despre ce este vorba în această cameră?" "Nu s-a putut decripta" - "Nu am putut trimite cu succes invitații unuia sau mai multor utilizatori." + "Nu am putut trimite invitații unuia sau mai multor utilizatori." "Nu s-a putut trimite invitația (invitațiile)" "Activați sunetul" "Eveniment neacceptat" @@ -140,7 +148,11 @@ "Călătorii & Locuri" "Simboluri" "Crearea permalink-ului a eșuat" + "%1$s nu a putut încărca harta. Vă rugăm să încercați din nou mai târziu." "Încărcarea mesajelor a eșuat" + "%1$s nu a putut accesa locația dumneavoastră. Vă rugăm să încercați din nou mai târziu." + "%1$s nu are permisiuni pentru a accesa locația dumneavoastră. Puteți permite accesul în Setări." + "%1$s nu are permisiuni pentru a accesa locația dumneavoastră. Permiteți accesul mai jos." "Unele mesaje nu au fost trimise" "Ne pare rău, a apărut o eroare" "🔐️ Alăturați-vă mie pe %1$s" @@ -154,10 +166,34 @@ "%1$d membri" "%1$d membri" + + "%d vot" + "%d voturi" + "%d voturi" + "Rageshake pentru a raporta erori" "Se pare că scuturați telefonul de frustrare. Doriți să deschdeți ecranul de raportare a unei erori?" "Acest mesaj va fi raportat administratorilor homeserver-ului tau. Ei nu vor putea citi niciun mesaj criptat." "Motivul raportării acestui conținut" + "Comutați lista cu puncte" + "Închideți opțiunile de formatare" + "Comutați blocul de cod" + "Mesaj…" + "Creați un link" + "Editați link-ul" + "Aplicați formatul aldin" + "Aplicați formatul italic" + "Aplicați formatul barat" + "Aplică formatul de subliniere" + "Comutați modul ecran complet" + "Indentare" + "Aplicați formatul de cod inline" + "Setați linkul" + "Comutați lista numerotată" + "Deschideți opțiunile de compunere" + "Aplicați citatul" + "Dez-identare" + "Link" "Acesta este începutul conversației %1$s." "Acesta este începutul acestei conversații." "Nou" @@ -165,9 +201,40 @@ "Selectarea fișierelor media a eșuat, încercați din nou." "Procesarea datelor media a eșuat, vă rugăm să încercați din nou." "Încărcarea fișierelor media a eșuat, încercați din nou." + "Setări adiționale" + "Apeluri audio și video" + "Nepotrivire de configurație" + "Am simplificat Setările pentru notificări pentru a face opțiunile mai ușor de găsit. + +Unele setări personalizate pe care le-ați ales în trecut nu sunt afișate aici, dar sunt încă active. + +Dacă continuați, unele dintre setările dumneavoastră pot fi modificate." + "Discuții directe" + "Setare personalizată per chat" + "A apărut o eroare în timpul actualizării setărilor pentru notificari." + "Toate mesajele" + "Numai mențiuni și cuvinte cheie" + "În conversațiile directe, anunță-mă pentru" + "În conversațiile de grup, anunțați-mă pentru" + "Activați notificările pe acest dispozitiv" + "Configurația nu a fost corectată, vă rugăm să încercați din nou." + "Discuții de grup" + "Mențiuni" + "Toate" + "Mențiuni" + "Anunță-mă pentru" + "Anunțați-mă pentru @room" + "Pentru a primi notificări, vă rugăm să vă schimbați %1$s." + "Setări de sistem" + "Notificările de sistem sunt dezactivate" + "Notificări" "Confirmați că doriți să ascundeți toate mesajele curente și viitoare de la acest utilizator" + "Cont și dispozitive" "Partajați locația" "Distribuiți locația mea" + "Deschideți în Apple Maps" + "Deschideți în Google Maps" + "Deschideți în OpenStreetMap" "Distribuiți această locație" "Locație" "Rageshake" diff --git a/libraries/ui-strings/src/main/res/values-ru/translations.xml b/libraries/ui-strings/src/main/res/values-ru/translations.xml index 23df74fff5..28284f6347 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -171,6 +171,20 @@ "Кажется, вы трясли телефон. Хотите открыть экран отчета об ошибке?" "Это сообщение будет передано администратору вашего домашнего сервера. Они не смогут прочитать зашифрованные сообщения." "Причина, по которой вы пожаловались на этот контент" + "Переключить список маркеров" + "Переключить блок кода" + "Сообщение" + "Применить жирный шрифт" + "Применить курсивный формат" + "Применить формат зачеркивания" + "Применить формат подчеркивания" + "Переключение полноэкранного режима" + "Отступ" + "Применить встроенный формат кода" + "Установить ссылку" + "Переключить нумерованный список" + "Переключить цитату" + "Без отступа" "Это начало %1$s." "Это начало разговора." "Новый" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index b8d919faa0..cad1b5a564 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -171,6 +171,20 @@ "Zdá sa, že zúrivo trasiete telefónom. Chcete otvoriť obrazovku s nahlásením chýb?" "Táto správa bude nahlásená správcovi vášho domovského servera. Nebude môcť prečítať žiadne šifrované správy." "Dôvod nahlásenia tohto obsahu" + "Prepnúť zoznam odrážok" + "Prepnúť blok kódu" + "Správa…" + "Použiť tučný formát" + "Použiť formát kurzívy" + "Použiť formát prečiarknutia" + "Použiť formát podčiarknutia" + "Prepnúť režim celej obrazovky" + "Odsadenie" + "Použiť formát riadkového kódu" + "Nastaviť odkaz" + "Prepnúť číslovaný zoznam" + "Prepnúť citáciu" + "Zrušiť odsadenie" "Toto je začiatok %1$s." "Toto je začiatok tejto konverzácie." "Nové" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index 32f8a23086..ddaaed0d33 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -141,6 +141,19 @@ "%d 票" "檢舉這個內容的原因" + "切換項目編號" + "切換程式碼區塊" + "訊息" + "套用粗體" + "套用斜體" + "套用刪除線" + "套用底線" + "切換全螢幕模式" + "增加縮排" + "設定連結" + "切換數字編號" + "切換引用" + "減少縮排" "新訊息" "分享分析數據" "無法上傳媒體檔案,請稍後再試。" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 95ae43dd21..8a9f1cee2f 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -1,6 +1,8 @@ "Hide password" + "Mentions only" + "Muted" "Send files" "Show password" "User menu" @@ -23,6 +25,7 @@ "Done" "Edit" "Enable" + "End poll" "Forgot password?" "Forward" "Invite" @@ -61,7 +64,6 @@ "Take photo" "View Source" "Yes" - "End poll" "About" "Acceptable use policy" "Analytics" @@ -121,6 +123,7 @@ "Success" "Suggestions" "Syncing" + "Text" "Third-party notices" "Topic" "What is this room about?" @@ -170,6 +173,25 @@ "You seem to be shaking the phone in frustration. Would you like to open the bug report screen?" "This message will be reported to your homeserver’s administrator. They will not be able to read any encrypted messages." "Reason for reporting this content" + "Toggle bullet list" + "Close formatting options" + "Toggle code block" + "Message…" + "Create a link" + "Edit link" + "Apply bold format" + "Apply italic format" + "Apply strikethrough format" + "Apply underline format" + "Toggle full screen mode" + "Indent" + "Apply inline code format" + "Set link" + "Toggle numbered list" + "Open compose options" + "Toggle quote" + "Unindent" + "Link" "This is the beginning of %1$s." "This is the beginning of this conversation." "New" From 1f167e9eca3443581f48d35174b4a967dc7e4317 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 5 Sep 2023 07:35:15 +0000 Subject: [PATCH 047/127] Update screenshots --- ...reate_null_CreatePollView-D-0_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...reate_null_CreatePollView-N-0_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-D-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-D-0_1_null_2,NEXUS_5,1.0,en].png index cc49158545..8e47757aa3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-D-0_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-D-0_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:155cee63d3e031c912786b95bcc8e28dc4d1b296f8f0e4c01bd96398bb2dd040 -size 40623 +oid sha256:636e6c2494e69d7f1383e0c2ef178db484cfa6802c6714ee20a66aad10f4421f +size 40500 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-N-0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-N-0_2_null_2,NEXUS_5,1.0,en].png index 127289d30b..96707cb507 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-N-0_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.create_null_CreatePollView-N-0_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b682b0025c98d9d37ab8dc67cbc8a637f672ae2bf9e4a26e48209188d612c0c -size 36455 +oid sha256:58ced9ebe2a161167f5515efa18b87eb02c340b75db47af84f91eab0866b113f +size 36370 From 9bf3521f39459b873a2f5347f8d52068689cccc5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 12:05:42 +0200 Subject: [PATCH 048/127] Compute avatar color of users and apply foreground color to the sender displayname. --- .../components/TimelineItemEventRow.kt | 4 +- .../designsystem/colors/AvatarColor.kt | 47 +++++++++++++++++++ .../theme/colors/AvatarColorsDark.kt | 35 ++++++++++++++ .../theme/colors/AvatarColorsLight.kt | 35 ++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt create mode 100644 libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsDark.kt create mode 100644 libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsLight.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 10671ee00f..e1c6b746d2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -75,6 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent +import io.element.android.libraries.designsystem.colors.AvatarColor import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -327,6 +328,7 @@ private fun MessageSenderInformation( ) { val avatarStrokeColor = MaterialTheme.colorScheme.background val avatarSize = senderAvatar.size.dp + val avatarColor = AvatarColor(senderAvatar.id) Box( modifier = modifier ) { @@ -350,7 +352,7 @@ private fun MessageSenderInformation( text = sender, maxLines = 1, overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.primary, + color = avatarColor.foreground, style = ElementTheme.typography.fontBodyMdMedium, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt new file mode 100644 index 0000000000..0edd90132a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 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.libraries.designsystem.colors + +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.theme.colors.avatarColorsDark +import io.element.android.libraries.theme.colors.avatarColorsLight + +data class AvatarColor( + val background: Color, + val foreground: Color, +) + +@Composable +fun AvatarColor(userId: String): AvatarColor { + val hash = userId.toHash() + val colors = if (ElementTheme.isLightTheme) { + avatarColorsLight[hash % avatarColorsLight.size] + } else { + avatarColorsDark[hash % avatarColorsDark.size] + } + return AvatarColor( + background = colors.first, + foreground = colors.second, + ) +} + +private fun String.toHash(): Int { + return toList().sumOf { it.code } % 8 + 1 +} + diff --git a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsDark.kt b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsDark.kt new file mode 100644 index 0000000000..a18721a60b --- /dev/null +++ b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsDark.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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.libraries.theme.colors + +import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens + +/** + * Avatar colors are not yet part of SemanticColors, so create list here. + * DarkDesignTokens is internal to the module. + */ + +val avatarColorsDark = listOf( + DarkDesignTokens.colorBlue300 to DarkDesignTokens.colorBlue1200, + DarkDesignTokens.colorFuchsia300 to DarkDesignTokens.colorFuchsia1200, + DarkDesignTokens.colorGreen300 to DarkDesignTokens.colorGreen1200, + DarkDesignTokens.colorPink300 to DarkDesignTokens.colorPink1200, + DarkDesignTokens.colorOrange300 to DarkDesignTokens.colorOrange1200, + DarkDesignTokens.colorCyan300 to DarkDesignTokens.colorCyan1200, + DarkDesignTokens.colorPurple300 to DarkDesignTokens.colorPurple1200, + DarkDesignTokens.colorLime300 to DarkDesignTokens.colorLime1200, +) diff --git a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsLight.kt b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsLight.kt new file mode 100644 index 0000000000..d2c320d479 --- /dev/null +++ b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/colors/AvatarColorsLight.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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.libraries.theme.colors + +import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens + +/** + * Avatar colors are not yet part of SemanticColors, so create list here. + * LightDesignTokens is internal to the module. + */ + +val avatarColorsLight = listOf( + LightDesignTokens.colorBlue300 to LightDesignTokens.colorBlue1200, + LightDesignTokens.colorFuchsia300 to LightDesignTokens.colorFuchsia1200, + LightDesignTokens.colorGreen300 to LightDesignTokens.colorGreen1200, + LightDesignTokens.colorPink300 to LightDesignTokens.colorPink1200, + LightDesignTokens.colorOrange300 to LightDesignTokens.colorOrange1200, + LightDesignTokens.colorCyan300 to LightDesignTokens.colorCyan1200, + LightDesignTokens.colorPurple300 to LightDesignTokens.colorPurple1200, + LightDesignTokens.colorLime300 to LightDesignTokens.colorLime1200, +) From e301d606482714e5a0e999c14bb77b59faf45700 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 12:12:59 +0200 Subject: [PATCH 049/127] Compute avatar color of users and apply foreground color to the sender displayname. --- .../components/TimelineItemEventRow.kt | 6 +-- .../{AvatarColor.kt => AvatarColors.kt} | 14 +++---- .../designsystem/colors/AvatarColorsTest.kt | 40 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/{AvatarColor.kt => AvatarColors.kt} (80%) create mode 100644 libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index e1c6b746d2..56ad1c338e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -75,7 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent -import io.element.android.libraries.designsystem.colors.AvatarColor +import io.element.android.libraries.designsystem.colors.AvatarColors import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -328,7 +328,7 @@ private fun MessageSenderInformation( ) { val avatarStrokeColor = MaterialTheme.colorScheme.background val avatarSize = senderAvatar.size.dp - val avatarColor = AvatarColor(senderAvatar.id) + val avatarColors = AvatarColors(senderAvatar.id) Box( modifier = modifier ) { @@ -352,7 +352,7 @@ private fun MessageSenderInformation( text = sender, maxLines = 1, overflow = TextOverflow.Ellipsis, - color = avatarColor.foreground, + color = avatarColors.foreground, style = ElementTheme.typography.fontBodyMdMedium, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt similarity index 80% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index 0edd90132a..e73cbf3218 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -22,26 +22,26 @@ import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsDark import io.element.android.libraries.theme.colors.avatarColorsLight -data class AvatarColor( +data class AvatarColors( val background: Color, val foreground: Color, ) @Composable -fun AvatarColor(userId: String): AvatarColor { +fun AvatarColors(userId: String): AvatarColors { val hash = userId.toHash() val colors = if (ElementTheme.isLightTheme) { - avatarColorsLight[hash % avatarColorsLight.size] + avatarColorsLight[hash] } else { - avatarColorsDark[hash % avatarColorsDark.size] + avatarColorsDark[hash] } - return AvatarColor( + return AvatarColors( background = colors.first, foreground = colors.second, ) } -private fun String.toHash(): Int { - return toList().sumOf { it.code } % 8 + 1 +internal fun String.toHash(): Int { + return toList().sumOf { it.code } % 8 } diff --git a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt new file mode 100644 index 0000000000..2b91a9e490 --- /dev/null +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 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.libraries.designsystem.colors + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.theme.colors.avatarColorsDark +import io.element.android.libraries.theme.colors.avatarColorsLight +import org.junit.Test + +class AvatarColorsTest { + + @Test + fun `ensure list size`() { + // avatarColorsDark and avatarColorsLight size must not be modified. + // 8 is used as a hard-coded modulo in `String.toHash()` extension. + assertThat(avatarColorsDark.size).isEqualTo(8) + assertThat(avatarColorsLight.size).isEqualTo(8) + } + + @Test + fun `compute string hash`() { + assertThat("@alice:domain.org".toHash()).isEqualTo(6) + assertThat("@bob:domain.org".toHash()).isEqualTo(3) + assertThat("@charlie:domain.org".toHash()).isEqualTo(0) + } +} From 1cffbbdca745168f6ed98ac73d699ff27066e40e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 12:44:36 +0200 Subject: [PATCH 050/127] Apply colors to default user avatar in the timeline. --- .../components/TimelineItemEventRow.kt | 2 +- .../designsystem/components/avatar/Avatar.kt | 8 ++- .../components/avatar/UserAvatarPreview.kt | 51 +++++++++++++++++++ .../designsystem/colors/AvatarColorsTest.kt | 12 +++++ 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 56ad1c338e..b5229c2656 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -346,7 +346,7 @@ private fun MessageSenderInformation( } // Content Row { - Avatar(senderAvatar) + Avatar(senderAvatar, avatarColors = avatarColors) Spacer(modifier = Modifier.width(4.dp)) Text( text = sender, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 2e2d98ddbb..cfc2efd6ae 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage +import io.element.android.libraries.designsystem.colors.AvatarColors import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar @@ -45,6 +46,7 @@ import timber.log.Timber fun Avatar( avatarData: AvatarData, modifier: Modifier = Modifier, + avatarColors: AvatarColors? = null, contentDescription: String? = null, ) { val commonModifier = modifier @@ -53,6 +55,7 @@ fun Avatar( if (avatarData.url.isNullOrBlank()) { InitialsAvatar( avatarData = avatarData, + avatarColors = avatarColors, modifier = commonModifier, ) } else { @@ -85,12 +88,13 @@ private fun ImageAvatar( @Composable private fun InitialsAvatar( avatarData: AvatarData, + avatarColors: AvatarColors?, modifier: Modifier = Modifier, ) { // Use temporary color for default avatar background val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled Box( - modifier.background(color = avatarColor), + modifier.background(color = avatarColors?.background ?: avatarColor) ) { val fontSize = avatarData.size.dp.toSp() / 2 val originalFont = ElementTheme.typography.fontBodyMdRegular @@ -100,7 +104,7 @@ private fun InitialsAvatar( modifier = Modifier.align(Alignment.Center), text = avatarData.initial, style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), - color = Color.White, + color = avatarColors?.foreground ?: Color.White, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt new file mode 100644 index 0000000000..f47ee9bb7a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 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.libraries.designsystem.components.avatar + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.colors.avatarColorsLight + +@DayNightPreviews +@Composable +internal fun UserAvatarPreview() = ElementPreview { + Column( + modifier = Modifier.padding(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + repeat(avatarColorsLight.size) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. + Avatar(anAvatarData(), avatarColors = AvatarColors("$it")) + Text(text = "Color index $it") + } + } + } +} diff --git a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt index 2b91a9e490..8e92e8186c 100644 --- a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt @@ -37,4 +37,16 @@ class AvatarColorsTest { assertThat("@bob:domain.org".toHash()).isEqualTo(3) assertThat("@charlie:domain.org".toHash()).isEqualTo(0) } + + @Test + fun `compute string hash reverse`() { + assertThat("0".toHash()).isEqualTo(0) + assertThat("1".toHash()).isEqualTo(1) + assertThat("2".toHash()).isEqualTo(2) + assertThat("3".toHash()).isEqualTo(3) + assertThat("4".toHash()).isEqualTo(4) + assertThat("5".toHash()).isEqualTo(5) + assertThat("6".toHash()).isEqualTo(6) + assertThat("7".toHash()).isEqualTo(7) + } } From 29f5373e71bb8bc689bc10952cf8478edf7b6175 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 14:04:38 +0200 Subject: [PATCH 051/127] changelog. --- changelog.d/1224.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1224.feature diff --git a/changelog.d/1224.feature b/changelog.d/1224.feature new file mode 100644 index 0000000000..c921977df4 --- /dev/null +++ b/changelog.d/1224.feature @@ -0,0 +1 @@ +Set color on display name and default avatar in the timeline. From 74fc570708cf0c0777c4969271b2bfd08e62f252 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 14:21:14 +0200 Subject: [PATCH 052/127] Composable functions that return a value should start with a lowercase letter --- .../messages/impl/timeline/components/TimelineItemEventRow.kt | 4 ++-- .../android/libraries/designsystem/colors/AvatarColors.kt | 2 +- .../designsystem/components/avatar/UserAvatarPreview.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index b5229c2656..fd9676653f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -75,7 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent -import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.colors.avatarColors import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -328,7 +328,7 @@ private fun MessageSenderInformation( ) { val avatarStrokeColor = MaterialTheme.colorScheme.background val avatarSize = senderAvatar.size.dp - val avatarColors = AvatarColors(senderAvatar.id) + val avatarColors = avatarColors(senderAvatar.id) Box( modifier = modifier ) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index e73cbf3218..26e255194c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -28,7 +28,7 @@ data class AvatarColors( ) @Composable -fun AvatarColors(userId: String): AvatarColors { +fun avatarColors(userId: String): AvatarColors { val hash = userId.toHash() val colors = if (ElementTheme.isLightTheme) { avatarColorsLight[hash] diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt index f47ee9bb7a..b9b8f42062 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.colors.avatarColors import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.Text @@ -43,7 +43,7 @@ internal fun UserAvatarPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(), avatarColors = AvatarColors("$it")) + Avatar(anAvatarData(), avatarColors = avatarColors("$it")) Text(text = "Color index $it") } } From ff77fca34d24415b402f59754f1fc363c762bd02 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 14:55:53 +0200 Subject: [PATCH 053/127] Avoid hard-coded number and update the related test. --- .../android/libraries/designsystem/colors/AvatarColors.kt | 2 +- .../libraries/designsystem/colors/AvatarColorsTest.kt | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index 26e255194c..fb379c751e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -42,6 +42,6 @@ fun avatarColors(userId: String): AvatarColors { } internal fun String.toHash(): Int { - return toList().sumOf { it.code } % 8 + return toList().sumOf { it.code } % avatarColorsLight.size } diff --git a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt index 8e92e8186c..7b3392607d 100644 --- a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt @@ -24,11 +24,8 @@ import org.junit.Test class AvatarColorsTest { @Test - fun `ensure list size`() { - // avatarColorsDark and avatarColorsLight size must not be modified. - // 8 is used as a hard-coded modulo in `String.toHash()` extension. - assertThat(avatarColorsDark.size).isEqualTo(8) - assertThat(avatarColorsLight.size).isEqualTo(8) + fun `ensure the size of the avatar color are equal for light and dark theme`() { + assertThat(avatarColorsDark.size).isEqualTo(avatarColorsLight.size) } @Test From d383590910bf8c37f4a32057a5f8b221a3bb9be8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 15:39:21 +0200 Subject: [PATCH 054/127] Use bolder font for fallback avatar. --- .../android/libraries/designsystem/components/avatar/Avatar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index cfc2efd6ae..dc6149d0f6 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -97,7 +97,7 @@ private fun InitialsAvatar( modifier.background(color = avatarColors?.background ?: avatarColor) ) { val fontSize = avatarData.size.dp.toSp() / 2 - val originalFont = ElementTheme.typography.fontBodyMdRegular + val originalFont = ElementTheme.typography.fontHeadingMdBold val ratio = fontSize.value / originalFont.fontSize.value val lineHeight = originalFont.lineHeight * ratio Text( From 6ef288c26d64c0b9988fce2b8bb873c2767b6605 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 15:45:12 +0200 Subject: [PATCH 055/127] Rename parameter and update comment. --- .../impl/timeline/components/TimelineItemEventRow.kt | 2 +- .../libraries/designsystem/components/avatar/Avatar.kt | 6 +++--- .../designsystem/components/avatar/UserAvatarPreview.kt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index fd9676653f..30478c6ef0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -346,7 +346,7 @@ private fun MessageSenderInformation( } // Content Row { - Avatar(senderAvatar, avatarColors = avatarColors) + Avatar(senderAvatar, initialAvatarColors = avatarColors) Spacer(modifier = Modifier.width(4.dp)) Text( text = sender, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index dc6149d0f6..958f4ca29e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -46,7 +46,7 @@ import timber.log.Timber fun Avatar( avatarData: AvatarData, modifier: Modifier = Modifier, - avatarColors: AvatarColors? = null, + initialAvatarColors: AvatarColors? = null, contentDescription: String? = null, ) { val commonModifier = modifier @@ -55,7 +55,7 @@ fun Avatar( if (avatarData.url.isNullOrBlank()) { InitialsAvatar( avatarData = avatarData, - avatarColors = avatarColors, + avatarColors = initialAvatarColors, modifier = commonModifier, ) } else { @@ -91,7 +91,7 @@ private fun InitialsAvatar( avatarColors: AvatarColors?, modifier: Modifier = Modifier, ) { - // Use temporary color for default avatar background + // Use temporary color for default avatar background, if avatarColors is not provided val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled Box( modifier.background(color = avatarColors?.background ?: avatarColor) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt index b9b8f42062..817650ffa7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -43,7 +43,7 @@ internal fun UserAvatarPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(), avatarColors = avatarColors("$it")) + Avatar(anAvatarData(), initialAvatarColors = avatarColors("$it")) Text(text = "Color index $it") } } From a8b9d0529f26cb41a5718a6ea9c310a62a297a0c Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 5 Sep 2023 13:55:40 +0000 Subject: [PATCH 056/127] Update screenshots --- ...people_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...eople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...l_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...om_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...m_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...mmary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...mmary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...s_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ..._null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...elineItemEventRowLongSenderName_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...emEventRowWithManyReactionsDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mEventRowWithManyReactionsLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...melineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...elineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-D-2_3_null_10,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-D-2_3_null_11,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-D-2_3_null_12,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-D-2_3_null_9,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-N-2_4_null_10,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-N-2_4_null_11,NEXUS_5,1.0,en].png | 4 ++-- ...meline_null_TimelineView-N-2_4_null_12,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...imeline_null_TimelineView-N-2_4_null_9,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ll_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ll_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...l_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...l_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...ser_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ser_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...mbers_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...mbers_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...bers_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...bers_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png | 2 +- ....impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png | 2 +- ....impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png | 2 +- ...impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png | 4 ++-- ..._null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...list.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...oomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png | 2 +- ...s.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png | 2 +- ...s.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png | 4 ++-- ...onents.avatar_null_UserAvatar-D_0_null,NEXUS_5,1.0,en].png | 3 +++ ...onents.avatar_null_UserAvatar-N_1_null,NEXUS_5,1.0,en].png | 3 +++ ...ll_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ll_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...l_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...l_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...ts_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...omponents_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...omponents_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png | 4 ++-- 241 files changed, 477 insertions(+), 471 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-D_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-N_1_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png index 7631149941..9031993cc7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:208bb2b2743d33d15741f502329ac9ed67eb73c0556c14803edf33eafeadbc06 -size 28586 +oid sha256:ff5cb940c05656ed7debf230c7c2d780395e30f20c5d3da3abef136afb5359fe +size 28541 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png index f95d150d54..d65aa5499e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abc707d2ec2e23878e78126063ea31c5eaa93559d2803fba5cf453e4a02a01bb -size 29293 +oid sha256:edf63c7ae4b058c94cd611948f2bb3c3304c2646af0200e08f7b480f1ba965d8 +size 29245 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png index 9005d6750d..b027f127c4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:013b3e67d39a895fb391b82a633d85bc5e372e2b209854dcda9a72db0c243812 -size 86646 +oid sha256:3fe351b3d0b78473fdab1d4bc806468485939734e46cb3fa6d9f9058513d4dba +size 86421 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png index 349c6d27ac..0f8dfab3d3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a72958cbdae4807f345d98501420e8f6ac1409ac534f8434341df4c3e53cd5e -size 45342 +oid sha256:9dbfb671a112ae3bab099db959b30dcd4185d48bd365f63373da62971df51e00 +size 45246 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png index fd8b3f3e85..1b3c77ebaa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f66d2db6c718056a13f463f0f0f62321250222039c234d267d788351a051ed4d -size 25777 +oid sha256:137a71939d978e2f10d94d49faed208c54a5fa82b32d9ba2b47a3946641d361f +size 25688 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png index ef70f98f62..ee833eae85 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e688c0f31238dd9870c8634409f854b29cb5ab43ca251fb41466f959103627af -size 64149 +oid sha256:eb84e5f7f23db39d8d2d162f0d55d8129ae88e984dcde816c86682981226bf4f +size 64074 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png index 97a7dd126d..1a18f078da 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:421f94cb97db6395d5b53188e7084599c2adba2ae44d38004d3e088bcc0daad2 -size 67968 +oid sha256:eeeb724c3797679434f580261071602e2b8991b466e0e47806c7d7b0e4e4be2a +size 67838 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png index e84042b3eb..ed8846c5f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44a6cda760e51d3710a951f38d14e1cc17a4fdcb91f281e8c002d424e53b82d6 -size 25829 +oid sha256:c2044763a0297a9d89c2a4ebb7fbd3ba967a5ac99a28375aeccf4766bc1a3be3 +size 25762 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png index 4d4ea9cb15..b014ceeaa4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:251f0553c3b80a4ca7c1c21fbf776c74ec6f0c85233d0481e0a6859c5f7fa53b -size 65976 +oid sha256:675584b016f10890e13008152ade861de50b3463de9a253353f0d1af4f57c200 +size 65789 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png index 6b00bf5b03..3160672512 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71639d6a2869732e57c682158360c1bf281a3c3ed3522007139200606794b3ec -size 69992 +oid sha256:708d5201ded559e388a453d0df87d97aa7068f4892d6acb8a3bf50497a6754eb +size 69831 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png index 780a9a189a..aebe6c0c19 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71255625dff4f333e8c8e0fe3cb77435dc552fdc756b8b517e2a783cf6c4677e -size 83540 +oid sha256:7816a99e6460155c0d4c8f74fec6b2f09ec724f3442f5b1e77b45e98b5d43be1 +size 83585 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png index 6ecce2c456..2b4f8e8e26 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0af148880e1609550dca835b9ca7d18ca277f19c056d5acc160d6877dc2192e0 -size 87215 +oid sha256:ec1b567e5175c9e83aee05623270f2f2d5497c901438042075a2b57a1284a368 +size 87153 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png index c45576d5cc..11393a5279 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e49f264556720e31a6974923f38765a4612f65a6be682dcb30cb65b4693c1171 -size 20738 +oid sha256:a59a7d481cdcc7b3fa216bc3ec4a20195730d27fe518a6610d9a61fb4a3b347f +size 20753 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png index 5bf0a8b17f..786c163f1e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fdc6810543c33b89da0d3ed0242d36ae4f33d3d16c73a6d4a6169abbbe28d8e3 -size 27046 +oid sha256:22ac66742c1e14c8f9ddf8f56f86fd155f6f8d3adfc90483772f4f78c71fe81c +size 27063 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png index 8d4037d07b..a4ed8eb2e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97dd59ac203eab2b727c3ceeb5191db5c4ad2d75eb1bc6676694ed06db7081ff -size 23810 +oid sha256:fd1cce3d0a456d3501f0f5c5160821210fd1060c24a66f1cacb65f9f95b44bb8 +size 23792 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png index 02d70404c1..05509fabe3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5288dbf84bb4f976917d7be59c469306397d97cc42065ad085dbe10ee75aa20f -size 31185 +oid sha256:2f26d62e7ca9b98ca9314305b0659f7919b58f5d7805684832e91d5f3cb6ece4 +size 31162 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png index ee189e660a..16876034a0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e13873cff0df39c7aec90c64041d8eb557bd2cd65935a34fb7122951b7cc0b87 -size 28452 +oid sha256:5740c7f4d76a786612c5a1cb9e58c29c87778f3e8d11878f310cfda3da1bed8a +size 28445 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png index cc4b32b204..9f6e875358 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6128ba7f2b0b5389be5310bf3778c093ea30a92fa3f78173e7d3aafce834b14d -size 32920 +oid sha256:fbb6813f970b0fcfa9489d06b28b2e17d6d0fc97d2f0494553a629df930af48c +size 32919 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png index 8b95e73430..da5124b675 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cb2252cfbd249fdb47c17881410f44fbdc8cbc0f8a8e79b8c973a311f77f3a9 -size 33053 +oid sha256:633165e86d70889024469309db5a4f44eaa00456f0452e6c1447ed7e24b7bc4b +size 33059 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png index dd98b758bb..e3e06b6a66 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c57803651c508e3d041a1a99cb3454935f2d7ae36ef82f8d0099c00089c96af -size 14041 +oid sha256:6fb2d663532efdd393063f3a1a53ad0da2bad91033dec2d6bad971f681a56a45 +size 14016 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png index 82f1f4484f..986ba9ee23 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a3693f62c718cb061106b0c33e162d4eb82efc766aa81d164dc860ec4394a17 -size 28611 +oid sha256:1e030b3d98c9d4e6a37a983b180e664b45697705a966bc9348ea432e123a3b6d +size 28604 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png index 48f2d5d109..27daa2fd10 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb11c46a91a1fe4e2227a6de21d418e698bb70ce68afafaefc5280a979a86bf3 -size 29114 +oid sha256:d75bae2ae2ee8a407d2b4652d699e664e619cffa5a7888cdf6169395abb97c6a +size 29142 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png index 900343f7d4..c1dc2207c0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2229208fd03717884b2af74aebdce70411f50c0b69a47093a6e8346dd9766610 -size 34892 +oid sha256:13fa1f840184a20cea94d1cd9d76480eda1c458225b4514e37213080c936d3fd +size 34888 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png index 5b4967d6f0..c45e89835f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02fd7d1c9b3f982c2fbfad109c55bd444ef183855800490cf9117606b493c314 -size 35018 +oid sha256:5abcb5badc21e715c6f7c4330e5721b0275fdcc678ca3920ce64ae5d34829250 +size 35005 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png index bccbae96c0..23a8c73c75 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:18589707589516bd02024a4989b47bb57204bdc77b882ebbcfc0b79be6314c9d -size 14173 +oid sha256:772d4d50bbed5bc5cebc8f636ce952fdc4951b714e4d621030a87db7a1df9c01 +size 14162 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png index 8615c02572..1ce40f977b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aaaa719eafbd61ad499b9dbc7d1ce1afa3d1b3dfc8e3a170b2f785a51684802a -size 29424 +oid sha256:e3cd5c467381c74c579e62405bc6016da1b9b050365d04a335845a19d1ae2c41 +size 29448 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png index 12c6450dea..3552000829 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bef80d54bce17851bbc1d003055743e1c7e95b0ee069261aa5e2732e7b722e6 -size 52319 +oid sha256:2aad1e4a3ba3691a37c9a2df872609ce7b7cbfb326deca6e5a81e6a0a50fb19b +size 52305 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png index 41adebbccb..fb13cb54ab 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6814fb800186b8c0e6d2c4c07f2f959a5962a94fbbfd1c15d83d2a789457d930 -size 49646 +oid sha256:bb5f62cf093e48c40732d801cb27c51005c82f84aaf96ce86e5dc50c54ff27cb +size 49589 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png index 322b98f06b..42cdd40e09 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09b31e87abee30225e796c3232b84c4670d57feb19c056de4238f60329e036d9 -size 50315 +oid sha256:d4954c0ae06d16a0058b88eb9b648911eb0c8b36eba19e40031bcf5ec6c262ff +size 50257 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png index c685dd2cba..568bdb2d89 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90ff5065ec23e1c835ac395015e0f5491d44722262951f72a19a184d9e3a47da -size 40245 +oid sha256:0623f68ed17b1d7e39b2737255a2f3d5448a984bcef00ee58558a7581af84074 +size 40173 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png index c685dd2cba..568bdb2d89 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90ff5065ec23e1c835ac395015e0f5491d44722262951f72a19a184d9e3a47da -size 40245 +oid sha256:0623f68ed17b1d7e39b2737255a2f3d5448a984bcef00ee58558a7581af84074 +size 40173 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png index cff979f7a8..44650d97d4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a348097d43335133ff83958b0b1dc24de2e4aae0fa2be6d000a7ca78516964b -size 55172 +oid sha256:9357fbad1987326b891699fb5e176e4458d1b7dbe660df95d20c079d8f38bc52 +size 55154 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png index aa81a4ff8d..0e6271869c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0aa744f1d069c68202a087789328c1ac46c45d6fb9bae8b5593bc477c182dde -size 54182 +oid sha256:840b7a0a23d458680f59f328d2a8b756e80ab76e368d749a511e7352d31d0f4f +size 54196 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png index cb710c9dcd..7c71ef8088 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7edbfc8e9e8bdcea6897860d1872fb8fabce139ec8610ec6180b28ca9ce9007 -size 54976 +oid sha256:062f857b2b2339f54543b70a864786b1463747cb7e45db54f76b1831938dd98f +size 54984 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png index 7b79f5ff42..31b2eb0efb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:380ae6ad1fa6f00427eb7267a338964b6f77a4d5f8c45c25f535502481e34cc6 -size 44834 +oid sha256:63070cf809fe17adedc37b9df0b9a421c453d09e8edd95869fb62f4b1b066a16 +size 44827 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png index 7b79f5ff42..31b2eb0efb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:380ae6ad1fa6f00427eb7267a338964b6f77a4d5f8c45c25f535502481e34cc6 -size 44834 +oid sha256:63070cf809fe17adedc37b9df0b9a421c453d09e8edd95869fb62f4b1b066a16 +size 44827 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png index 50a0dbc183..0ccf45d0dd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:830ead63e3965435fc6fff2c8aa0c83d2654dd151972d8d88ad025dab2ff2902 -size 38536 +oid sha256:b64a7ad8a711dcb67a5b130bac5f3083421ff79b4476060fa5f54f3b14dac173 +size 38511 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png index cb2e25b07f..3b48d22222 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3598515dc84276014c2f3827f533c808a2683191a67e7a68191501bb848b8293 -size 28326 +oid sha256:4e335de03505f63e0b02ef98b916a1fd979b32a58f3c91bf0dc6194d6b66d671 +size 28302 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png index 7902cce465..1e64e85760 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e433bf7d2f96067dc0743e262d8907a45f0e404cfb307a018fe671dcee9d5f02 -size 37054 +oid sha256:5366117e506df73eb6073bfcdc76738a89262c4ff83182a381c50b98230c71c2 +size 37051 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png index 0311150ab0..53b1988ad5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d00152b1ff92d93564af11537dcb8d77116e943cfa2b45dee2c66260284b8807 -size 26875 +oid sha256:286f4ed93711fe203aace6e629971b6681ed74cb2a9cd7cb8544125144d4fb17 +size 26867 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index d6ec63a2fc..d41ab12fd3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5e4d1ba12c6372c7d53e3d6a8a4d11e2882a16d1dad0899248b5663557bc359 -size 26999 +oid sha256:98bfdfa99e207e5f50aa6a6aa08914b8f2be407d5547f39984a0a3e05d41bab7 +size 26932 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png index dfdc242956..a6fc15351a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e10d7e07f854017d9fe902649d66dd30b39624a0667023962004236986c30b2 -size 26540 +oid sha256:05e62d2584c3eda7e22068731de56223393e869c8e91ac547a148a7f84e870dc +size 26485 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index f2759edd0a..e7d3a908ec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57776151ae74ec98a498b59ee05841cfa50c6cb657c2706e54a7deba058a2a0a -size 26530 +oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f +size 26473 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png index f2759edd0a..e7d3a908ec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57776151ae74ec98a498b59ee05841cfa50c6cb657c2706e54a7deba058a2a0a -size 26530 +oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f +size 26473 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png index f2759edd0a..e7d3a908ec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57776151ae74ec98a498b59ee05841cfa50c6cb657c2706e54a7deba058a2a0a -size 26530 +oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f +size 26473 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index 6ed0384bfd..6b74783202 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e1503c710bf466e643720c73387d92b38c34aed007b34153dc5170066688dee -size 28759 +oid sha256:080d58220454a98725f418f931c6e18c4af11821076d8cd446525098a52db6d2 +size 28739 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png index 0754809b7f..2ce5fc6bc0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a104e7f7fa15a31d9d6ebf30e6a8e59ba6cdc3155cc7e7274ef63ab6bc884473 -size 28164 +oid sha256:7da900d8aab1134bbcc472104a876c390f156a9531f1f3f7d57e2e9211be5ba6 +size 28146 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index bcf6d823ab..24919e87b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da0a285163516046676b6a0f5d2660f03be7a9c08209e7198d2d5726df2cafa3 -size 28230 +oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 +size 28198 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png index bcf6d823ab..24919e87b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da0a285163516046676b6a0f5d2660f03be7a9c08209e7198d2d5726df2cafa3 -size 28230 +oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 +size 28198 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png index bcf6d823ab..24919e87b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da0a285163516046676b6a0f5d2660f03be7a9c08209e7198d2d5726df2cafa3 -size 28230 +oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 +size 28198 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png index 1e577f0904..9572127bae 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0c32a81b2e3c751a7eb8c60ba71ed4b53e73fee920f02aab63d35fa492be87a -size 25266 +oid sha256:094a0f5436527308d2a37b52f6e0c5f12e267f214b79fae980e409da116a07ec +size 25277 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png index 5f41e9dfef..73180b7d05 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c47835cf1fc4cf11f183ee7e658d2a4d16a83b17b6a03750f16e660867442b51 -size 24948 +oid sha256:f0a29a48138febe8b13b1e1099fbeab2280f1b0567233614187d97117df05de0 +size 24943 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png index 9158fb98e9..722bd8c6a5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad2c0bb00b406a7fc3497117a89be7422390c7be16aa1f078c5be3791f8fcfd8 -size 151481 +oid sha256:f0ad6895582183b697732ef032f89a6a0cad32106c9bbf30925c390dcab65ee6 +size 151752 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png index cf59c8c1a2..fb9457779e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb32728cfcad251e3bd2ddee2a40456f329e8e3a910d145b58a3323322c8a721 -size 156825 +oid sha256:676b62ab782652c45a7267aac5df12943fd181bea48964d28dce664884ae4182 +size 156619 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLongSenderName_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLongSenderName_0_null,NEXUS_5,1.0,en].png index 56d35e8f11..4011a2572a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLongSenderName_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLongSenderName_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb071f845598b35931253304f4c9f4c865b5fe9f57662c03c88a0c94a7835d83 -size 18615 +oid sha256:82459b6a9a3882bcdba78e89f8938f3749d6fabb4673bd0a4cc953d2b7f069d9 +size 18215 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png index 1bba8742c9..923bbeea49 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:860bc20fb4c847183290adcf1f76d1a382b0dad4d3f11a987924a816e6b5609a -size 62000 +oid sha256:c196f9cb2da2366e4e67d59012f61c5f50a5775475230c3a0cbc8d823ba53dcd +size 63317 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png index dcb828c9db..b59ac27461 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70f4e9bff2565317041fd037c2a0d9bf596b0c67d04927e64e89f7674f4a9966 -size 64038 +oid sha256:59773d8a5435a37b3d47bf0c41412299b0b277af4be7a1a25ccb33b4b60a32db +size 65397 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png index bc89b7cde5..c586722f7b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:474628a1247dc41f3b17dfaa0174fd47b4468f075fc728d14419b7299d7952a1 -size 68584 +oid sha256:ee692fa3f3dbe4500cff084526a4537fef6444440c78f63a03d990a6a027f794 +size 69844 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png index 740f11b5bf..b518541c41 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d30f7b8de3ba0b44350eff2ebb8cd0d2572b435208673edbaf6c9914cf79a703 -size 70541 +oid sha256:0b8155faa2599615048193667f540664c7185ac7b6a9159afdc14dfb6286d62e +size 71826 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png index dd47e9ed26..7cc47ddfae 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:705c1bdcd680cd85759b9644f266eb0c1d343f76001bea1ac667b21ca9b9e390 -size 63441 +oid sha256:771343ea6a9d83160284b3a9248f744c68ab25c2ad64817269c3628a5ca67972 +size 62319 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png index 2744202175..903f4965cc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8307f0003cea667faf6d8fd57b4b650a00c6728d7bebebed22d7991a0c2f158a -size 65924 +oid sha256:4663107c550f193aa9bb23b6bccf9229aed5ad30c380ce6b9a326e6a3fe5def7 +size 64854 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png index 19023b2f69..60029246ea 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b519caf1e062d1fd9f3f6b0b122efcbe77775508fe272283cda71cc76eff9b8a -size 70408 +oid sha256:ca51c27cb553709458343bf16d8402a55eb1b7187b4b85191c3318f5b88c29db +size 69312 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png index a7f9730ab8..08348ad401 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e15b3ac5a03ddcd0bdd72528541a8f95e4fd40ccfa3bad2269b878890dc4aeac -size 73123 +oid sha256:b0a825d8090414c617780bf2d7332b8e80e5e4de066cd117c53f5e90cae8d4f6 +size 72112 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsDark_0_null,NEXUS_5,1.0,en].png index 6052944bf4..ee5176435a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5edcd092587b8c006f32f5da93b2658ca0ab6f0fecb17f617b93cd1fb5f4b03 -size 81123 +oid sha256:21f0f4844935aec3102efc6bda98be54f48e8dedbdc539907199e5f4edc3a9b9 +size 81343 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsLight_0_null,NEXUS_5,1.0,en].png index 757252b315..37620fce39 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactionsLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40fee515ef4e1bbc3cda0ccedf7b9c6fa48e040db79de5c9c40bdae6461cd018 -size 84907 +oid sha256:155baab65e9a3431f7afc8320e0b9ff12454a5faaef6c34701e50e7b0d1c3c0f +size 84763 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png index 7484490f6d..c39b41db87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe770a92f211c69118868e0fa8c451680ee30f64c9ddc99c426c13690a4b8c8e -size 127240 +oid sha256:b991a34a137d82ff4dedf48316a05ebbc008233984b11af70e64889a5fb5eda8 +size 127438 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png index 8b506e4e44..a6500ca748 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe1687609b8da30cea710072927512219d628e40b74ca53751c0560b5c72a9d6 -size 132412 +oid sha256:43b6514716d18382c8962520928d9d2ff6d0f665b2471e8a24e5d2e44a25c88c +size 132295 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png index c1d740b8cb..6f6070772e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f689d80043e7d5121d072b928c866a3bde0358b5d5df06e1d4f0ceeb9a11dfef -size 56344 +oid sha256:fe0a95b6c94668709c75052feec2953d310b8bcfda42758b2898e28b384ce193 +size 56189 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_0,NEXUS_5,1.0,en].png index 8474499ecc..93b0744c82 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af68664850a3604c8df21d0395a0ea06ad7286a5ca6889c4a2814e61003f14a2 -size 52312 +oid sha256:e40acbd30f8d9f815161b6a3ed1646733568015f03ffb0f24efaf6ec7fcdad6e +size 52145 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_1,NEXUS_5,1.0,en].png index b9c07b4b9e..021bf7cada 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1dbc2fec7de4e8ec1cddce4f2c8522b74c3ff4c8688170f8188412ca7dc7b561 -size 64049 +oid sha256:fd2166469e00817c11b429c3e4c8508f56aba93696bb182310a277873e8ef080 +size 63847 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_10,NEXUS_5,1.0,en].png index b2ab3a2244..f3e8bdfb28 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9329845bb7ddd9cbdf6756061a442d5a227b0acfffc4d372570245422ed2766e -size 50300 +oid sha256:53c5d2bce5d3502d5b09610faefeb68d20514076ba4a8189f7fc8f41c8e3174c +size 50150 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_11,NEXUS_5,1.0,en].png index fd56993e7a..2c4900d9e7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa69e3166a92a13a1b263f4040fc2431a33d52a6542bc809fc026e5a7dad3cbd -size 67359 +oid sha256:1223ea8bca4d42e8f5a6cace4a530055df5f6f0eea02c62e9b35104aff7408ad +size 67145 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_12,NEXUS_5,1.0,en].png index 9ffdb4df92..3138d3ee2a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ef257207d4497ea056fa37bff1ce9bff7793517d1ed83bda82fdaf2792147ce -size 57441 +oid sha256:48784809032f7474179742d8cf83986a366c62e1678a2d2f4a94e09856ff6302 +size 57274 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_4,NEXUS_5,1.0,en].png index 411213a72b..ef3c05fdb1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b03bb08a6cebdc1adece3deaecc07964d29f893d151ab693b490af1c9b4078d1 -size 72362 +oid sha256:ed11b0598ea4b2a991bbf6188372c33f35a3a661785ffdaefe4ef5257576e460 +size 72181 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_5,NEXUS_5,1.0,en].png index a41c9434c0..83b1c4316c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:160f3917d6918f0f5be4bc39d537528dd654c8e26ac6e3d5b8020bb2ef132ac5 -size 87912 +oid sha256:5c1d4fa3e1f403c0e5cd7583f9204759a0cba7dc63b4d1bb5d6a889cfcd10ab8 +size 87675 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_8,NEXUS_5,1.0,en].png index c071274718..0e34e05ec5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0725e61bc775166de6d82f5730e223ff9d10f6ffa3e7598a17fd3cc4c2af434 -size 53848 +oid sha256:edcc8b013786ec7b316161deb347278085fa196520b2d4acee74b5e2b426efc6 +size 53677 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_9,NEXUS_5,1.0,en].png index 30335490d1..89f5efe6e2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1bc72ead6dc9f348f5bf2dd1cba24e2903c990a85414f6f155437bc0237e7ddf -size 66060 +oid sha256:d9ee29be03d3e25834cfa50194ae8280b09fcac2dbf8fc79416638b36ffd07eb +size 65852 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_0,NEXUS_5,1.0,en].png index 2b0a249003..a9b5cc33de 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e28eec0e60cef1d1234ccae1031413105e2291f1367537b9eb36b038402dd29e -size 50314 +oid sha256:bdd5697196181f91a5d36f8ec4170d5d8668052f67478d22f0c2f1d39ed3cf37 +size 50397 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_1,NEXUS_5,1.0,en].png index 38fd06b5d1..15a02387b7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef4295d36c3fc110ba5b04032e4fa71f39879d05e368f6eb88fadba7ffd501a5 -size 61306 +oid sha256:b029a486993477abddf2cd602c5b935dd1fa4b22d1df5ef918c428f5714ca6bf +size 61327 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_10,NEXUS_5,1.0,en].png index 066d89473d..7b2dc3f516 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23703da549937fc871388f12a07f0aca70095273cd90f0eb21bce9e89500bf81 -size 48528 +oid sha256:d9c28c48732089f547388c779922c3cf3dfe1c41d5d38df93366ab6c0a546327 +size 48617 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_11,NEXUS_5,1.0,en].png index a08f83f399..9e476a55e1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:015afae65070b8df055542730915e029dcf36493ed491f23a801861547cb7314 -size 64378 +oid sha256:56e14c49836bd57eec889ac66bf0016da7e0c5bcdc9c51309e680ef77adc12ba +size 64406 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_12,NEXUS_5,1.0,en].png index 710a494e69..b43b1872c1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc3691993fab8d245c72ab1d3318f73c36f02709f4a7fa3abb664209947bb257 -size 54972 +oid sha256:cb26b5d108b12720d523d2912b4f71a7799322565bda95087fc8cf52a6bfd2b9 +size 55070 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_4,NEXUS_5,1.0,en].png index d51df54093..2a2361797c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33ae97a6acd31df8419b2066b86d97628151a3aed0464abdec5fbcb4028e3f9d -size 69435 +oid sha256:27d7a635a477aa1b2a4d0ae657333ecf55eafb9a84f29e5494526a64e7c085a0 +size 69525 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_5,NEXUS_5,1.0,en].png index d1f3020e18..8507c48fa6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74637c58a18194e1d3af5d3be5755cda81107216732cf8064c49a3dda346c487 -size 82836 +oid sha256:8776d4f031fbb8c934081ac29b6b6bd5746bdd67edac0904e1468b76727ef541 +size 82893 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_8,NEXUS_5,1.0,en].png index a4e5f88942..be7f3f8601 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:354d3112e77e3839dfa894f5baffc68c61795592d3f17a3401595dd47a1c63b7 -size 51648 +oid sha256:60858ea74ed5fe4ef865ccd3f0290edd32bf87ad010f5f7691153491c163c42a +size 51734 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_9,NEXUS_5,1.0,en].png index d997157e7c..d69df0df42 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b988dd6ede4b8e7fd4d488677bf1cb2ab46c2a50f30551268d1573b1466633c -size 63282 +oid sha256:4745bb37c991a9a90996a9ce8975639cf5fcb2d8981d0147d6a3445650d63620 +size 63304 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png index 3f327480f0..08734109fb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ebcbfc34ae17c122d3372d3cf5676c95d1c82db8c23bec467490b1787e267bc -size 51288 +oid sha256:39b527075df2b3f7afa4f3ecfca1ac93a180855b20d2bd64cb763fb98b0a7b69 +size 51340 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png index d8ec14e7c2..60f606fe58 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83d62d8eb4aadd86e7aa07076df9ea615f2f18b6520086bcaf44e9ae086c870f -size 52540 +oid sha256:81f196dc08f4de31f4257f6ba89c52ea41a97b107e7c5c04261188e6c572d4d0 +size 52594 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index 44c28c0a3f..6b3be5e81e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:937c9762afb8aa96715acb5239364f42ed0bc2afba764a2f15eadb5782803286 -size 51523 +oid sha256:a648d286a3b0536fc97801c3281bb8df432c7ffa28efff66f67cd6cf4c546c10 +size 51579 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png index ee186b8130..57b61342dc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87770ae87e7d8a74e04842c47d55c3554c348997e2c03fc65b67add3db7980c0 -size 53931 +oid sha256:7225f3510289f07d4c273e3bb179d05df0ac9f1a2ec868f061a2622c6f9d0b84 +size 54030 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index 951de46085..e2266026d1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8737e6006d60b361b5039c0989fd142554b09ce9847dc649139cb7ef9f901d9a -size 50597 +oid sha256:34f9eacfd61965cfde4f420fe6a0fc0d637a21aca0d4b12c6a6f1642bd44556d +size 50586 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png index 0f04cd7988..040fa6c12a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d71dea06589fdd8b62843d6898a74eff256ed0206ed8ad1ddc689f69d145a72 -size 48869 +oid sha256:c336a9cbc803eb314aa9333719d813ae64994a75344aa363b25aee8d52551b21 +size 48928 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png index cf1b87bde4..a178b31231 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bda5e19667a7acab4f72ad4dc10fead50f1f3373bd67b6db82eee50c3b53fcdc -size 53096 +oid sha256:5d7148068516b5e3299cce2924ea3cb54c8f1ddd6378e48b0fa746217a547d22 +size 52940 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png index a3785ac776..f4a3738cf8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8188739ddc45610d6539592e7aa62a679436f90248b3eaa95ff76b7da808e6e3 -size 54453 +oid sha256:b8aaf2c70473711a24bf587ff524fd71d43c2610ade1c3d4ff2013705d5670b3 +size 54314 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index 0be5726cab..f40d649d64 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14d058d0867360a6648876572001087835a06aba20710ed5381bdf393ab5e3df -size 53409 +oid sha256:566d5b197091d4b740e1241eab54017fd31e65f570def4b8c24ade19ea78ccc8 +size 53254 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png index 4a53e5dbbc..cd18a11803 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2485a5713950429ea18c4a7275c2b86a214e45f100116a93c1252b4011aa75a -size 55956 +oid sha256:c9f686208853c864a9aada2c809a43e1de230e422e93af7c6330b8e78dffffec +size 55730 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index 82e1cd0fea..4e0d1ce4bc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf7a41495ded2f16c86fd293096234ff730dc9bc84814aaec98b01fb9eb56e69 -size 55402 +oid sha256:8353077959916fa85046d3a81d1479d552748635f1286bb8bacc6d922ba30f28 +size 55312 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png index becdf3d51c..d2ac508bf8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87ab35c42a7b42a2625625bc99575ef37d54b84256554ee2e2b5bab80bf4700b -size 50465 +oid sha256:a84dabfdcbaff8de5c30472676dee2cee8dc0f77469f2802dfc796a87bc10dff +size 50328 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png index d590c4eb8e..5fcb6cc260 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72eee76cc8244eb54f147fc589c7b200dc3a46db4ea7306dbd6757918e4fffde -size 39744 +oid sha256:46bdcc0dcd5dd9ae0740eeb0af0b0587f1989689ec744c2f38cb4813c860bfab +size 39711 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png index a3449da98e..3b7938f529 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8796e5f70cdd09087ed22ede78c3aed985dcd57e073f68d83dd5884e4f29a2c8 -size 39042 +oid sha256:ae44b96af239aee5fc7839df08f9298490add53d76c51f4778d2af4d57aa746b +size 39043 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png index 370689a2fc..f973a24462 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97250f48dfa0cf2320f837eb87ad90d8a1e73642fbb2d571f326d689c4fc10e0 -size 42373 +oid sha256:66cf5b700fefe4839d6956e83d7590711bc38a659e41d0aff829cf877e7dc209 +size 42351 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png index 6bf7f8fdb0..e400a8de25 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73f2811197c014d91834d39dad1fe18abdaea9b2510d8deccead39c10a1b5aa8 -size 42473 +oid sha256:9372f8f7e0a173d680fd860fbbe7e4319409b82b02cad8b83eca2059fbf35bba +size 42486 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png index 8bb0a53a37..f7d8135d0b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9048da25ad83e544de8dfa2ec910b7650e34c78a0864e0e1f9644fa18a0ffba8 -size 13144 +oid sha256:964d97909629c1228e96d923ddb478735475839b8540c02142444f9ebd5bf400 +size 13100 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png index 8e68fdc6c1..bff7b81448 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58660c588499291f198046058bf725844bde74a7db4c371d29ee43fba2780e04 +oid sha256:bd8ff4a09babf30be0eb3c336f3cbe6a1508a21696512d0dadbcc9d543e6e34f size 12356 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png index 754ea0cecb..fe1fe39c26 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d4ee26a608ba57aa6e9eca05d4db22a9135243a73faf767cdc10ff0252079a2 -size 12887 +oid sha256:85530997942e39ce73512513ab0698494778168bc28cfab543b50b721c1807f5 +size 12855 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png index 05e82479e2..23211c9508 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8daffe981e83c5a81b60ec1d00d09a12fb3a67d3bd957bab5b0b924480330bfe -size 12952 +oid sha256:2e0a638be5745c75c2663116877d380c83df093d226d2c969d4f6620e8cee109 +size 12965 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png index bf92475b4c..3703690be4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9e26aa62cf66b8fc92025cc7cc4cb4f1a8f298edb1b7ccc2597cb8fc16cc876 -size 29888 +oid sha256:48311f503e47fc462a1f4d5afa2ea82c0e0eef99aaddea9cfabf5517af37bcd5 +size 29796 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png index 360298acc8..d19b6c9ec9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d05e01f9c8d0a6173debaf8b6a8491e705b19b3dc0ec2ea133d6f59a210d5388 -size 23442 +oid sha256:1aaa12b291dc1e187835114eb8c5c49bb4eb5bf16d87b039272a6e32e16cc6e2 +size 23369 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png index 189dac37b4..46ed873359 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf8fcba0dff3f86fe7334b829e710f31dce67b5ca207474ac6b1a138568cad9c -size 28824 +oid sha256:82e2cd2caae9b20cb2e3990216b0ecdf0bcfde4478911f00168e4f936c223889 +size 28736 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png index fa4f813321..ac9817e2c7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6485d6e4eb3429140d73f54d99467b2058628681f3588c1462d59390ec7b1bd1 -size 28562 +oid sha256:b2cb829eadcf07760a073af775be6d15e91624a9366d7bde366d7c9cfabe2c9b +size 28456 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png index ff4c6d9a78..ade52ae50b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:922a88411d9c53be79d4c755c977e3a0102fb5a91003c57084048b1597ac924b -size 28878 +oid sha256:e142fdf51287c82112267ac8070ff4d6c2fc3f92c14c82c16127aa1822823312 +size 28839 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png index 6a122cd7db..abb2875d87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8911100294fac69ccff4c6d90df5b72e4c45590e369fba3cafca77a0f31b4927 -size 25049 +oid sha256:447fdfc57825e1da34d294b7e212984b088e283810fe961c5b21b66f3c770cbb +size 24971 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png index 4bd5c9f12a..9fa729c209 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ee4fc0d07c55e3729d2cfa81f1304e3553ef9927dc4d7893c9c893b3e888af2 -size 31129 +oid sha256:2b27f3e2719d238b61a8f83264417c9c2d9e561bbaf12eea20f9169366c90489 +size 31076 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png index 703e90febf..1408e43788 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ebeb7f5a99059d2a90acb98f6453ae4b9292ccd57a5b17239a58c6e87d83cdd -size 24410 +oid sha256:b5b4b04d5163e8acec4f156396fd239296b7fe3fc251fc5efa78200f4b6a0e83 +size 24352 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png index 17c8b03f44..1dddcbf124 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a90489e5bf9bf1509f17f4f5e36c2b8f72b15e0b9120c29393e6f9d394a58d47 -size 30842 +oid sha256:61b56cbc0193c9081ceb3c8662afc2da8686a7de4a3e8ed12af2f7dadfd0328a +size 30784 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png index 2014be77c7..d108a47a92 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88887436882d7a079ea677bd6a3a947f44c961b1715ceca2ff3955dc178ea675 -size 29767 +oid sha256:f7ff9340f9788a65fe6ec4707cba125196fed08bb57ead4dce8bce2efb70f1f6 +size 29714 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png index abf7196fb4..68b91dcaaf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed04dcb3e6b3dd792b6500573ee60a64fc08fc6f767e2bb90f54518bcdab385e -size 30862 +oid sha256:3ab65feb9ba77f6a08e52fae42f32133845f169c651049e90c32c3abfbd8cea1 +size 30835 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png index 4c4f348533..29f2bfe96a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7470928e4f59c48239d7936805235e3deb04fe5c242d4a5c173649052dff1f5b -size 28255 +oid sha256:bf0735290b594857c52df56f2704b3e9ac7bae00a61a26b956febd5c6679357a +size 28228 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png index 56593ba4cd..774ae616b9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a07fcc59d425bdbe449537e69448fa4603a69e073c88c2e8b8bc6f1719cd18b -size 28638 +oid sha256:41c029826a7f0d722ff9493a287dc45ed01c4e0f02e1fbdb4f69abd0b762b5ac +size 28592 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png index fed3463750..4ace7951a5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8321e14c29391b34ab81e6b85f8e095773dcb00e615329e41032a057f2a0d5ab -size 26574 +oid sha256:5b4898e10aef39b1e7e9d16d9f214fab756dd203403de00e263a6049d4ff8b86 +size 26594 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png index 02e6fae1b4..1d6c880873 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57eb5eac361c61478e9352b7cd92c37212cccad2f1de2c509f06097eb0ef999a -size 45353 +oid sha256:473160d4ce97eecd9bc9ed67011c505e536272ce1acf838516c34f3b992f74a8 +size 45367 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png index 7a817b8991..866984d7e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:783ad0f124f4f385eaa556ad80daa0621fa6251622c16da8be47dca1937c4ce1 -size 38600 +oid sha256:b20115a793c0b021d077d816061b5b221f8e40581a6cf715fb4701941a38c207 +size 38583 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png index 9f479f3f6d..36b034bdb4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b013fa7cba8393ec0defe267dcd64427ed2023ceb7a306ad96b9cb03f63a687e -size 29609 +oid sha256:695041dfecf9415914d4f642c81154c8f90c8460bbd5c2023c9cce91352d2245 +size 29528 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png index 7fee50f122..9ac987f959 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a00fde670a39c0cb6e4e12185f9790d3394be743b034fdd1478824d594812f48 -size 27550 +oid sha256:2f8b8e95fc48731162ddf10a3b00bee300ba6fcaa02ea48455a68ce834915b8d +size 27532 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png index 7fd2027c56..a7e212f2f3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2dda676216b8f97ef36f02f7bacce4e605bef3c2fa521fbcb59745f27fb36a34 -size 47139 +oid sha256:867deebdc8a7e1844718508501e05d1f2f811f9847c60815fea86113ccb82bbd +size 47057 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png index ffb9c0546f..b204cae7f5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc2746f63bf1f5baf6b0a2595adc67063bdfe958596be405ab5aa2385af0cfd6 -size 40697 +oid sha256:2d99677b0930567cae7f6e356137ed98e701ff9ed2a6bd8aad66f9d12d8a1f27 +size 40726 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png index ab649faf22..ba78172dd9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cc10ed03f4190d4d66f0ece4a4213db4fc071a7bb7867cee3bb1e17b44451e9 -size 19589 +oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 +size 19574 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png index 07e172f24b..3a070189ae 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6234b7193211bb6b27a174d06ff9bf9f73143c7da668c113a2ae3ac6606b8f6 -size 17393 +oid sha256:29fa748333d5bfaebc2877ba66677687a0ac40581c1a4c61bc7cfd67f627f85b +size 17375 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png index ac8594070d..2245a0502d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8b06ea0eeba1a6603bed919934c6869709f948d1dbc6b8333f10be7493a7b97 -size 20005 +oid sha256:dc56b1324ca0206fe25eb83b1bfc0ceb559ec86581227e3db766ed52c4b314e1 +size 19992 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png index ab649faf22..ba78172dd9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cc10ed03f4190d4d66f0ece4a4213db4fc071a7bb7867cee3bb1e17b44451e9 -size 19589 +oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 +size 19574 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png index ab649faf22..ba78172dd9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cc10ed03f4190d4d66f0ece4a4213db4fc071a7bb7867cee3bb1e17b44451e9 -size 19589 +oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 +size 19574 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png index 5e20da1ed3..e366ece74c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d4cc58182afd5e7883e2299e882842e252d9d650ede8d692cc5b55d86f0eaaf -size 20597 +oid sha256:84218b0e445d477223d7dc7aa87e043671b6c4a5ce24f431af4860ba04fc8f02 +size 20591 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png index 3a611ff2b3..9aefe59c7c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d06cfa869f95b907f72152ca550536755cde19a9bf14b083ebf4c162208514f1 -size 20037 +oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 +size 20054 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png index db428f07ef..23ead15fc3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3c0aba4502aeee24df94fb526fde10f7b8b638dedf6a6330babfcd168845d53 -size 17739 +oid sha256:85bb085789a6c4fa5cfa4379ef19eea470b4e7f276823362cb06f49903c01788 +size 17754 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png index b3db394d03..2d1bd42c0e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1217f1e8fbad860bc099746765e7321553338b2e49e55458c55ba331c179dce5 -size 20494 +oid sha256:d21c65c4d5c0070c8a75156cadfa8b7a6f97a4ea8e2ab8b52339792a21638c63 +size 20512 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png index 3a611ff2b3..9aefe59c7c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d06cfa869f95b907f72152ca550536755cde19a9bf14b083ebf4c162208514f1 -size 20037 +oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 +size 20054 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png index 3a611ff2b3..9aefe59c7c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d06cfa869f95b907f72152ca550536755cde19a9bf14b083ebf4c162208514f1 -size 20037 +oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 +size 20054 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png index ee7132040d..121f05a71c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ce5ba511326e7641dfeb27dcfb94e372a75c6265201248b52d88d977fc8e61f -size 21056 +oid sha256:be5e1b77f5a7d9673f4c498a99e40cb633d536de608408a54dcb78fae7434d45 +size 21068 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png index 8affd2826f..592eb43fad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3dd75d76dc7e0202e2ee3aa97c81de15f595776402c105cad3dbf55db44720a5 -size 38338 +oid sha256:c59cb5eb1538494a95a4dd531127afc8cae252b08c7812bee79db4b32cce500e +size 38214 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png index ac29bf0749..5e988eb0b1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d002a12bc5821e0cd2838e35d8a74ad9408609acfc8268b002f2066dee143ebe -size 24925 +oid sha256:3535a659e893592ba4010c91049f0595d900d9f0aeea7bc2cb8317484bda58d5 +size 24897 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png index fafd4618fe..8ac709d1b5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:affe57ae0e4a387770f7776ee22be35cdc2bb9fb82281b1c9efdc30e302a64e1 -size 39529 +oid sha256:da07b9156d4e27aaecf0d3860d927660a688f46caa305940f57ae2f783402c8e +size 39429 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png index 4dcd4e578f..d8fd92355c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c4c30c30dbcbf0da1238096ea9bb152f4a691bcbf02f2aa0ff31720309a8313 -size 25608 +oid sha256:3237f778a1be6d86fcc107942ed8d19d38f4c332c1c307391b70521f9b11c8c8 +size 25600 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png index 77c1b4c04a..0845a2a7be 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8502e633bb26a506693f80ccd438d47280aeb7bc238f25a3834d06a290e7c2ce +oid sha256:2673fa6964ac88be99edaa839a8684bc459b029d210b96fdca698fee569d36f3 size 54613 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png index fbcbc79691..0dc50f37c2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f82980c426b2374c6c7de0c1d0cabc56d721b34660a0bc2902871a6c4556f7d2 -size 45257 +oid sha256:20e630b0f3bb9fddd5f11e4e9f2a92b5d35c4bbe182662e8d0fde27451297006 +size 45247 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png index f651181262..ca7b6913d5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15de254bfc9ed30f47d3195a95082af0da1feea68ab703e29ca5c0cdb28533c8 -size 46092 +oid sha256:553b498247e9da02ad037716a67c080a3da2fb07602b0c0c44de8f16a4891eda +size 46086 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png index bb20f8c8c4..57bdb33e14 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b94c7bc6ff6b3e525507529b73088e8f73c2f094ad1e521c7c1f1d556c6e935 +oid sha256:29aef78fc92caa5283a6c066088d43512c36364ae01709d5d7182f6bf11f52b3 size 48496 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png index bfec221901..570e9977a1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91062f451f97a21fbf1ca703dc595a093433b02e7ad87651c6b4499cc374143f -size 60188 +oid sha256:20ebfe833d0432d25076c97aaba8007fae940f70ad4e39502e4695e59fdf4c5e +size 60182 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png index e49accd332..b0dc0b4495 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62925d3679c26248a8a8dd3f71d226cef760e2191ff018d71f482ff302c81980 -size 60411 +oid sha256:c31e8e9d8971b8ef0e4e5a5b7a909baf4e65faa18d50452b38cb109edd193de2 +size 60401 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png index e49accd332..b0dc0b4495 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62925d3679c26248a8a8dd3f71d226cef760e2191ff018d71f482ff302c81980 -size 60411 +oid sha256:c31e8e9d8971b8ef0e4e5a5b7a909baf4e65faa18d50452b38cb109edd193de2 +size 60401 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png index c5e5b9bd70..c5444af671 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c444b237d087b863b2ee7279a97433c0e66e80f3561e195453625f508075633 -size 49413 +oid sha256:c159c58e5fa811e63cc8396f0b6910dd62945014c9a645e149b4bc88b0527dee +size 49416 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png index 508dee85bb..8e4244ccad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4f35b517edf875a7d9b780e050ff409cef3b1fe15d42571d85256adede78998 -size 54870 +oid sha256:55d72a6ef38f3822131425b56fbb02cad52e836a94cbf878fc654b1f893f9571 +size 54866 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png index b15a56c1e8..90756f11ad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc94103988c32e43ea7cf0f350637641b2a3687ced38eb6a5c9deec449cc5b45 -size 56789 +oid sha256:0f1681459983d04b98cfb583679c1c44504e0fb05d9cbcab90c149de04a91ae9 +size 56779 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png index 54f59b053a..852e18b044 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:375b26ca9b248a7d60aed3c3b1c270971e0c944ae281c03aa33fc40d3c151d32 -size 47297 +oid sha256:6f65151d983057ca185c53b4045fb33675f12730fee1b40e3df6d269e2290a05 +size 47290 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png index 22a8280dd8..89ce9d4604 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19607983cd3005f2d187f40f92ff4fe654ee4fe7d1a579246a5c54af34043210 -size 48370 +oid sha256:de6a5ac50e8b30364b9e630d2edbe49c18cc3684da080e2167f41bd689f17700 +size 48369 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png index c417113267..652fc31f8c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8835bd5edacdbf3db313af13f811f9d5e832cb0d248e29ca19d46f22a2e995f9 -size 49660 +oid sha256:07dc159ecc1cce762240c06902690098a3f84a651272b3d51bf2ebc00951d16c +size 49655 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png index 278b704bbc..5496c8b265 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7654d7ca36112fa73bbb03904cdb93fdbee9507dcd23c7998659a7f0185eccce +oid sha256:44f783fc10ca0aaf56827afb1d2d9a24694e5d192441a8a9f9d1507326d7de94 size 62479 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png index 8a06e354c4..9e791b59b6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0adc2b1ae404c4c1cc54fe70326043df9c68ed23029e679461f2294b6df8f3d -size 62518 +oid sha256:b6c8cbb0c5ae7a9e4d4426daaa00c2625731fa93d7fc05bf0cca64d1d7833ec0 +size 62536 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png index 8a06e354c4..9e791b59b6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0adc2b1ae404c4c1cc54fe70326043df9c68ed23029e679461f2294b6df8f3d -size 62518 +oid sha256:b6c8cbb0c5ae7a9e4d4426daaa00c2625731fa93d7fc05bf0cca64d1d7833ec0 +size 62536 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png index 2070b2135a..3e8e0372e9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2790af60ce68930b750508f433cbea718366ee8efc7a310af10719f0f2fe6c25 -size 50726 +oid sha256:210a21565a6b4bf56468125338e9270b9ccc48ce06d24c9eb48f32a027ffc0a4 +size 50720 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png index 3ad38a0cd5..9d9e068cde 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:062d7de096cebe935df18f5daf9b8bcdf93057d6979659f6bd9ed1ab8d7b0c7f -size 57035 +oid sha256:dcf896ec4b058043d5b52065ed3e23549d540d2496e94df3c6c8226d68de5dc4 +size 57033 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png index a7e8db9f25..72105204f5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15b339b0c15ecf38f094378e8541fcf417fcab80291db47b061e05f12cf9663a -size 10567 +oid sha256:efe240e29b1e9565edf56390c4ed5cb67a7e342cdfb96361782dd2d5dd28c939 +size 10554 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png index 438d20a0ba..afcb237bb8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da7b416757518cff72cc5bb37b670855fe22119082201871f6fea0bb620a348c -size 10419 +oid sha256:62f986c59715c6f74b0c2bf98afe7ea9df4619b833919183863c2550419e8dc7 +size 10412 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png index 045521cfc7..96ad4b73cb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5586f03088e8571e1f2921721e23aa4415b8254a5785d0fe76a600de57c5fefb -size 12102 +oid sha256:bf5694071227c215dfeee78347b20575aab8456c97ba33129386fa7b156beee0 +size 12089 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png index cebcc7ec15..4e2a983e69 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fada88c1a80d3bc00a8dc88ba502744d151dfb9af014d3efea3f3d7500641f83 -size 9376 +oid sha256:9a186c8be46410cd829bcbc46f2e2360816e6d50f6476d1bfa5dbd970d9fe609 +size 9367 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png index abd40193da..fcf7318f4f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0abb3a07dc5283ae1411151caa4b33dfc4f153f70aa0cfe6a9287d47763097de -size 12479 +oid sha256:50826af8c22e844eca956ae277f09ff4c69a262507d32144313bb4638436a186 +size 12465 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png index bece04c505..d4ff97ad67 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf7e89a8bb33b5f9d17f04c35fc9ac78c362f0576333c82d36aa2929da9e8cdf -size 13376 +oid sha256:dd7d6642bde8e6062a2a87829741b23a18c9a08ecca3f8f1b291ddee9cac8a29 +size 13363 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png index d86cb78f0c..8a1c18bb99 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d16f977abe60656440752e82da244ada6de9dd2ce329679e7c21d4c03df4d306 -size 13710 +oid sha256:bb25fca8bf0a2c4567e1687b37c4eba72cf8d7830cb74555f4bcf72941c66b2b +size 13694 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png index 7010d8c333..7d4841a54c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbc96b4dc345f95d4cee8b2840431ac203e3ad43dc2cf3d8dce688dd4cb28ce6 -size 22111 +oid sha256:3b7fed22743d761141600d8c1f0df0ed9799acc3d2087d693da2fffe53605a30 +size 22092 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png index f841f89d1e..0d10b79070 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a09f04c04925b55b268f16a95ddb9ecadce377ae3bd593bb370488268b230b1 -size 11873 +oid sha256:b0959e717c4964cd8c5acf05fcbbadb2e44bee3217ab451a7b2d77e534be08e3 +size 11868 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png index af204846e7..d58e9f7aa0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63cf90f5dd21d3267bc1aa003861cbd375006176c7ab20285905caddbfb59e9e -size 9228 +oid sha256:17dd1974f121b1bf0c769cb005f0b1cfb57b11e8cfe94f752b4e9d491e554af5 +size 9216 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png index 23e410fcfa..7b034632db 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac700080f4b413f4b7ad1fdcefb5c6c7ce2fb0086f76c01e95946d77641f595 -size 12254 +oid sha256:d90d24f83b8ef1d33ddeefe7942728d1b8de914de97b5724f1413fc88acac771 +size 12247 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png index b9cf9a3e68..cf650bfb41 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:145e9daa38533395e411299d9aa2ff09852a8e474e94df20efcb24415934a8bc -size 13215 +oid sha256:193959145770210881785866b3951a5fc9c02f11604d96d2f4dcf9154b69328f +size 13211 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png index da811477a2..07acdce0af 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa5d7338831e74563c8d93c1627dd1236c511765c1049100370e3d0be2dc6e76 -size 13690 +oid sha256:a439996ea530d83c8f40baf0c4320a8ac21966cff838922e8fab926f7d3af5a4 +size 13683 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png index c9f2fe1d4b..5f190faa9e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8605388c16b1099f10b8bfccde3f5c84669fb252951425d56c2ac5d95ecff5e -size 22492 +oid sha256:9ff4b3f9f077ba9a62878463e3153e89e033bc631c4b627d31324d4f9af511e4 +size 22486 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png index c2f594936c..aebe17e861 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:519b00c507122ea88d0a43b9774faffba08bf9008208a8cb2e63c7fc4c7c0395 -size 30497 +oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 +size 30482 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png index 4d21322aa4..26664565ca 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccb53997d492a88ccd952a7b9e4832ef697b78853b5f10c5c21b3d2a3100ec3e -size 29744 +oid sha256:15198a0c45657bcfa1f945349b18106e3239def6e869aa000030e3354ddc03d6 +size 29732 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png index c2f594936c..aebe17e861 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:519b00c507122ea88d0a43b9774faffba08bf9008208a8cb2e63c7fc4c7c0395 -size 30497 +oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 +size 30482 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png index eba7c38ad3..40e658fe68 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b9ffcde3ac2129ae6bde0cf165b47ec42fb7c436140b5da87ccdfd203076a41 -size 35563 +oid sha256:e045c8686effc435e5d31b7ef034d93bca64a226d2e6ebae941afeb36dbad099 +size 35534 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png index 87a72dfed2..8a8da5a453 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3696cfbb10e89433efbf86d8b3c5dbfa4f3110e4b348811f48b73355aec7ba8 -size 58615 +oid sha256:a62f8d9a50f7d23bc355dfe98be0bc5eeb2b68866e3035b79b51591eae2f781f +size 58626 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png index eba7c38ad3..40e658fe68 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b9ffcde3ac2129ae6bde0cf165b47ec42fb7c436140b5da87ccdfd203076a41 -size 35563 +oid sha256:e045c8686effc435e5d31b7ef034d93bca64a226d2e6ebae941afeb36dbad099 +size 35534 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png index 034f8eef9d..28ec864478 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:113f877cb441ed9960785eb6b6ff37ed876f50e2a82e232d43130de50e171e90 -size 37464 +oid sha256:76b43763ca93e7bf31e49aa4ba98e9c9cb6d5ee2ab6dba573e69315084884859 +size 37433 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png index 9d2b285afe..a26740c566 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19b85235a764b18aab53b00e75f7513ab357cb8876d77912ba32c73fbeaf2762 -size 36848 +oid sha256:0451e8d5939e9c90ccef22a8384d80e7d83cf8faa8a7df4bcd6032d9f3ef394c +size 36884 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png index e5cfd4c10f..e7cb3b98e5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88afc93c92cf92ac492a82b753c53fde12e34b2e12cee8a67c40570388f33569 -size 37201 +oid sha256:e9220e4a8dca8924d574e9a5511f25f6c41d14163b58cb4d8f622d7fd8fc71ae +size 37238 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png index 4d21322aa4..26664565ca 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccb53997d492a88ccd952a7b9e4832ef697b78853b5f10c5c21b3d2a3100ec3e -size 29744 +oid sha256:15198a0c45657bcfa1f945349b18106e3239def6e869aa000030e3354ddc03d6 +size 29732 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png index b936e1b8e4..7f84966744 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b79fdca5780e49319367b0a9d8d965e4d8b290313ac68ae9035ef781bd55a49f -size 38247 +oid sha256:8d24c1170affdcae6f189ba2e6646fb61e01f8eed4d83340297f3f189c2f3470 +size 38225 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png index e4b351db01..6a5f613b72 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd7d4fe0a126ea90cde648ac9f461f1ffb715737330038a7b31f944be3814ccc -size 62183 +oid sha256:1cca9ca327d8a64cb04489cd52c52d3871bd583de9835eb266a1e60db8e53f84 +size 62191 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png index b936e1b8e4..7f84966744 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b79fdca5780e49319367b0a9d8d965e4d8b290313ac68ae9035ef781bd55a49f -size 38247 +oid sha256:8d24c1170affdcae6f189ba2e6646fb61e01f8eed4d83340297f3f189c2f3470 +size 38225 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png index cb279871dd..7ea53599fb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:684de1bfd46b540064668dfa54179705f8b3a0ef2ed2b34cdf17c5dafddd510d -size 40281 +oid sha256:fcfec887ae55ce77b049ef49880f1858e7a0a0ea2a7c81140c8c66069a598a14 +size 40265 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png index 57dac5e082..dfc6c1155f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0649ff24ba1b1efb8a310202e6bc111db19defcee2d86fedb0c7aa7ee860a8c0 -size 39566 +oid sha256:5716646f8c5d8e9488f79b033ffce5f337133eb78a63328ec616b8eb35d1c70b +size 39534 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png index b8bae6649c..d947e91005 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35e68fda7b2beeab9e716f10fa9a1160af7a427354e8809d7270740047e3f0ae -size 39930 +oid sha256:4a8723f12c2884d20c195a779cf6d48a08191f1caa0acdaa2324e478ecac92b2 +size 39898 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png index c2f594936c..aebe17e861 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:519b00c507122ea88d0a43b9774faffba08bf9008208a8cb2e63c7fc4c7c0395 -size 30497 +oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 +size 30482 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png index afc4d7c496..dd5e1401fb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a33d4b4ed08044b8f539914da03e0228e121c1f82f3b1f0acfe34f22dfd4f47 -size 17915 +oid sha256:3d5e1eec999486b11a48ae992708adb8634a46fc89114de463894fd5730330a8 +size 17895 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png index e0079e5e3a..83cf5299d7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0712f3a8e86eb5ba2588a03fe79bb4e29e2c6d341f80906d0b39301c694d054 -size 17361 +oid sha256:8a66c143d05cad7db2ca195bcd0d9a3007169c123c96f11fb66dfade6904db1e +size 17359 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png index 97ba3cfdc1..8321f05002 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65aef36778adb865c6320a13e6a2bb297cd8837079adab8524d656266ccc48d1 -size 19095 +oid sha256:8da740d8a43f978b1da59585326848fe18b71b7cbd4cbaecbf520a7219bf5df4 +size 19100 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png index 2083ced12f..7dc547ba61 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2a0967d18a75294f09aafd3b116c270b5c88d9e49a2918f6229a9d6f97cf099 -size 20277 +oid sha256:ae676fe3063c21680f87ba11f7f68d11250c67365a4da0541397c4fb635f939f +size 20231 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png index cf6ea92cff..c0d18e4417 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc3d57b23d0665737f57a2aa6da5133f08410ee12a9fa9112334357960889e3d -size 19021 +oid sha256:2834d0f7335480a35ca041091c8d7062d64501d52855458864505a1eb12453c1 +size 19043 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png index a41f70f1e1..7c3c298a92 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f1f23fc00e55e3ed3f185b931274656e23b5307b238c02188baf5a994d8ef69 -size 22917 +oid sha256:71ea9ad8c4934ee391d94836e57e06f5332963c09ed4c689c125337bb4f66504 +size 22821 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png index 1d8aac11ea..c6c2cca49b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e7a7bc8d46ac765cc79ebb456d789cd919a3b5270d0d682b6964d329525b1f9 -size 20845 +oid sha256:02d3fc1981a83b1635b89cecbfe2ffac65b070060f28050fbafcbb35fa4222b1 +size 20911 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png index 3aea92db8b..0f4969c23d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed96f288c1137cd68c524910fa461336694cd867f2533f92adef228b86738fd7 -size 16680 +oid sha256:34aab6f95f04977d64f97c5a9391806cae363408f011bd57a7a2954f6af6c5a2 +size 16654 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png index 6ec22f322a..b66d0a9445 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5a87ff184c790e5763c6a4249d4f6e3c2a4cd40308c35260578d70b7c6d3db0 +oid sha256:5222d968327e6de88f6f1f2bc02e47da51b6bd2fb2dc109279e5b240762966df size 15899 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png index 9d2ba67cf8..8a9e08a783 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9603c41811649cf758e94bd229ed2fbd6eaada6648adf37b7acc4bb0def80665 -size 19586 +oid sha256:677d553d6098e0534d81e7c4218698f8e0b9635225332d484108917332350494 +size 19540 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png index 9c3ef31c21..200d140d83 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84c1d472d23a09383dbeae496c9d2fe54aba37a1ff93e08da0bb4b419242e505 -size 18320 +oid sha256:34e763d9617c7023f3f365ca00e75dcc0d4e80a7a9a2c74bede55456c73f3fea +size 18349 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png index 779efb9dda..12f34d2fe0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8853a6320f11de9e77c115afd576a1fefec9b72086b9c818cf7a83d98bb3902 -size 20512 +oid sha256:7acf87fd6c7da93132c9c89974b6e82728b7aee91f078146ba9a002ed1ae261b +size 20457 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png index 144b992b4d..d6b341d0f2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00c21652a153330deeb12bbcd95968ef9032cfff38f9d6b325d7d98de6fbb7b4 -size 19256 +oid sha256:a6654898419c10c0fc2f96aa975295ac94a68bf1362c3ac955388e5f9bf8e67c +size 19301 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png index ce9cb0fcae..300f3e1ba0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:848bd4e8f7954582d803715d7b04a7dca6888c32c5ac0843e8a6880d1c99bd61 -size 16255 +oid sha256:cba6dc7fb2520afe1553ba63b92195708fd77f8ef852ecae0a1407e65970b31e +size 16263 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png index 9579b215da..a94d27f33c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4f8280513fd8b8f950511389e0cbdd8d1d45a78b5eb5b17592b95ff05b68efe -size 15577 +oid sha256:0271737aee4d0922d0613bce60098a921b1b9f717e9be68d5288f7bef07bd76d +size 15576 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png index b4b7bade0a..ae8c04c855 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f48d8ed65f7b190c5bd0ef69b07da3e8388697a04d2598aa642cf57494d762c -size 23333 +oid sha256:7ea7a72ca0a5e99b0c906342ed34830b7e9ac75cb1e370fc7c9eb33441492aff +size 23247 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png index 23d4f42f4f..203e9e5ca2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:744e8704616c4792d19f4b89b8fdd1ebab7f95c155344edcee839383f87d0297 -size 17063 +oid sha256:c1fbe133ecfff74a27273db57f40991cc3f4676f454a85a18162e0c9bc75b55d +size 17065 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png index a8e354900d..6d763a36c3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bec608ddf547a8436f7f2c7e707409d9a5375010a60f97228068b7255c78cc6f -size 16409 +oid sha256:9665e21d61256c77e239a587e45529edd30db85448bb768070d48ccf42a90c32 +size 16407 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png index 9655b03e8e..95df6d421f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b84b5f310a6d04511e06208eb638dfc344f0629c6cae50644a1d925e286917b -size 20737 +oid sha256:46ffbd54e3171340f0b6b8d632964b3b91480cfd6d99871c0f1d6bb7b8cfecc6 +size 20738 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png index 2f81f23152..59e8eac7f5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56857d24261e0385855825f310c1e76c4eb244957d6afc48657794231b2041ec +oid sha256:10989322060483d1948f297cf66d7442444f613e9a883fa1377941d73b57be22 size 20096 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png index 3f27b667aa..d455ea4877 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ba04160e69b6a05b81f121f64c375809006bf77899be22e3e4fe07a627921b3 -size 18853 +oid sha256:736bd589ada20b9ac5d653fcc78acbedf08d406c0aab7a8159b0bd52db49d8be +size 18774 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png index 42da6e6b20..3a075cd929 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b30a0deed825c98ef6be90b0b11485a76547a77959058ed816b133f9190b4f6c -size 17694 +oid sha256:1a494c20b5047c925aa60b8253b4ea1bd90a95013df3d711bded444f1cbb0941 +size 17683 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png index 707c54ca65..9b2e1e6381 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e4cc6b4362468eb094d478cf613b272cfe4b55db4be989e33e56d12dd886672 -size 14590 +oid sha256:1fed24563d497b368859de9de4e4c9ae27cb645d89888f7fa7402df64d447471 +size 14589 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png index a0d5273229..c479e6007c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e40bf3da586f0ecbfd3794d20fb5b1fc65f4b662aab920fd417a40c17c48326f -size 21308 +oid sha256:bc087aeecec205ff20e45fbe27003409591e9ecada4c2f2b4322537deac6b490 +size 21381 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png index 24b67b4efc..46cc322fde 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0971b7af9ec67b0c6ba30dd21a21e9ca780c87862499135afa104ffbbfb70fbd -size 14289 +oid sha256:4ff8361d32597bea90e830056f00846b9e2392685eb6ac000c8c930ba5c981cd +size 14296 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png index a957af4444..7165d890d3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7653f42cb5eaaaebcd81d3ccedcfdaebc31d8ea228f7c28d0faf0e288b3d7e1e -size 18762 +oid sha256:6e2070fbae74dff21576afcd623f73ceacd018b934d44247066f469c9690d2f1 +size 18679 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png index 0296201a02..92daab450b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bef3f8dabcaf1e4143e3b9f9b965f452d291704dc37b33f0653c1b85c17037af -size 17614 +oid sha256:86660baa06208b38f8201d9155a64fade6fb3ba49689982fa013488f8cbd6f83 +size 17595 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png index 60bc9b48ee..3c81ba86b6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3675b41c8caf7069d18e31a5f4a45d0bbb89ec6c468475e39441bd6108cba11b -size 19875 +oid sha256:febcacfbb96dcd0cf8815760409d105847b1fadc65e8254d386d774e41178a38 +size 19849 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-D_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-D_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..5c14f662d3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-D_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85c3b45953da8370bf043b3bfee87304b1c1703e11722c7c796a9e8cf5e84de6 +size 41413 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-N_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-N_1_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..acf8d2793c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_UserAvatar-N_1_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ab02c533d9866bb6e6ac9b6d732c0d81cfcd080e1321df2834937e6274c9363 +size 40896 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png index d56de11ee3..f6663c9291 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb0428758e6ef33fc1852566606de812234ca5f01a069fe170002e60739b38cb -size 29257 +oid sha256:775f1249eded2e16bc7e03a827256020504379a6999b7ca3a1eeae2fdbf8415a +size 29227 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png index 9ef8e06a2c..f06a8e0ce6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ac5ec83fe207221f064ba9eb4f33ad34c4df69cd10a42c85e7d10982ebb73b3 -size 27535 +oid sha256:12c84950e69b760e32bb59c9d90a01d4ec1e17a28ac3c6ba53bd16c8d561db05 +size 27552 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png index a2649e498b..454bbe5c79 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d91bcfb40c3ba7ab56323c028dae8b6771f9c4a4134e352c67b3981c68b66d14 -size 29638 +oid sha256:f5882ca765a08118f6e23925d0621b882d41eb6ead7f8e62240c3473f3aa029d +size 29599 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png index 96c0c46024..6533078c75 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f5b9648f35fb2e7e5832d46fd7d5abf93cd3c0cc7a272b27c6fa23f1361da2f -size 29382 +oid sha256:73fc004c07b36c64f08a65a8b9b62352e9a69f634629141dc1da3aa28397d6f1 +size 29347 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png index e3db6e41f1..a645112020 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f1802db5efefe0117383026cfb5310c8b8d391a15013387be6be8f6aa43bf05 -size 116202 +oid sha256:84714adab3d3fc1a8f076589fd49bb35562913d99d353e9a9e318615568fe3a7 +size 116049 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png index 8bb0a53a37..f7d8135d0b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9048da25ad83e544de8dfa2ec910b7650e34c78a0864e0e1f9644fa18a0ffba8 -size 13144 +oid sha256:964d97909629c1228e96d923ddb478735475839b8540c02142444f9ebd5bf400 +size 13100 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png index 8e68fdc6c1..bff7b81448 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58660c588499291f198046058bf725844bde74a7db4c371d29ee43fba2780e04 +oid sha256:bd8ff4a09babf30be0eb3c336f3cbe6a1508a21696512d0dadbcc9d543e6e34f size 12356 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png index 754ea0cecb..fe1fe39c26 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d4ee26a608ba57aa6e9eca05d4db22a9135243a73faf767cdc10ff0252079a2 -size 12887 +oid sha256:85530997942e39ce73512513ab0698494778168bc28cfab543b50b721c1807f5 +size 12855 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png index 05e82479e2..23211c9508 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8daffe981e83c5a81b60ec1d00d09a12fb3a67d3bd957bab5b0b924480330bfe -size 12952 +oid sha256:2e0a638be5745c75c2663116877d380c83df093d226d2c969d4f6620e8cee109 +size 12965 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png index e333bab625..ad70967875 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd957f1da256db3c598e38d2d6221738ec3feec9124ad00ae6a48ad20e814418 -size 11200 +oid sha256:1acf91a8440717f3467e62a533a6172a7eba01c65b2d8d32b3b3b44d514f52b4 +size 11227 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png index 6bc076c6e2..0563bc9ae3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b7779aec984398ff8fd44dfaf156fc3af31a43073238faa57cd69e2d6ad67cf -size 10648 +oid sha256:01b6759a944884c2c6c7c0631984dc904da890c3a05ac65f4648729065c4f26c +size 10669 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png index b92144d166..847d11231f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8d6f64ccc3f43f057f6558340fea61ececbe78655c4ec441f0a4ce3cdbae62e -size 10970 +oid sha256:6c881c08f6501f8a7d2b865360510ec8b2cfc5819d398b477aa1ca970b20fac3 +size 10983 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png index 7cf5f228fc..f133082603 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ba7e3a152cd236450eb13bd05f4bbb153c38dbc66c4411d2b5e5cfb990d3a2f -size 10997 +oid sha256:ea7db4fd34a741fecff2a084941a55582e167d72a66a4e206102b5cf8d52c806 +size 11014 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png index 0cbcead563..14155e5999 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53e540fd5760b5df921fee79d6ee5387e8d4a830a100c21c699d973ff63844f2 -size 9336 +oid sha256:64ca46029a544e74b05f4a1bc84f17082832b5fdaa9d76a1b5dd3aa755241951 +size 9297 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png index 141d3a059d..0c18e4464d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:366b834d60978a9c8fe677660feedcc16dfeb4c725f249d788a8b90740f76e9a -size 9128 +oid sha256:78d437e9257a4e8e0f8478607cb852a18e188f65adc30c2297f1d18ef4fbccf1 +size 9108 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png index 7669bcfbf5..b640b61655 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66ee0c1c8a79faa3067e4fb8c2349c459d9a26db099ed06f9050f6498705d93c -size 9503 +oid sha256:e4f6d3ffbe069775e1110e49d7e95d43cb81919642062953d6d8a7ab3b82987e +size 9464 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png index ebcee9e7cd..6a1f4eaa15 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4a756b6fcfa482996055448296f06aed6aaca2849c116692e4a8f2f8c2b455a -size 9173 +oid sha256:c77400352729ec572955725cd8afd6149e7ae86aab18a82dcbd51f4c2cdc0e81 +size 9161 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png index 425afced51..0d23f92aad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e71b7329a2f6f4763f2062e0aa4206c62848f566e210eac3fb2787fc53cd08ac -size 74783 +oid sha256:5d3677896ec686f3b9cff36bc947de97bfa3b9274dd19705d6fc79b26bcdcc82 +size 74472 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png index 637bd77768..bd01feb258 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be62026c5821e47b15b8a2d7f03f9c4ea0fe3dbead9ac12c33d23c72b777f3c4 -size 74045 +oid sha256:d3c61acf6eff591fb7765468aa981b8a87fb6da4054175ea60968f5d81370677 +size 73693 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png index 7f3f19bea6..c5a2a4a248 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffbc6dae4b06297fbc248d7ac7e0972037492ea3e1d3bae74176b08d1616df1e -size 32171 +oid sha256:9aa050bd40cae65f3a2fbcd396f525238d182d5e99656adc706692e8feeffd42 +size 32134 From 717f632b35c66a8d9d215c8d7ba8fcae1668d1ab Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 16:19:04 +0200 Subject: [PATCH 057/127] Fix system bar color after login on light theme. Actually for the SunsetPage, we need a light status bar. --- changelog.d/1222.bugfix | 1 + .../designsystem/atomic/pages/SunsetPage.kt | 5 ++--- .../android/libraries/theme/ElementTheme.kt | 17 +++++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 changelog.d/1222.bugfix diff --git a/changelog.d/1222.bugfix b/changelog.d/1222.bugfix new file mode 100644 index 0000000000..325cf6fc4d --- /dev/null +++ b/changelog.d/1222.bugfix @@ -0,0 +1 @@ +Fix system bar color after login on light theme. diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt index 10a6f529af..d4b203d4ae 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt @@ -44,6 +44,7 @@ import io.element.android.libraries.designsystem.text.withColoredPeriod import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.theme.ForcedDarkElementTheme @Composable fun SunsetPage( @@ -53,9 +54,7 @@ fun SunsetPage( modifier: Modifier = Modifier, overallContent: @Composable () -> Unit, ) { - ElementTheme( - darkTheme = true - ) { + ForcedDarkElementTheme(lightStatusBar = true) { Box( modifier = modifier.fillMaxSize() ) { diff --git a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/ElementTheme.kt b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/ElementTheme.kt index fa7bd279e7..81780d1c2d 100644 --- a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/ElementTheme.kt +++ b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/ElementTheme.kt @@ -92,6 +92,7 @@ internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLigh @Composable fun ElementTheme( darkTheme: Boolean = isSystemInDarkTheme(), + lightStatusBar: Boolean = !darkTheme, dynamicColor: Boolean = false, /* true to enable MaterialYou */ compoundColors: SemanticColors = if (darkTheme) compoundColorsDark else compoundColorsLight, materialLightColors: ColorScheme = materialColorSchemeLight, @@ -111,8 +112,19 @@ fun ElementTheme( darkTheme -> materialDarkColors else -> materialLightColors } + val statusBarColorScheme = if (lightStatusBar) { + when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + dynamicLightColorScheme(context) + } + else -> materialLightColors + } + } else { + colorScheme + } SideEffect { - systemUiController.applyTheme(colorScheme = colorScheme, darkTheme = darkTheme) + systemUiController.applyTheme(colorScheme = statusBarColorScheme, darkTheme = darkTheme && !lightStatusBar) } CompositionLocalProvider( LocalCompoundColors provides currentCompoundColor, @@ -132,6 +144,7 @@ fun ElementTheme( */ @Composable fun ForcedDarkElementTheme( + lightStatusBar: Boolean = false, content: @Composable () -> Unit, ) { val systemUiController = rememberSystemUiController() @@ -142,7 +155,7 @@ fun ForcedDarkElementTheme( systemUiController.applyTheme(colorScheme, wasDarkTheme) } } - ElementTheme(darkTheme = true, content = content) + ElementTheme(darkTheme = true, lightStatusBar = lightStatusBar, content = content) } private fun SystemUiController.applyTheme( From cfdccc904e994b095497dc369373d6c0934eaf34 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 5 Sep 2023 18:58:05 +0200 Subject: [PATCH 058/127] Replace notification permission dialog with a screen (#1223) * Replace notification permission dialog with a screen --------- Co-authored-by: ElementBot --- appnav/build.gradle.kts | 2 - .../appnav/loggedin/LoggedInPresenter.kt | 16 -- .../android/appnav/loggedin/LoggedInState.kt | 3 - .../appnav/loggedin/LoggedInStateProvider.kt | 2 - .../android/appnav/loggedin/LoggedInView.kt | 9 - .../appnav/loggedin/LoggedInPresenterTest.kt | 9 +- changelog.d/897.feature | 1 + features/ftue/impl/build.gradle.kts | 6 + .../features/ftue/impl/FtueFlowNode.kt | 15 ++ .../notifications/NotificationsOptInEvents.kt | 22 ++ .../notifications/NotificationsOptInNode.kt | 57 +++++ .../NotificationsOptInPresenter.kt | 89 ++++++++ .../notifications/NotificationsOptInState.kt | 24 ++ .../NotificationsOptInStateProvider.kt | 33 +++ .../notifications/NotificationsOptInView.kt | 206 ++++++++++++++++++ .../ftue/impl/state/DefaultFtueState.kt | 25 ++- .../impl/src/main/res/values/localazy.xml | 2 + .../ftue/impl/DefaultFtueStateTests.kt | 62 +++++- .../NotificationsOptInPresenterTests.kt | 140 ++++++++++++ .../components/avatar/AvatarSize.kt | 2 + .../api/PermissionStateProvider.kt | 30 +++ .../permissions/api}/PermissionsStore.kt | 2 +- libraries/permissions/impl/build.gradle.kts | 1 + .../AccompanistPermissionStateProvider.kt | 4 +- .../impl/DefaultPermissionStateProvider.kt | 48 ++++ .../impl/DefaultPermissionsPresenter.kt | 5 +- .../impl/DefaultPermissionsStore.kt | 3 +- .../impl/FakePermissionStateProvider.kt | 53 +++++ .../impl/DefaultPermissionsPresenterTest.kt | 67 ++++-- ... FakeComposablePermissionStateProvider.kt} | 4 +- libraries/permissions/test/build.gradle.kts | 28 +++ .../test/FakePermissionsPresenter.kt | 51 +++++ .../test}/InMemoryPermissionsStore.kt | 6 +- services/toolbox/test/build.gradle.kts | 26 +++ .../sdk/FakeBuildVersionSdkIntProvider.kt | 25 +++ ...OptInView-D-1_2_null_0,NEXUS_5,1.0,en].png | 3 + ...OptInView-N-1_3_null_0,NEXUS_5,1.0,en].png | 3 + ...elcomeView-D-2_3_null,NEXUS_5,1.0,en].png} | 0 ...elcomeView-N-2_4_null,NEXUS_5,1.0,en].png} | 0 ...atars_Avatar_0_null_42,NEXUS_5,1.0,en].png | 3 + ...atars_Avatar_0_null_43,NEXUS_5,1.0,en].png | 3 + ...atars_Avatar_0_null_44,NEXUS_5,1.0,en].png | 3 + tools/localazy/config.json | 3 +- 43 files changed, 1027 insertions(+), 69 deletions(-) create mode 100644 changelog.d/897.feature create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInNode.kt create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInStateProvider.kt create mode 100644 features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt create mode 100644 features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt create mode 100644 libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionStateProvider.kt rename libraries/permissions/{impl/src/main/kotlin/io/element/android/libraries/permissions/impl => api/src/main/kotlin/io/element/android/libraries/permissions/api}/PermissionsStore.kt (95%) create mode 100644 libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionStateProvider.kt create mode 100644 libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt rename libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/{FakePermissionStateProvider.kt => FakeComposablePermissionStateProvider.kt} (95%) create mode 100644 libraries/permissions/test/build.gradle.kts create mode 100644 libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt rename libraries/permissions/{impl/src/test/kotlin/io/element/android/libraries/permissions/impl => test/src/main/kotlin/io/element/android/libraries/permissions/test}/InMemoryPermissionsStore.kt (90%) create mode 100644 services/toolbox/test/build.gradle.kts create mode 100644 services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/sdk/FakeBuildVersionSdkIntProvider.kt create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-D-1_2_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-N-1_3_null_0,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-1_2_null,NEXUS_5,1.0,en].png => ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-2_3_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-1_3_null,NEXUS_5,1.0,en].png => ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-2_4_null,NEXUS_5,1.0,en].png} (100%) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_44,NEXUS_5,1.0,en].png diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index cffd318fb1..88f0741ebe 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -48,8 +48,6 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.matrixui) implementation(projects.libraries.uiStrings) - implementation(projects.libraries.permissions.api) - implementation(projects.libraries.permissions.noop) implementation(libs.coil) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt index 6d386a17e5..f2af582c25 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt @@ -16,8 +16,6 @@ package io.element.android.appnav.loggedin -import android.Manifest -import android.os.Build import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -30,8 +28,6 @@ import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.roomlist.RoomListService -import io.element.android.libraries.permissions.api.PermissionsPresenter -import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter import io.element.android.libraries.push.api.PushService import kotlinx.coroutines.delay import javax.inject.Inject @@ -40,20 +36,10 @@ private const val DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS = 1500L class LoggedInPresenter @Inject constructor( private val matrixClient: MatrixClient, - private val permissionsPresenterFactory: PermissionsPresenter.Factory, private val networkMonitor: NetworkMonitor, private val pushService: PushService, ) : Presenter { - private val postNotificationPermissionsPresenter by lazy { - // Ask for POST_NOTIFICATION PERMISSION on Android 13+ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - permissionsPresenterFactory.create(Manifest.permission.POST_NOTIFICATIONS) - } else { - NoopPermissionsPresenter() - } - } - @Composable override fun present(): LoggedInState { LaunchedEffect(Unit) { @@ -66,7 +52,6 @@ class LoggedInPresenter @Inject constructor( val roomListState by matrixClient.roomListService.state.collectAsState() val networkStatus by networkMonitor.connectivity.collectAsState() - val permissionsState = postNotificationPermissionsPresenter.present() var showSyncSpinner by remember { mutableStateOf(false) } @@ -82,7 +67,6 @@ class LoggedInPresenter @Inject constructor( } return LoggedInState( showSyncSpinner = showSyncSpinner, - permissionsState = permissionsState, ) } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt index bb06952a50..4196277698 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt @@ -16,9 +16,6 @@ package io.element.android.appnav.loggedin -import io.element.android.libraries.permissions.api.PermissionsState - data class LoggedInState( val showSyncSpinner: Boolean, - val permissionsState: PermissionsState, ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStateProvider.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStateProvider.kt index 3cfb03f123..0e8fdef8d8 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStateProvider.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStateProvider.kt @@ -17,7 +17,6 @@ package io.element.android.appnav.loggedin import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.permissions.api.createDummyPostNotificationPermissionsState open class LoggedInStateProvider : PreviewParameterProvider { override val values: Sequence @@ -32,5 +31,4 @@ fun aLoggedInState( showSyncSpinner: Boolean = true, ) = LoggedInState( showSyncSpinner = showSyncSpinner, - permissionsState = createDummyPostNotificationPermissionsState(), ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt index 0ade93a795..37e6e9591d 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt @@ -23,21 +23,16 @@ import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.libraries.androidutils.system.openAppSettingsPage import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.permissions.api.PermissionsView @Composable fun LoggedInView( state: LoggedInState, modifier: Modifier = Modifier ) { - val context = LocalContext.current - Box( modifier = modifier .fillMaxSize() @@ -49,10 +44,6 @@ fun LoggedInView( .align(Alignment.TopCenter), isVisible = state.showSyncSpinner, ) - PermissionsView( - state = state.permissionsState, - openSystemSettings = context::openAppSettingsPage - ) } } diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt index 4abc89e7ee..9ac795f9ab 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt @@ -26,8 +26,6 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService -import io.element.android.libraries.permissions.api.PermissionsPresenter -import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter import io.element.android.libraries.push.api.PushService import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider @@ -43,7 +41,7 @@ class LoggedInPresenterTest { presenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionsState.permission).isEmpty() + assertThat(initialState.showSyncSpinner).isFalse() } } @@ -68,11 +66,6 @@ class LoggedInPresenterTest { ): LoggedInPresenter { return LoggedInPresenter( matrixClient = FakeMatrixClient(roomListService = roomListService), - permissionsPresenterFactory = object : PermissionsPresenter.Factory { - override fun create(permission: String): PermissionsPresenter { - return NoopPermissionsPresenter() - } - }, networkMonitor = FakeNetworkMonitor(networkStatus), pushService = object : PushService { override fun notificationStyleChanged() { diff --git a/changelog.d/897.feature b/changelog.d/897.feature new file mode 100644 index 0000000000..f705f8dee8 --- /dev/null +++ b/changelog.d/897.feature @@ -0,0 +1 @@ +Add a notification permission screen to the initial flow. diff --git a/features/ftue/impl/build.gradle.kts b/features/ftue/impl/build.gradle.kts index 8b12767b20..a4edc8fb7f 100644 --- a/features/ftue/impl/build.gradle.kts +++ b/features/ftue/impl/build.gradle.kts @@ -43,6 +43,10 @@ dependencies { implementation(projects.libraries.testtags) implementation(projects.features.analytics.api) implementation(projects.services.analytics.api) + implementation(projects.libraries.permissions.api) + implementation(projects.libraries.permissions.noop) + implementation(projects.services.toolbox.api) + implementation(projects.services.toolbox.test) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) @@ -51,6 +55,8 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) + testImplementation(projects.libraries.permissions.impl) + testImplementation(projects.libraries.permissions.test) ksp(libs.showkase.processor) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt index 2b515c18a6..ab6bf94a69 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt @@ -35,6 +35,7 @@ import io.element.android.anvilannotations.ContributesNode import io.element.android.features.analytics.api.AnalyticsEntryPoint import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.impl.migration.MigrationScreenNode +import io.element.android.features.ftue.impl.notifications.NotificationsOptInNode import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep import io.element.android.features.ftue.impl.welcome.WelcomeNode @@ -79,6 +80,9 @@ class FtueFlowNode @AssistedInject constructor( @Parcelize data object WelcomeScreen : NavTarget + @Parcelize + data object NotificationsOptIn : NavTarget + @Parcelize data object AnalyticsOptIn : NavTarget } @@ -124,6 +128,14 @@ class FtueFlowNode @AssistedInject constructor( } createNode(buildContext, listOf(callback)) } + NavTarget.NotificationsOptIn -> { + val callback = object : NotificationsOptInNode.Callback { + override fun onNotificationsOptInFinished() { + lifecycleScope.launch { moveToNextStep() } + } + } + createNode(buildContext, listOf(callback)) + } NavTarget.AnalyticsOptIn -> { analyticsEntryPoint.createNode(this, buildContext) } @@ -138,6 +150,9 @@ class FtueFlowNode @AssistedInject constructor( FtueStep.WelcomeScreen -> { backstack.newRoot(NavTarget.WelcomeScreen) } + FtueStep.NotificationsOptIn -> { + backstack.newRoot(NavTarget.NotificationsOptIn) + } FtueStep.AnalyticsOptIn -> { backstack.replace(NavTarget.AnalyticsOptIn) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt new file mode 100644 index 0000000000..55b6748c72 --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +sealed interface NotificationsOptInEvents { + data object ContinueClicked : NotificationsOptInEvents + data object NotNowClicked : NotificationsOptInEvents +} diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInNode.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInNode.kt new file mode 100644 index 0000000000..00fbb10b1f --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInNode.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.architecture.NodeInputs +import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.di.AppScope + +@ContributesNode(AppScope::class) +class NotificationsOptInNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenterFactory: NotificationsOptInPresenter.Factory, +) : Node(buildContext, plugins = plugins) { + + interface Callback: NodeInputs { + fun onNotificationsOptInFinished() + } + + private val callback = inputs() + + private val presenter: NotificationsOptInPresenter by lazy { + presenterFactory.create(callback) + } + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + NotificationsOptInView( + state = state, + onBack = { callback.onNotificationsOptInFinished() }, + modifier = modifier + ) + } +} diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt new file mode 100644 index 0000000000..f7e4b6b26d --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import android.Manifest +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.compose.runtime.Composable +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.permissions.api.PermissionStateProvider +import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsPresenter +import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter +import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +class NotificationsOptInPresenter @AssistedInject constructor( + private val permissionsPresenterFactory: PermissionsPresenter.Factory, + @Assisted private val callback: NotificationsOptInNode.Callback, + private val appCoroutineScope: CoroutineScope, + private val permissionStateProvider: PermissionStateProvider, + private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider, +) : Presenter { + + @AssistedFactory + interface Factory { + fun create(callback: NotificationsOptInNode.Callback): NotificationsOptInPresenter + } + + private val postNotificationPermissionsPresenter by lazy { + // Ask for POST_NOTIFICATION PERMISSION on Android 13+ + if (buildVersionSdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { + permissionsPresenterFactory.create(Manifest.permission.POST_NOTIFICATIONS) + } else { + NoopPermissionsPresenter() + } + } + + @Composable + override fun present(): NotificationsOptInState { + val notificationPremissionsState = postNotificationPermissionsPresenter.present() + + fun handleEvents(event: NotificationsOptInEvents) { + when (event) { + NotificationsOptInEvents.ContinueClicked -> { + if (notificationPremissionsState.permissionGranted) { + callback.onNotificationsOptInFinished() + } else { + notificationPremissionsState.eventSink(PermissionsEvents.OpenSystemDialog) + } + } + NotificationsOptInEvents.NotNowClicked -> { + if (buildVersionSdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { + appCoroutineScope.setPermissionDenied() + } + callback.onNotificationsOptInFinished() + } + } + } + + return NotificationsOptInState( + notificationsPermissionState = notificationPremissionsState, + eventSink = ::handleEvents + ) + } + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun CoroutineScope.setPermissionDenied() = launch { + permissionStateProvider.setPermissionDenied(Manifest.permission.POST_NOTIFICATIONS, true) + } +} diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt new file mode 100644 index 0000000000..a64fb7ad4a --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import io.element.android.libraries.permissions.api.PermissionsState + +data class NotificationsOptInState( + val notificationsPermissionState: PermissionsState, + val eventSink: (NotificationsOptInEvents) -> Unit +) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInStateProvider.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInStateProvider.kt new file mode 100644 index 0000000000..230e125c1b --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInStateProvider.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.permissions.api.aPermissionsState + +open class NotificationsOptInStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aNotificationsOptInState(), + // Add other states here + ) +} + +fun aNotificationsOptInState() = NotificationsOptInState( + notificationsPermissionState = aPermissionsState(), + eventSink = {} +) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt new file mode 100644 index 0000000000..73135cafdc --- /dev/null +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Notifications +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.features.ftue.impl.R +import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage +import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Surface +import io.element.android.libraries.designsystem.theme.components.TextButton +import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun NotificationsOptInView( + state: NotificationsOptInState, + onBack: () -> Unit, + modifier: Modifier = Modifier, +) { + BackHandler(onBack = onBack) + + if (state.notificationsPermissionState.permissionAlreadyDenied) { + LaunchedEffect(Unit) { + state.eventSink(NotificationsOptInEvents.NotNowClicked) + } + } + + HeaderFooterPage( + modifier = modifier + .systemBarsPadding() + .fillMaxSize(), + header = { NotificationsOptInHeader(modifier = Modifier.padding(top = 60.dp, bottom = 12.dp),) }, + footer = { NotificationsOptInFooter(state) }, + ) { + NotificationsOptInContent(modifier = Modifier.fillMaxWidth()) + } +} + +@Composable +private fun NotificationsOptInHeader( + modifier: Modifier = Modifier, +) { + IconTitleSubtitleMolecule( + modifier = modifier, + title = stringResource(R.string.screen_notification_optin_title), + subTitle = stringResource(R.string.screen_notification_optin_subtitle), + iconImageVector = Icons.Default.Notifications, + ) +} + +@Composable +private fun NotificationsOptInFooter(state: NotificationsOptInState) { + ButtonColumnMolecule { + Button( + modifier = Modifier.fillMaxWidth(), + text = stringResource(CommonStrings.action_ok), + onClick = { + state.eventSink(NotificationsOptInEvents.ContinueClicked) + } + ) + TextButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(CommonStrings.action_not_now), + onClick = { + state.eventSink(NotificationsOptInEvents.NotNowClicked) + } + ) + } +} + +@Composable +private fun NotificationsOptInContent( + modifier: Modifier = Modifier, +) { + Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Column( + verticalArrangement = Arrangement.spacedBy( + 16.dp, + alignment = Alignment.CenterVertically + ) + ) { + NotificationRow( + avatarLetter = "M", + avatarColors = avatarColors("5"), + firstRowPercent = 1f, + secondRowPercent = 0.4f + ) + + NotificationRow( + avatarLetter = "A", + avatarColors = avatarColors("1"), + firstRowPercent = 1f, + secondRowPercent = 1f + ) + + NotificationRow( + avatarLetter = "T", + avatarColors = avatarColors("4"), + firstRowPercent = 0.65f, + secondRowPercent = 0f + ) + } + } +} + +@Composable +private fun NotificationRow( + avatarLetter: String, + avatarColors: AvatarColors, + firstRowPercent: Float, + secondRowPercent: Float, + modifier: Modifier = Modifier +) { + Surface( + modifier = modifier, + color = ElementTheme.colors.bgCanvasDisabled, + shape = RoundedCornerShape(14.dp), + shadowElevation = 2.dp, + ) { + Row( + modifier = Modifier.padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Avatar( + avatarData = AvatarData(id = "", name = avatarLetter, size = AvatarSize.NotificationsOptIn), + initialAvatarColors = avatarColors, + ) + Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(12.dp)) { + Box( + modifier = Modifier + .clip(CircleShape) + .fillMaxWidth(firstRowPercent) + .height(10.dp) + .background(ElementTheme.colors.borderInteractiveSecondary) + ) + if (secondRowPercent > 0f) { + Box( + modifier = Modifier.clip(CircleShape) + .fillMaxWidth(secondRowPercent) + .height(10.dp) + .background(ElementTheme.colors.borderInteractiveSecondary) + ) + } + } + } + } +} + +@DayNightPreviews +@Composable +internal fun NotificationsOptInViewPreview( + @PreviewParameter(NotificationsOptInStateProvider::class) state: NotificationsOptInState +) { + ElementPreview { + NotificationsOptInView( + onBack = {}, + state = state, + ) + } +} diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt index 108072cba9..3247d7faf8 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt @@ -16,6 +16,8 @@ package io.element.android.features.ftue.impl.state +import android.Manifest +import android.os.Build import androidx.annotation.VisibleForTesting import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.ftue.api.state.FtueState @@ -23,7 +25,9 @@ import io.element.android.features.ftue.impl.migration.MigrationScreenStore import io.element.android.features.ftue.impl.welcome.state.WelcomeScreenState import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.permissions.api.PermissionStateProvider import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first @@ -34,10 +38,12 @@ import javax.inject.Inject @ContributesBinding(SessionScope::class) class DefaultFtueState @Inject constructor( + private val sdkVersionProvider: BuildVersionSdkIntProvider, private val coroutineScope: CoroutineScope, private val analyticsService: AnalyticsService, private val welcomeScreenState: WelcomeScreenState, private val migrationScreenStore: MigrationScreenStore, + private val permissionStateProvider: PermissionStateProvider, private val matrixClient: MatrixClient, ) : FtueState { @@ -47,6 +53,9 @@ class DefaultFtueState @Inject constructor( welcomeScreenState.reset() analyticsService.reset() migrationScreenStore.reset() + if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { + permissionStateProvider.resetPermission(Manifest.permission.POST_NOTIFICATIONS) + } } init { @@ -63,7 +72,10 @@ class DefaultFtueState @Inject constructor( FtueStep.MigrationScreen -> if (shouldDisplayWelcomeScreen()) FtueStep.WelcomeScreen else getNextStep( FtueStep.WelcomeScreen ) - FtueStep.WelcomeScreen -> if (needsAnalyticsOptIn()) FtueStep.AnalyticsOptIn else getNextStep( + FtueStep.WelcomeScreen -> if (shouldAskNotificationPermissions()) FtueStep.NotificationsOptIn else getNextStep( + FtueStep.NotificationsOptIn + ) + FtueStep.NotificationsOptIn -> if (needsAnalyticsOptIn()) FtueStep.AnalyticsOptIn else getNextStep( FtueStep.AnalyticsOptIn ) FtueStep.AnalyticsOptIn -> null @@ -73,6 +85,7 @@ class DefaultFtueState @Inject constructor( return listOf( shouldDisplayMigrationScreen(), shouldDisplayWelcomeScreen(), + shouldAskNotificationPermissions(), needsAnalyticsOptIn() ).any { it } } @@ -90,6 +103,15 @@ class DefaultFtueState @Inject constructor( return welcomeScreenState.isWelcomeScreenNeeded() } + private fun shouldAskNotificationPermissions(): Boolean { + return if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { + val permission = Manifest.permission.POST_NOTIFICATIONS + val isPermissionDenied = runBlocking { permissionStateProvider.isPermissionDenied(permission).first() } + val isPermissionGranted = permissionStateProvider.isPermissionGranted(permission) + !isPermissionGranted && !isPermissionDenied + } else false + } + fun setWelcomeScreenShown() { welcomeScreenState.setWelcomeScreenShown() updateState() @@ -104,5 +126,6 @@ class DefaultFtueState @Inject constructor( sealed interface FtueStep { data object MigrationScreen : FtueStep data object WelcomeScreen : FtueStep + data object NotificationsOptIn : FtueStep data object AnalyticsOptIn : FtueStep } diff --git a/features/ftue/impl/src/main/res/values/localazy.xml b/features/ftue/impl/src/main/res/values/localazy.xml index aee8470751..b398ba37d0 100644 --- a/features/ftue/impl/src/main/res/values/localazy.xml +++ b/features/ftue/impl/src/main/res/values/localazy.xml @@ -2,6 +2,8 @@ "This is a one time process, thanks for waiting." "Setting up your account." + "You can change your settings later." + "Allow notifications and never miss a message" "Calls, polls, search and more will be added later this year." "Message history for encrypted rooms won’t be available in this update." "We’d love to hear from you, let us know what you think via the settings page." diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt index f93f761994..1388eb8fc1 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt @@ -16,6 +16,7 @@ package io.element.android.features.ftue.impl +import android.os.Build import com.google.common.truth.Truth.assertThat import io.element.android.features.ftue.impl.migration.InMemoryMigrationScreenStore import io.element.android.features.ftue.impl.migration.MigrationScreenStore @@ -25,8 +26,10 @@ import io.element.android.features.ftue.impl.welcome.state.FakeWelcomeState import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.permissions.impl.FakePermissionStateProvider import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel @@ -51,13 +54,21 @@ class DefaultFtueStateTests { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() val migrationScreenStore = InMemoryMigrationScreenStore() + val permissionStateProvider = FakePermissionStateProvider(permissionGranted = true) val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) - val state = createState(coroutineScope, welcomeState, analyticsService, migrationScreenStore) + val state = createState( + coroutineScope = coroutineScope, + welcomeState = welcomeState, + analyticsService = analyticsService, + migrationScreenStore = migrationScreenStore, + permissionStateProvider = permissionStateProvider + ) welcomeState.setWelcomeScreenShown() analyticsService.setDidAskUserConsent() migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) + permissionStateProvider.setPermissionGranted() state.updateState() assertThat(state.shouldDisplayFlow.value).isFalse() @@ -71,9 +82,16 @@ class DefaultFtueStateTests { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() val migrationScreenStore = InMemoryMigrationScreenStore() + val permissionStateProvider = FakePermissionStateProvider(permissionGranted = false) val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) - val state = createState(coroutineScope, welcomeState, analyticsService, migrationScreenStore) + val state = createState( + coroutineScope = coroutineScope, + welcomeState = welcomeState, + analyticsService = analyticsService, + migrationScreenStore = migrationScreenStore, + permissionStateProvider = permissionStateProvider + ) val steps = mutableListOf() // First step, migration screen @@ -84,7 +102,11 @@ class DefaultFtueStateTests { steps.add(state.getNextStep(steps.lastOrNull())) welcomeState.setWelcomeScreenShown() - // Third step, analytics opt in + // Third step, notifications opt in + steps.add(state.getNextStep(steps.lastOrNull())) + permissionStateProvider.setPermissionGranted() + + // Fourth step, analytics opt in steps.add(state.getNextStep(steps.lastOrNull())) analyticsService.setDidAskUserConsent() @@ -94,6 +116,7 @@ class DefaultFtueStateTests { assertThat(steps).containsExactly( FtueStep.MigrationScreen, FtueStep.WelcomeScreen, + FtueStep.NotificationsOptIn, FtueStep.AnalyticsOptIn, null, // Final state ) @@ -107,11 +130,40 @@ class DefaultFtueStateTests { val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) val analyticsService = FakeAnalyticsService() val migrationScreenStore = InMemoryMigrationScreenStore() + val permissionStateProvider = FakePermissionStateProvider(permissionGranted = false) val state = createState( coroutineScope = coroutineScope, analyticsService = analyticsService, migrationScreenStore = migrationScreenStore, + permissionStateProvider = permissionStateProvider, + ) + + // Skip first 3 steps + migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) + state.setWelcomeScreenShown() + permissionStateProvider.setPermissionGranted() + + assertThat(state.getNextStep()).isEqualTo(FtueStep.AnalyticsOptIn) + + analyticsService.setDidAskUserConsent() + assertThat(state.getNextStep(FtueStep.WelcomeScreen)).isNull() + + // Cleanup + coroutineScope.cancel() + } + + @Test + fun `if version is older than 13 we don't display the notification opt in screen`() = runTest { + val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) + val analyticsService = FakeAnalyticsService() + val migrationScreenStore = InMemoryMigrationScreenStore() + + val state = createState( + sdkIntVersion = Build.VERSION_CODES.M, + coroutineScope = coroutineScope, + analyticsService = analyticsService, + migrationScreenStore = migrationScreenStore, ) migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) @@ -132,12 +184,16 @@ class DefaultFtueStateTests { welcomeState: FakeWelcomeState = FakeWelcomeState(), analyticsService: AnalyticsService = FakeAnalyticsService(), migrationScreenStore: MigrationScreenStore = InMemoryMigrationScreenStore(), + permissionStateProvider: FakePermissionStateProvider = FakePermissionStateProvider(permissionGranted = false), matrixClient: MatrixClient = FakeMatrixClient(), + sdkIntVersion: Int = Build.VERSION_CODES.TIRAMISU, // First version where notification permission is required ) = DefaultFtueState( + sdkVersionProvider = FakeBuildVersionSdkIntProvider(sdkIntVersion), coroutineScope = coroutineScope, analyticsService = analyticsService, welcomeScreenState = welcomeState, migrationScreenStore = migrationScreenStore, + permissionStateProvider = permissionStateProvider, matrixClient = matrixClient, ) } diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt new file mode 100644 index 0000000000..fa1ab39007 --- /dev/null +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 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.features.ftue.impl.notifications + +import android.os.Build +import app.cash.molecule.RecompositionMode +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth +import io.element.android.libraries.permissions.api.PermissionStateProvider +import io.element.android.libraries.permissions.api.PermissionsPresenter +import io.element.android.libraries.permissions.impl.FakePermissionStateProvider +import io.element.android.libraries.permissions.test.FakePermissionsPresenter +import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class NotificationsOptInPresenterTests { + + private var isFinished = false + + @Test + fun `initial state`() = runTest { + val presenter = createPresenter() + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + Truth.assertThat(initialState.notificationsPermissionState.showDialog).isFalse() + } + } + + @Test + fun `show dialog on continue clicked`() = runTest { + val permissionPresenter = FakePermissionsPresenter() + val presenter = createPresenter(permissionPresenter) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(NotificationsOptInEvents.ContinueClicked) + Truth.assertThat(awaitItem().notificationsPermissionState.showDialog).isTrue() + } + } + + @Test + fun `finish flow on continue clicked with permission already granted`() = runTest { + val permissionPresenter = FakePermissionsPresenter().apply { + setPermissionGranted() + } + val presenter = createPresenter(permissionPresenter) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(NotificationsOptInEvents.ContinueClicked) + Truth.assertThat(isFinished).isTrue() + } + } + + @Test + fun `finish flow on not now clicked`() = runTest { + val permissionPresenter = FakePermissionsPresenter() + val presenter = createPresenter( + permissionsPresenter = permissionPresenter, + sdkIntVersion = Build.VERSION_CODES.M + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(NotificationsOptInEvents.NotNowClicked) + Truth.assertThat(isFinished).isTrue() + } + } + + @Test + fun `set permission denied on not now clicked in API 33`() = runTest(StandardTestDispatcher()) { + val permissionPresenter = FakePermissionsPresenter() + val permissionStateProvider = FakePermissionStateProvider() + val presenter = createPresenter( + permissionsPresenter = permissionPresenter, + permissionStateProvider = permissionStateProvider, + sdkIntVersion = Build.VERSION_CODES.TIRAMISU + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(NotificationsOptInEvents.NotNowClicked) + + // Allow background coroutines to run + runCurrent() + + val isPermissionDenied = runBlocking { + permissionStateProvider.isPermissionDenied("notifications").first() + } + Truth.assertThat(isPermissionDenied).isTrue() + } + } + + private fun TestScope.createPresenter( + permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(), + permissionStateProvider: PermissionStateProvider = FakePermissionStateProvider(), + sdkIntVersion: Int = Build.VERSION_CODES.TIRAMISU, + ) = NotificationsOptInPresenter( + permissionsPresenterFactory = object : PermissionsPresenter.Factory { + override fun create(permission: String): PermissionsPresenter { + return permissionsPresenter + } + }, + callback = object : NotificationsOptInNode.Callback { + override fun onNotificationsOptInFinished() { + isFinished = true + } + }, + appCoroutineScope = this, + permissionStateProvider = permissionStateProvider, + buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(sdkIntVersion), + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 2438e5f017..372aecea32 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -42,4 +42,6 @@ enum class AvatarSize(val dp: Dp) { RoomInviteItem(52.dp), InviteSender(16.dp), + + NotificationsOptIn(32.dp), } diff --git a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionStateProvider.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionStateProvider.kt new file mode 100644 index 0000000000..8ea50b4ada --- /dev/null +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionStateProvider.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 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.libraries.permissions.api + +import kotlinx.coroutines.flow.Flow + +interface PermissionStateProvider { + fun isPermissionGranted(permission: String): Boolean + suspend fun setPermissionDenied(permission: String, value: Boolean) + fun isPermissionDenied(permission: String): Flow + + suspend fun setPermissionAsked(permission: String, value: Boolean) + fun isPermissionAsked(permission: String): Flow + + suspend fun resetPermission(permission: String) +} diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/PermissionsStore.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsStore.kt similarity index 95% rename from libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/PermissionsStore.kt rename to libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsStore.kt index 25b41e2a71..be16dc74e5 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/PermissionsStore.kt +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsStore.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.permissions.impl +package io.element.android.libraries.permissions.api import kotlinx.coroutines.flow.Flow diff --git a/libraries/permissions/impl/build.gradle.kts b/libraries/permissions/impl/build.gradle.kts index 9808986f8f..4ae9fc9fcc 100644 --- a/libraries/permissions/impl/build.gradle.kts +++ b/libraries/permissions/impl/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.permissions.test) ksp(libs.showkase.processor) } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/AccompanistPermissionStateProvider.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/AccompanistPermissionStateProvider.kt index 15acd868f2..02b4dd535c 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/AccompanistPermissionStateProvider.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/AccompanistPermissionStateProvider.kt @@ -26,13 +26,13 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope import javax.inject.Inject -interface PermissionStateProvider { +interface ComposablePermissionStateProvider { @Composable fun provide(permission: String, onPermissionResult: (Boolean) -> Unit): PermissionState } @ContributesBinding(AppScope::class) -class AccompanistPermissionStateProvider @Inject constructor() : PermissionStateProvider { +class AccompanistPermissionStateProvider @Inject constructor() : ComposablePermissionStateProvider { @Composable override fun provide(permission: String, onPermissionResult: (Boolean) -> Unit): PermissionState { return rememberPermissionState( diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionStateProvider.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionStateProvider.kt new file mode 100644 index 0000000000..86cc646982 --- /dev/null +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionStateProvider.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 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.libraries.permissions.impl + +import android.content.Context +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.di.SingleIn +import io.element.android.libraries.permissions.api.PermissionStateProvider +import io.element.android.libraries.permissions.api.PermissionsStore +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +class DefaultPermissionStateProvider @Inject constructor( + @ApplicationContext private val context: Context, + private val permissionsStore: PermissionsStore, +): PermissionStateProvider { + override fun isPermissionGranted(permission: String): Boolean { + return context.checkSelfPermission(permission) == android.content.pm.PackageManager.PERMISSION_GRANTED + } + + override suspend fun setPermissionDenied(permission: String, value: Boolean) = permissionsStore.setPermissionDenied(permission, value) + + override fun isPermissionDenied(permission: String): Flow = permissionsStore.isPermissionDenied(permission) + + override suspend fun setPermissionAsked(permission: String, value: Boolean) = permissionsStore.setPermissionAsked(permission, value) + + override fun isPermissionAsked(permission: String): Flow = permissionsStore.isPermissionAsked(permission) + + override suspend fun resetPermission(permission: String) = permissionsStore.resetPermission(permission) +} diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt index f98ab1fb9d..ddd45f865f 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.di.AppScope import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.api.PermissionsState +import io.element.android.libraries.permissions.api.PermissionsStore import kotlinx.coroutines.launch import timber.log.Timber @@ -46,7 +47,7 @@ private val loggerTag = LoggerTag("DefaultPermissionsPresenter") class DefaultPermissionsPresenter @AssistedInject constructor( @Assisted val permission: String, private val permissionsStore: PermissionsStore, - private val permissionStateProvider: PermissionStateProvider, + private val composablePermissionStateProvider: ComposablePermissionStateProvider, ) : PermissionsPresenter { @AssistedFactory @@ -90,7 +91,7 @@ class DefaultPermissionsPresenter @AssistedInject constructor( } } - permissionState = permissionStateProvider.provide( + permissionState = composablePermissionStateProvider.provide( permission = permission, onPermissionResult = ::onPermissionResult ) diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsStore.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsStore.kt index 9ee29b7a61..49528da329 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsStore.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsStore.kt @@ -26,6 +26,7 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.permissions.api.PermissionsStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import javax.inject.Inject @@ -34,7 +35,7 @@ private val Context.dataStore: DataStore by preferencesDataStore(na @ContributesBinding(AppScope::class) class DefaultPermissionsStore @Inject constructor( - @ApplicationContext context: Context, + @ApplicationContext private val context: Context, ) : PermissionsStore { private val store = context.dataStore diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt new file mode 100644 index 0000000000..364f8072a1 --- /dev/null +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 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.libraries.permissions.impl + +import io.element.android.libraries.permissions.api.PermissionStateProvider +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow + +class FakePermissionStateProvider( + private var permissionGranted: Boolean = true, + permissionDenied: Boolean = false, + permissionAsked: Boolean = false, +): PermissionStateProvider { + private val permissionDeniedFlow = MutableStateFlow(permissionDenied) + private val permissionAskedFlow = MutableStateFlow(permissionAsked) + + fun setPermissionGranted() { + permissionGranted = true + } + + override fun isPermissionGranted(permission: String): Boolean = permissionGranted + + override suspend fun setPermissionDenied(permission: String, value: Boolean) { + permissionDeniedFlow.value = value + } + + override fun isPermissionDenied(permission: String): Flow = permissionDeniedFlow + + override suspend fun setPermissionAsked(permission: String, value: Boolean) { + permissionAskedFlow.value = value + } + + override fun isPermissionAsked(permission: String): Flow = permissionAskedFlow + + override suspend fun resetPermission(permission: String) { + setPermissionAsked(permission, false) + setPermissionDenied(permission, false) + } +} diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index f501bcee8a..d435e4b89d 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -25,6 +25,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionStatus import com.google.common.truth.Truth.assertThat import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.test.InMemoryPermissionsStore import kotlinx.coroutines.test.runTest import org.junit.Test @@ -34,8 +35,14 @@ class DefaultPermissionsPresenterTest { @Test fun `present - initial state`() = runTest { val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Granted) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Granted + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -57,8 +64,14 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user closes dialog`() = runTest { val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Denied(shouldShowRationale = false)) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Denied(shouldShowRationale = false) + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -77,8 +90,14 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission`() = runTest { val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Denied(shouldShowRationale = false)) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Denied(shouldShowRationale = false) + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -106,8 +125,14 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission second time`() = runTest { val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Denied(shouldShowRationale = true)) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Denied(shouldShowRationale = true) + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -134,9 +159,19 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission third time`() = runTest { - val permissionsStore = InMemoryPermissionsStore(permissionDenied = true, permissionAsked = true) - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Denied(shouldShowRationale = false)) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionsStore = + InMemoryPermissionsStore( + permissionDenied = true, + permissionAsked = true + ) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Denied(shouldShowRationale = false) + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -157,8 +192,14 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user grants permission`() = runTest { val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState(A_PERMISSION, PermissionStatus.Denied(shouldShowRationale = false)) - val permissionStateProvider = FakePermissionStateProvider(permissionState) + val permissionState = FakePermissionState( + A_PERMISSION, + PermissionStatus.Denied(shouldShowRationale = false) + ) + val permissionStateProvider = + FakeComposablePermissionStateProvider( + permissionState + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakeComposablePermissionStateProvider.kt similarity index 95% rename from libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt rename to libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakeComposablePermissionStateProvider.kt index c204ff5fc6..900d9ccc69 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/FakeComposablePermissionStateProvider.kt @@ -27,9 +27,9 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionState import com.google.accompanist.permissions.PermissionStatus -class FakePermissionStateProvider constructor( +class FakeComposablePermissionStateProvider constructor( private val permissionState: FakePermissionState -) : PermissionStateProvider { +) : ComposablePermissionStateProvider { private lateinit var onPermissionResult: (Boolean) -> Unit @OptIn(ExperimentalPermissionsApi::class) diff --git a/libraries/permissions/test/build.gradle.kts b/libraries/permissions/test/build.gradle.kts new file mode 100644 index 0000000000..6ed6a89677 --- /dev/null +++ b/libraries/permissions/test/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.libraries.permissions.test" +} + +dependencies { + implementation(projects.libraries.architecture) + api(projects.libraries.permissions.api) +} diff --git a/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt new file mode 100644 index 0000000000..f26f268860 --- /dev/null +++ b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 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.libraries.permissions.test + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsPresenter +import io.element.android.libraries.permissions.api.PermissionsState +import io.element.android.libraries.permissions.api.aPermissionsState + +class FakePermissionsPresenter( + private val initialState: PermissionsState = aPermissionsState().copy(showDialog = false), +) : PermissionsPresenter { + + private fun eventSink(events: PermissionsEvents) { + when (events) { + PermissionsEvents.OpenSystemDialog -> state.value = state.value.copy(showDialog = true, permissionAlreadyAsked = true) + PermissionsEvents.CloseDialog -> state.value = state.value.copy(showDialog = false) + } + } + + private val state = mutableStateOf(initialState.copy(eventSink = ::eventSink)) + + fun setPermissionGranted() { + state.value = state.value.copy(permissionGranted = true) + } + + fun setPermissionDenied() { + state.value = state.value.copy(permissionAlreadyDenied = true) + } + + @Composable + override fun present(): PermissionsState { + return state.value + } +} diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/InMemoryPermissionsStore.kt b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/InMemoryPermissionsStore.kt similarity index 90% rename from libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/InMemoryPermissionsStore.kt rename to libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/InMemoryPermissionsStore.kt index 3f5d925ccd..abb357ab98 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/InMemoryPermissionsStore.kt +++ b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/InMemoryPermissionsStore.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.element.android.libraries.permissions.impl +package io.element.android.libraries.permissions.test +import io.element.android.libraries.permissions.api.PermissionsStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -43,6 +44,5 @@ class InMemoryPermissionsStore( setPermissionDenied(permission, false) } - override suspend fun resetStore() { - } + override suspend fun resetStore() = Unit } diff --git a/services/toolbox/test/build.gradle.kts b/services/toolbox/test/build.gradle.kts new file mode 100644 index 0000000000..cb8857ceaa --- /dev/null +++ b/services/toolbox/test/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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. + */ +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.services.toolbox.test" +} + +dependencies { + api(projects.services.toolbox.api) +} diff --git a/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/sdk/FakeBuildVersionSdkIntProvider.kt b/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/sdk/FakeBuildVersionSdkIntProvider.kt new file mode 100644 index 0000000000..072afeca77 --- /dev/null +++ b/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/sdk/FakeBuildVersionSdkIntProvider.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 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.services.toolbox.test.sdk + +import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider + +class FakeBuildVersionSdkIntProvider( + private val sdkInt: Int +) : BuildVersionSdkIntProvider { + override fun get(): Int = sdkInt +} diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-D-1_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-D-1_2_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..aa866c7812 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-D-1_2_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a47f94d02280f2122c0743fadc2d53824555f2e57e2c595b07dc32836f80586 +size 37142 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-N-1_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-N-1_3_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..49c3a7bafb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_null_NotificationsOptInView-N-1_3_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9028f6a5a6f67954385bcbcc098535071c096f37d12428c32af94a3e898bf6a +size 33685 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-2_3_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-1_2_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-D-2_3_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-2_4_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-1_3_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_null_WelcomeView-N-2_4_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..1483a5ea12 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c50d9aee05b3e8b8be0b403a0621bc949c08dbca46695f6c70666002d5101d2 +size 18355 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..868cdd8e71 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d56abddf692484f8e2f3795c6cd3c62e8497a2d03042ef770fb75e8863921d40 +size 17689 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_44,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_44,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..a475b2e7d1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_44,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0cb196c59e3bbd845f0e110150ac358ca78c9c08c212e184423ead5d841f67c +size 20219 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 4be78689de..05d1ced2c6 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -118,7 +118,8 @@ "name": ":features:ftue:impl", "includeRegex": [ "screen_welcome_.*", - "screen_migration_.*" + "screen_migration_.*", + "screen_notification_optin_.*" ] }, { From 7f8e54662f1a1c257e9d2f4b863f7e515bc505d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:02:09 +0000 Subject: [PATCH 059/127] Update dependency me.saket.telephoto:zoomable-image-coil to v0.6.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 841e53b75d..7a722301fd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,7 +45,7 @@ dependencycheck = "8.4.0" dependencyanalysis = "1.21.0" stem = "2.3.0" sqldelight = "1.5.5" -telephoto = "0.6.0-SNAPSHOT" +telephoto = "0.6.0" # DI dagger = "2.48" From ffff48b66e2858512272b1a743ec118b8644a6b4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Sep 2023 08:58:32 +0200 Subject: [PATCH 060/127] Fix R8 error, due to exclusion of analytics group done in #1221. --- libraries/pushproviders/firebase/build.gradle.kts | 7 +++++++ .../pushproviders/firebase/consumer-proguard-rules.pro | 4 ++++ 2 files changed, 11 insertions(+) create mode 100644 libraries/pushproviders/firebase/consumer-proguard-rules.pro diff --git a/libraries/pushproviders/firebase/build.gradle.kts b/libraries/pushproviders/firebase/build.gradle.kts index cdb55b1119..186ab121fd 100644 --- a/libraries/pushproviders/firebase/build.gradle.kts +++ b/libraries/pushproviders/firebase/build.gradle.kts @@ -20,6 +20,13 @@ plugins { android { namespace = "io.element.android.libraries.pushproviders.firebase" + + buildTypes { + release { + isMinifyEnabled = true + consumerProguardFiles("consumer-proguard-rules.pro") + } + } } anvil { diff --git a/libraries/pushproviders/firebase/consumer-proguard-rules.pro b/libraries/pushproviders/firebase/consumer-proguard-rules.pro new file mode 100644 index 0000000000..0bc7b604bf --- /dev/null +++ b/libraries/pushproviders/firebase/consumer-proguard-rules.pro @@ -0,0 +1,4 @@ +# Fix this error: +# ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/bmarty/workspaces/element-x-android/app/build/outputs/mapping/nightly/missing_rules.txt. +# ERROR: R8: Missing class com.google.firebase.analytics.connector.AnalyticsConnector (referenced from: void com.google.firebase.messaging.MessagingAnalytics.logToScion(java.lang.String, android.os.Bundle) and 1 other context) +-dontwarn com.google.firebase.analytics.connector.AnalyticsConnector From ce12b7f3f7588f19c455726659adbbc301638495 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Sep 2023 09:23:22 +0200 Subject: [PATCH 061/127] Draft a documentation about the continuous integration --- docs/continuous_integration.md | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/continuous_integration.md diff --git a/docs/continuous_integration.md b/docs/continuous_integration.md new file mode 100644 index 0000000000..4ff0ebb983 --- /dev/null +++ b/docs/continuous_integration.md @@ -0,0 +1,69 @@ +# Continuous integration strategy + + + +* [Introduction](#introduction) +* [CI tools](#ci-tools) +* [Rules](#rules) +* [What is the CI checking](#what-is-the-ci-checking) +* [What is the CI reporting](#what-is-the-ci-reporting) +* [Current choices](#current-choices) + * [R8 task](#r8-task) + * [Android test (connected test)](#android-test-connected-test) + + + +## Introduction + +This document gives some information about how we take advantage of the continuous integration (CI). + +## CI tools + +We use GitHub Actions to configure and perform the CI. + +## Rules + +We want: + +1. The CI to detect as soon as possible any issue in the code +2. The CI to be fast - it's run on all the Pull Requests, and developers do not like to wait too long +3. The CI to be reliable - it should not fail randomly +4. The CI to generate artifacts which can be used by the team and the community +5. The CI to generate useful logs and reports, not too verbose, not too short +6. The developer to be able to run the CI locally - to help with this we have [a script](../tools/check/check_code_quality.sh) the can be run locally and which does more checks that just building and deploying the app. +7. The CI to be used as a common environment for the team: generate the screenshots image for the screenshot test, build the release build (unsigned) +8. The CI to run repeated tasks, like building the nightly builds, integrating data from external tools (translations, etc.) +9. The CI to upgrade our dependencies (Renovate) +10. The CI to do some issue triaging + +## What is the CI checking + +The CI checks that: + +1. The code is compiling, without any warnings, for all the app build types and variants and for the minimal app +2. The tests are passing +3. The code quality is good (detekt, ktlint, lint) +4. The code is running and smoke tests are passing (maestro) +5. The PullRequest itself is good (with danger) +6. Files that must be added with git-lfs are added with git-lfs + +## What is the CI reporting + +The CI reports: + +1. Code coverage reports +2. Sonar reports + +## Current choices + +### R8 task + +The CI does not run R8 because it's too slow, and it breaks rule 2. + +The drawback is that the nightly build can fail, as well as the release build. + +Since the nightly build is failing, the team can detect the failure quite fast and react to it. + +### Android test (connected test) + +We limit the number of connected tests (tests under folder `androidTest`), because it often break rule 2 and 3. From 64030fa0a383c05a884de4c2dece8ef9c65803d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 07:56:49 +0000 Subject: [PATCH 062/127] Update dependency io.sentry:sentry-android to v6.29.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 841e53b75d..3d5d605118 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -163,7 +163,7 @@ maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:2.0.1" # Analytics posthog = "com.posthog.android:posthog:2.0.3" -sentry = "io.sentry:sentry-android:6.28.0" +sentry = "io.sentry:sentry-android:6.29.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8" # Emojibase From 128c4a7b09f77e54eec2cb1342ab4dc8af1f7e5d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Sep 2023 11:33:36 +0200 Subject: [PATCH 063/127] SDK 0.1.49: notification decryption is now fully handled by the Rust SDK. (#1231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "Ensure the sync is started when receiving a Push, to ensure that the encryption loop is running." This reverts commit 82f6f358a7987e46a38189e78f96455b94f2b6ad. * Integrate SDK from https://github.com/matrix-org/matrix-rust-sdk/pull/2505 * Enable retryDecryption() on the NotificationClient. * SDK 0.1.49 - Encryption Sync is enabled by default now, and retryDecryption is the default too. * Remove feature flag `UseEncryptionSync` * Fix sample project build * Exclude `DeveloperSettingsPresenter` from kover verification. * Add changelog --------- Co-authored-by: Jorge Martín --- .../android/appnav/LoggedInFlowNode.kt | 5 +-- build.gradle.kts | 2 + changelog.d/+sdk_bump.feature | 1 + .../developer/DeveloperSettingsPresenter.kt | 6 +-- gradle/libs.versions.toml | 2 +- .../libraries/featureflag/api/FeatureFlags.kt | 6 --- .../impl/BuildtimeFeatureFlagProvider.kt | 1 - .../matrix/api/sync/StartSyncReason.kt | 25 ------------ .../libraries/matrix/api/sync/SyncService.kt | 4 +- .../libraries/matrix/impl/RustMatrixClient.kt | 13 ++++-- .../matrix/impl/RustMatrixClientFactory.kt | 9 +---- .../impl/roomlist/RustRoomListService.kt | 1 + .../matrix/impl/sync/RustSyncService.kt | 40 +++++-------------- .../matrix/test/sync/FakeSyncService.kt | 5 +-- .../notifications/NotifiableEventResolver.kt | 12 ------ .../android/samples/minimal/MainActivity.kt | 2 - .../android/samples/minimal/RoomListScreen.kt | 5 +-- 17 files changed, 35 insertions(+), 104 deletions(-) create mode 100644 changelog.d/+sdk_bump.feature delete mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index c3a79acb81..5006218bda 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -60,7 +60,6 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.MAIN_SPACE import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.push.api.notifications.NotificationDrawerManager import io.element.android.services.appnavstate.api.AppNavigationStateService @@ -125,7 +124,7 @@ class LoggedInFlowNode @AssistedInject constructor( onStop = { //Counterpart startSync is done in observeSyncStateAndNetworkStatus method. coroutineScope.launch { - syncService.stopSync(StartSyncReason.AppInForeground) + syncService.stopSync() } }, onDestroy = { @@ -151,7 +150,7 @@ class LoggedInFlowNode @AssistedInject constructor( .collect { (syncState, networkStatus) -> Timber.d("Sync state: $syncState, network status: $networkStatus") if (syncState != SyncState.Running && networkStatus == NetworkStatus.Online) { - syncService.startSync(StartSyncReason.AppInForeground) + syncService.startSync() } } } diff --git a/build.gradle.kts b/build.gradle.kts index b48ef70ce7..69f5676e72 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -261,6 +261,8 @@ koverMerged { includes += "*Presenter" excludes += "*Fake*Presenter" excludes += "io.element.android.appnav.loggedin.LoggedInPresenter$*" + // Some options can't be tested at the moment + excludes += "io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*" } bound { minValue = 85 diff --git a/changelog.d/+sdk_bump.feature b/changelog.d/+sdk_bump.feature new file mode 100644 index 0000000000..4f92120f84 --- /dev/null +++ b/changelog.d/+sdk_bump.feature @@ -0,0 +1 @@ +Bump Rust SDK to `v0.1.49` \ No newline at end of file diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index 5f50fde309..ebcd44b4db 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -124,16 +124,12 @@ class DeveloperSettingsPresenter @Inject constructor( enabledFeatures: SnapshotStateMap, featureUiModel: FeatureUiModel, enabled: Boolean, - triggerClearCache: () -> Unit, + @Suppress("UNUSED_PARAMETER") triggerClearCache: () -> Unit, ) = launch { val feature = features[featureUiModel.key] ?: return@launch if (featureFlagService.setFeatureEnabled(feature, enabled)) { enabledFeatures[featureUiModel.key] = enabled } - - if (featureUiModel.key == FeatureFlags.UseEncryptionSync.key) { - triggerClearCache() - } } private fun CoroutineScope.computeCacheSize(cacheSize: MutableState>) = launch { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7a722301fd..f42532ac1b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -146,7 +146,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" } timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.48" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.49" sqldelight-driver-android = { module = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-jvm = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqldelight" } diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 312745a4df..c28dc28144 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -31,10 +31,4 @@ enum class FeatureFlags( title = "Polls", description = "Create poll and render poll events in the timeline", ), - UseEncryptionSync( - key = "feature.useencryptionsync", - title = "Use encryption sync", - description = "Use the encryption sync API for decrypting notifications.", - defaultValue = true, - ) } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt index 5640d108a6..83913cbac5 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt @@ -31,7 +31,6 @@ class BuildtimeFeatureFlagProvider @Inject constructor() : when (feature) { FeatureFlags.LocationSharing -> true FeatureFlags.Polls -> false - FeatureFlags.UseEncryptionSync -> true } } else { false diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt deleted file mode 100644 index 4a6b44949e..0000000000 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/StartSyncReason.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2023 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.libraries.matrix.api.sync - -import io.element.android.libraries.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.core.RoomId - -sealed interface StartSyncReason { - data object AppInForeground : StartSyncReason - data class Notification(val roomId: RoomId, val eventId: EventId) : StartSyncReason -} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt index 03a8402b32..994b35edc4 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt @@ -22,12 +22,12 @@ interface SyncService { /** * Tries to start the sync. If already syncing it has no effect. */ - suspend fun startSync(reason: StartSyncReason): Result + suspend fun startSync(): Result /** * Tries to stop the sync. If service is not syncing it has no effect. */ - suspend fun stopSync(reason: StartSyncReason): Result + suspend fun stopSync(): Result /** * Flow of [SyncState]. Will be updated as soon as the current [SyncState] changes. diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 4b0afb0b4f..54641f785b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -65,6 +65,7 @@ import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.ClientDelegate +import org.matrix.rustcomponents.sdk.NotificationProcessSetup import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.use @@ -98,9 +99,13 @@ class RustMatrixClient constructor( client = client, dispatchers = dispatchers, ) - private val notificationClient = client.notificationClient().use { builder -> - builder.filterByPushRules().finish() - } + private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(syncService) + private val notificationClient = client.notificationClient(notificationProcessSetup) + .use { builder -> + builder + .filterByPushRules() + .finish() + } private val notificationService = RustNotificationService(sessionId, notificationClient, dispatchers, clock) @@ -279,6 +284,7 @@ class RustMatrixClient constructor( syncService.destroy() innerRoomListService.destroy() notificationClient.destroy() + notificationProcessSetup.destroy() client.destroy() } @@ -316,6 +322,7 @@ class RustMatrixClient constructor( client.accountUrl() } } + override suspend fun loadUserDisplayName(): Result = withContext(sessionDispatcher) { runCatching { client.displayName() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 3615115bb4..b37266342e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -19,8 +19,6 @@ package io.element.android.libraries.matrix.impl import android.content.Context import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.ApplicationContext -import io.element.android.libraries.featureflag.api.FeatureFlagService -import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.network.useragent.UserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionData import io.element.android.libraries.sessionstorage.api.SessionStore @@ -41,7 +39,6 @@ class RustMatrixClientFactory @Inject constructor( private val sessionStore: SessionStore, private val userAgentProvider: UserAgentProvider, private val clock: SystemClock, - private val featureFlagsService: FeatureFlagService, ) { suspend fun create(sessionData: SessionData): RustMatrixClient = withContext(coroutineDispatchers.io) { @@ -56,11 +53,7 @@ class RustMatrixClientFactory @Inject constructor( client.restoreSession(sessionData.toSession()) - val syncService = client.syncService().apply { - if (featureFlagsService.isFeatureEnabled(FeatureFlags.UseEncryptionSync)) { - withEncryptionSync(withCrossProcessLock = false, appIdentifier = null) - } - } + val syncService = client.syncService() .finish() RustMatrixClient( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt index f56e55d759..655c634502 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt @@ -126,6 +126,7 @@ private fun RoomListLoadingState.toLoadingState(): RoomList.LoadingState { private fun RoomListServiceState.toRoomListState(): RoomListService.State { return when (this) { RoomListServiceState.INITIAL, + RoomListServiceState.RECOVERING, RoomListServiceState.SETTING_UP -> RoomListService.State.Idle RoomListServiceState.RUNNING -> RoomListService.State.Running RoomListServiceState.ERROR -> RoomListService.State.Error diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt index b0a9fb31ec..932da42afb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt @@ -16,7 +16,6 @@ package io.element.android.libraries.matrix.impl.sync -import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import kotlinx.coroutines.CoroutineScope @@ -26,8 +25,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import org.matrix.rustcomponents.sdk.SyncServiceInterface import org.matrix.rustcomponents.sdk.SyncServiceState import timber.log.Timber @@ -36,36 +33,19 @@ class RustSyncService( private val innerSyncService: SyncServiceInterface, sessionCoroutineScope: CoroutineScope ) : SyncService { - private val mutex = Mutex() - private val startSyncReasonSet = mutableSetOf() - override suspend fun startSync(reason: StartSyncReason): Result { - return mutex.withLock { - startSyncReasonSet.add(reason) - runCatching { - Timber.d("Start sync") - innerSyncService.start() - }.onFailure { - Timber.e("Start sync failed: $it") - } - } + override suspend fun startSync() = runCatching { + Timber.i("Start sync") + innerSyncService.start() + }.onFailure { + Timber.d("Start sync failed: $it") } - override suspend fun stopSync(reason: StartSyncReason): Result { - return mutex.withLock { - startSyncReasonSet.remove(reason) - if (startSyncReasonSet.isEmpty()) { - runCatching { - Timber.d("Stop sync") - innerSyncService.stop() - }.onFailure { - Timber.e("Stop sync failed: $it") - } - } else { - Timber.d("Stop sync skipped, still $startSyncReasonSet") - Result.success(Unit) - } - } + override suspend fun stopSync() = runCatching { + Timber.i("Stop sync") + innerSyncService.stop() + }.onFailure { + Timber.d("Stop sync failed: $it") } override val syncState: StateFlow = diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt index 87a54a2571..4e618deb9a 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt @@ -16,7 +16,6 @@ package io.element.android.libraries.matrix.test.sync -import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import kotlinx.coroutines.flow.MutableStateFlow @@ -30,12 +29,12 @@ class FakeSyncService : SyncService { syncStateFlow.value = SyncState.Error } - override suspend fun startSync(reason: StartSyncReason): Result { + override suspend fun startSync(): Result { syncStateFlow.value = SyncState.Running return Result.success(Unit) } - override suspend fun stopSync(reason: StartSyncReason): Result { + override suspend fun stopSync(): Result { syncStateFlow.value = SyncState.Terminated return Result.success(Unit) } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt index ce3d09f013..e5af7785db 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt @@ -26,7 +26,6 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.room.RoomMembershipState -import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -45,7 +44,6 @@ import io.element.android.libraries.push.impl.notifications.model.NotifiableMess import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.toolbox.api.strings.StringProvider import io.element.android.services.toolbox.api.systemclock.SystemClock -import kotlinx.coroutines.delay import timber.log.Timber import javax.inject.Inject @@ -67,14 +65,6 @@ class NotifiableEventResolver @Inject constructor( // Restore session val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null val notificationService = client.notificationService() - - // Restart the sync service to ensure that the crypto sync handle the toDevice Events. - client.syncService().startSync(StartSyncReason.Notification(roomId, eventId)) - // Wait for toDevice Event to be processed - // FIXME This delay can be removed when the Rust SDK will handle internal retry to get - // clear notification content. - delay(300) - val notificationData = notificationService.getNotification( userId = sessionId, roomId = roomId, @@ -83,8 +73,6 @@ class NotifiableEventResolver @Inject constructor( Timber.tag(loggerTag.value).e(it, "Unable to resolve event: $eventId.") }.getOrNull() - client.syncService().stopSync(StartSyncReason.Notification(roomId, eventId)) - // TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event return notificationData?.asNotifiableEvent(sessionId) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index 94cd28f021..d0309ebec7 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.core.view.WindowCompat -import io.element.android.libraries.featureflag.impl.DefaultFeatureFlagService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.impl.RustMatrixClientFactory import io.element.android.libraries.matrix.impl.auth.RustMatrixAuthenticationService @@ -56,7 +55,6 @@ class MainActivity : ComponentActivity() { sessionStore = sessionStore, userAgentProvider = userAgentProvider, clock = DefaultSystemClock(), - featureFlagsService = DefaultFeatureFlagService(emptySet()) ) ) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt index bb90425a48..faaccc9b8e 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt @@ -39,7 +39,6 @@ import io.element.android.libraries.eventformatter.impl.StateContentFormatter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomMembershipObserver -import io.element.android.libraries.matrix.api.sync.StartSyncReason import io.element.android.services.toolbox.impl.strings.AndroidStringProvider import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -110,12 +109,12 @@ class RoomListScreen( DisposableEffect(Unit) { Timber.w("Start sync!") runBlocking { - matrixClient.syncService().startSync(StartSyncReason.AppInForeground) + matrixClient.syncService().startSync() } onDispose { Timber.w("Stop sync!") runBlocking { - matrixClient.syncService().stopSync(StartSyncReason.AppInForeground) + matrixClient.syncService().stopSync() } } } From 9e5b46200bd31d5213e59af58fcbaaed723f8504 Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Wed, 6 Sep 2023 11:08:21 +0100 Subject: [PATCH 064/127] Reduce test flakiness by warming up molecule tests (#1226) --- .../android/appnav/RootPresenterTest.kt | 6 +++ .../appnav/loggedin/LoggedInPresenterTest.kt | 7 +++ features/analytics/impl/build.gradle.kts | 1 + .../impl/AnalyticsOptInPresenterTest.kt | 7 +++ .../AnalyticsPreferencesPresenterTest.kt | 7 +++ features/createroom/impl/build.gradle.kts | 1 + .../impl/addpeople/AddPeoplePresenterTests.kt | 6 +++ .../ConfigureRoomPresenterTests.kt | 6 +++ .../impl/root/CreateRoomRootPresenterTests.kt | 6 +++ .../userlist/DefaultUserListPresenterTests.kt | 6 +++ features/ftue/impl/build.gradle.kts | 1 + .../migration/MigrationScreenPresenterTest.kt | 7 +++ .../NotificationsOptInPresenterTests.kt | 6 +++ features/invitelist/impl/build.gradle.kts | 1 + .../impl/InviteListPresenterTests.kt | 5 ++ .../impl/LeaveRoomPresenterImplTest.kt | 6 +++ features/location/impl/build.gradle.kts | 1 + .../impl/send/SendLocationPresenterTest.kt | 6 +++ .../impl/show/ShowLocationPresenterTest.kt | 6 +++ .../changeserver/ChangeServerPresenterTest.kt | 7 +++ .../impl/oidc/webview/OidcPresenterTest.kt | 7 +++ .../ChangeAccountProviderPresenterTest.kt | 7 +++ .../ConfirmAccountProviderPresenterTest.kt | 7 +++ .../LoginPasswordPresenterTest.kt | 7 +++ .../SearchAccountProviderPresenterTest.kt | 7 +++ .../waitlistscreen/WaitListPresenterTest.kt | 7 +++ features/logout/impl/build.gradle.kts | 1 + .../impl/LogoutPreferencePresenterTest.kt | 7 +++ .../messages/MessagesPresenterTest.kt | 6 +++ .../actionlist/ActionListPresenterTest.kt | 7 +++ .../AttachmentsPreviewPresenterTest.kt | 6 +++ .../forward/ForwardMessagesPresenterTests.kt | 7 +++ .../media/viewer/MediaViewerPresenterTest.kt | 7 +++ .../report/ReportMessagePresenterTests.kt | 6 +++ .../MessageComposerPresenterTest.kt | 6 +++ .../timeline/TimelinePresenterTest.kt | 7 +++ .../CustomReactionPresenterTests.kt | 6 +++ .../ReactionSummaryPresenterTests.kt | 7 +++ .../RetrySendMenuPresenterTests.kt | 6 +++ features/onboarding/impl/build.gradle.kts | 1 + .../impl/OnBoardingPresenterTest.kt | 7 +++ features/poll/impl/build.gradle.kts | 1 + .../impl/create/CreatePollPresenterTest.kt | 6 +++ .../impl/about/AboutPresenterTest.kt | 7 +++ .../AnalyticsSettingsPresenterTest.kt | 7 +++ .../DeveloperSettingsPresenterTest.kt | 7 +++ .../tracing/ConfigureTracingPresenterTest.kt | 6 +++ .../impl/root/PreferencesRootPresenterTest.kt | 7 +++ features/rageshake/impl/build.gradle.kts | 1 + .../impl/bugreport/BugReportPresenterTest.kt | 7 +++ .../crash/ui/CrashDetectionPresenterTest.kt | 7 +++ .../RageshakeDetectionPresenterTest.kt | 6 +++ .../RageshakePreferencesPresenterTest.kt | 7 +++ .../roomdetails/RoomDetailsPresenterTests.kt | 6 +++ .../edit/RoomDetailsEditPresenterTest.kt | 6 +++ .../invite/RoomInviteMembersPresenterTest.kt | 6 +++ .../members/RoomMemberListPresenterTests.kt | 6 +++ .../RoomMemberDetailsPresenterTests.kt | 6 +++ .../roomlist/impl/RoomListPresenterTests.kt | 6 +++ features/verifysession/impl/build.gradle.kts | 1 + .../impl/VerifySelfSessionPresenterTests.kt | 6 +++ libraries/permissions/impl/build.gradle.kts | 1 + .../impl/DefaultPermissionsPresenterTest.kt | 7 +++ libraries/permissions/noop/build.gradle.kts | 1 + .../noop/NoopPermissionsPresenterTest.kt | 7 +++ tests/testutils/build.gradle.kts | 3 +- .../android/tests/testutils/WarmUpRule.kt | 48 +++++++++++++++++++ 67 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 tests/testutils/src/main/kotlin/io/element/android/tests/testutils/WarmUpRule.kt diff --git a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt index dad9365921..703e59c7f1 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt @@ -31,10 +31,16 @@ import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolde import io.element.android.services.apperror.api.AppErrorState import io.element.android.services.apperror.api.AppErrorStateService import io.element.android.services.apperror.impl.DefaultAppErrorStateService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class RootPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = createPresenter() diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt index 9ac795f9ab..f0a9642f4f 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt @@ -29,11 +29,18 @@ import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.push.api.PushService import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class LoggedInPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = createPresenter() diff --git a/features/analytics/impl/build.gradle.kts b/features/analytics/impl/build.gradle.kts index 3ce2bab507..3deb202ebc 100644 --- a/features/analytics/impl/build.gradle.kts +++ b/features/analytics/impl/build.gradle.kts @@ -51,4 +51,5 @@ dependencies { testImplementation(libs.test.mockk) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) + testImplementation(projects.tests.testutils) } diff --git a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt index b9cb4d95ff..aad9973282 100644 --- a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt +++ b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt @@ -23,11 +23,18 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.analytics.api.AnalyticsOptInEvents import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class AnalyticsOptInPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - enable`() = runTest { val analyticsService = FakeAnalyticsService(isEnabled = false) diff --git a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt index 29c4579d8f..3a2812b72e 100644 --- a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt +++ b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt @@ -23,10 +23,17 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.analytics.api.AnalyticsOptInEvents import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class AnalyticsPreferencesPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state available`() = runTest { val presenter = DefaultAnalyticsPreferencesPresenter( diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 0ef46a57ec..3ea54ca4ea 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -65,6 +65,7 @@ dependencies { testImplementation(projects.libraries.mediapickers.test) testImplementation(projects.libraries.mediaupload.test) testImplementation(projects.libraries.usersearch.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt index 43cf6cff4d..af68f0dd57 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt @@ -24,12 +24,18 @@ import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.libraries.usersearch.test.FakeUserRepository +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest import org.junit.Before +import org.junit.Rule import org.junit.Test class AddPeoplePresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private lateinit var presenter: AddPeoplePresenter @Before diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 864d85423d..bc5bafa843 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -47,6 +48,7 @@ import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -58,6 +60,10 @@ private const val AN_URI_FROM_GALLERY = "content://uri_from_gallery" @RunWith(RobolectricTestRunner::class) class ConfigureRoomPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private lateinit var presenter: ConfigureRoomPresenter private lateinit var userListDataStore: UserListDataStore private lateinit var createRoomDataStore: CreateRoomDataStore diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt index 0f88280c84..1809df135b 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -35,13 +35,19 @@ import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Before +import org.junit.Rule import org.junit.Test class CreateRoomRootPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private lateinit var userRepository: FakeUserRepository private lateinit var presenter: CreateRoomRootPresenter private lateinit var fakeUserListPresenter: FakeUserListPresenter diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index 3561387dcf..12e9f2fc90 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -25,12 +25,18 @@ import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult import io.element.android.libraries.usersearch.test.FakeUserRepository +import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class DefaultUserListPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val userRepository = FakeUserRepository() @Test diff --git a/features/ftue/impl/build.gradle.kts b/features/ftue/impl/build.gradle.kts index a4edc8fb7f..42fe8dade5 100644 --- a/features/ftue/impl/build.gradle.kts +++ b/features/ftue/impl/build.gradle.kts @@ -57,6 +57,7 @@ dependencies { testImplementation(projects.services.analytics.test) testImplementation(projects.libraries.permissions.impl) testImplementation(projects.libraries.permissions.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt index 6e19879b86..1a9a33130d 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt @@ -25,10 +25,17 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class MigrationScreenPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial`() = runTest { val presenter = createPresenter() diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt index fa1ab39007..0c55992367 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt @@ -26,16 +26,22 @@ import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.impl.FakePermissionStateProvider import io.element.android.libraries.permissions.test.FakePermissionsPresenter import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class NotificationsOptInPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private var isFinished = false @Test diff --git a/features/invitelist/impl/build.gradle.kts b/features/invitelist/impl/build.gradle.kts index cd008472b5..d8fb25585f 100644 --- a/features/invitelist/impl/build.gradle.kts +++ b/features/invitelist/impl/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { testImplementation(projects.libraries.push.test) testImplementation(projects.features.invitelist.test) testImplementation(projects.services.analytics.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt index adb2042b62..9ba26b5e2d 100644 --- a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt +++ b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt @@ -44,10 +44,15 @@ import io.element.android.libraries.push.api.notifications.NotificationDrawerMan import io.element.android.libraries.push.test.notifications.FakeNotificationDrawerManager import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class InviteListPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() @Test fun `present - starts empty, adds invites when received`() = runTest { diff --git a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterImplTest.kt b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterImplTest.kt index 3075d3c686..7bbab71a8d 100644 --- a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterImplTest.kt +++ b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterImplTest.kt @@ -29,14 +29,20 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MembershipCha import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class LeaveRoomPresenterImplTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state hides all dialogs`() = runTest { val presenter = createPresenter() diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index 325003b110..dd265ee7f0 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -57,4 +57,5 @@ dependencies { testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) testImplementation(projects.features.messages.test) + testImplementation(projects.tests.testutils) } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt index 21766a2cf0..15afa48b26 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt @@ -34,12 +34,18 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.SendLocationInvocation import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class SendLocationPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val permissionsPresenterFake = PermissionsPresenterFake() private val fakeMatrixRoom = FakeMatrixRoom() private val fakeAnalyticsService = FakeAnalyticsService() diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index 12ccdc16a5..ebb146ca57 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -27,12 +27,18 @@ import io.element.android.features.location.impl.common.permissions.PermissionsP import io.element.android.features.location.impl.common.permissions.PermissionsPresenterFake import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ShowLocationPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val permissionsPresenterFake = PermissionsPresenterFake() private val fakeLocationActions = FakeLocationActions() private val fakeBuildMeta = aBuildMeta(applicationName = "app name") diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt index 009ab31dcd..4a2fcc397c 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt @@ -26,10 +26,17 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.test.A_HOMESERVER import io.element.android.libraries.matrix.test.A_HOMESERVER_URL import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ChangeServerPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = ChangeServerPresenter( diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt index 32d1c6918a..60cc1285e3 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt @@ -27,11 +27,18 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.auth.A_OIDC_DATA import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class OidcPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = OidcPresenter( diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderPresenterTest.kt index f807355cb1..6fe3248ec3 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderPresenterTest.kt @@ -24,10 +24,17 @@ import io.element.android.features.login.impl.accountprovider.AccountProvider import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource import io.element.android.features.login.impl.changeserver.ChangeServerPresenter import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ChangeAccountProviderPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val changeServerPresenter = ChangeServerPresenter( diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt index 95cd9bf053..0ec396694b 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt @@ -31,11 +31,18 @@ import io.element.android.libraries.matrix.test.A_HOMESERVER import io.element.android.libraries.matrix.test.A_HOMESERVER_OIDC import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.waitForPredicate import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ConfirmAccountProviderPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial test`() = runTest { val presenter = createConfirmAccountProviderPresenter() diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt index 421eb869b0..1848940966 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt @@ -31,10 +31,17 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class LoginPasswordPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val authenticationService = FakeAuthenticationService() diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt index ae6ae4d344..89d1a22b0c 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt @@ -30,11 +30,18 @@ import io.element.android.features.login.impl.resolver.network.WellKnownSlidingS import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.test.A_HOMESERVER_URL import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class SearchAccountProviderPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val fakeWellknownRequest = FakeWellknownRequest() diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt index 507e8cec8b..dadcbe186a 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt @@ -30,10 +30,17 @@ import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class WaitListPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val authenticationService = FakeAuthenticationService().apply { diff --git a/features/logout/impl/build.gradle.kts b/features/logout/impl/build.gradle.kts index 464695e169..52a9f76b41 100644 --- a/features/logout/impl/build.gradle.kts +++ b/features/logout/impl/build.gradle.kts @@ -48,4 +48,5 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.tests.testutils) } diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPreferencePresenterTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPreferencePresenterTest.kt index 29df521cb1..9527012e28 100644 --- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPreferencePresenterTest.kt +++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPreferencePresenterTest.kt @@ -25,10 +25,17 @@ import io.element.android.features.logout.api.LogoutPreferenceState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class LogoutPreferencePresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = DefaultLogoutPreferencePresenter( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 992ea60869..3d98f665b6 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -70,6 +70,7 @@ import io.element.android.libraries.mediaupload.api.MediaSender import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilTimeout import io.element.android.tests.testutils.testCoroutineDispatchers @@ -77,10 +78,15 @@ import io.element.android.tests.testutils.waitForPredicate import io.mockk.mockk import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class MessagesPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val mockMediaUrl: Uri = mockk("localMediaUri") @Test diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt index a4ff484ff3..3f3114dff3 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt @@ -33,11 +33,18 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemStateEventContent import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ActionListPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = anActionListPresenter(isBuildDebuggable = true) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/attachments/AttachmentsPreviewPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/attachments/AttachmentsPreviewPresenterTest.kt index 3608d9e80e..5a66fe13b8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/attachments/AttachmentsPreviewPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/attachments/AttachmentsPreviewPresenterTest.kt @@ -34,13 +34,19 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaSender import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor +import io.element.android.tests.testutils.WarmUpRule import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class AttachmentsPreviewPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val mediaPreProcessor = FakeMediaPreProcessor() private val mockMediaUrl: Uri = mockk("localMediaUri") diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/forward/ForwardMessagesPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/forward/ForwardMessagesPresenterTests.kt index 983b251df7..7b6f48403f 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/forward/ForwardMessagesPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/forward/ForwardMessagesPresenterTests.kt @@ -30,13 +30,20 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ForwardMessagesPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + + @Test fun `present - initial state`() = runTest { val presenter = aPresenter() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt index 3c31fa49d3..97ee81bcb6 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt @@ -33,15 +33,22 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.utils.SnackbarDispatcher import io.element.android.libraries.matrix.test.media.FakeMediaLoader import io.element.android.libraries.matrix.test.media.aMediaSource +import io.element.android.tests.testutils.WarmUpRule import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test private val TESTED_MEDIA_INFO = aFileInfo() class MediaViewerPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + + private val mockMediaUri: Uri = mockk("localMediaUri") private val localMediaFactory = FakeLocalMediaFactory(mockMediaUri) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/report/ReportMessagePresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/report/ReportMessagePresenterTests.kt index e6b0dee0c9..97b0227def 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/report/ReportMessagePresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/report/ReportMessagePresenterTests.kt @@ -28,11 +28,17 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ReportMessagePresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `presenter - initial state`() = runTest { val presenter = aPresenter() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index 799db7f274..d89a0392ad 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -55,15 +55,21 @@ import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import io.mockk.mockk import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test import java.io.File class MessageComposerPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val pickerProvider = FakePickerProvider().apply { givenResult(mockk()) // Uri is not available in JVM, so the only way to have a non-null Uri is using Mockk } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt index 860f8def37..4e8ab07d95 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt @@ -37,15 +37,22 @@ import io.element.android.libraries.matrix.test.room.aMessageContent import io.element.android.libraries.matrix.test.room.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.awaitWithLatch import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test import java.util.Date class TimelinePresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = createTimelinePresenter() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt index bb77605132..9f9b7358d8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/customreaction/CustomReactionPresenterTests.kt @@ -26,11 +26,17 @@ import io.element.android.features.messages.impl.timeline.components.customreact import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class CustomReactionPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val presenter = CustomReactionPresenter(emojibaseProvider = FakeEmojibaseProvider()) @Test diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/reactionsummary/ReactionSummaryPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/reactionsummary/ReactionSummaryPresenterTests.kt index 0170878cb5..c2a415ea44 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/reactionsummary/ReactionSummaryPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/reactionsummary/ReactionSummaryPresenterTests.kt @@ -30,10 +30,17 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ReactionSummaryPresenterTests { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val aggregatedReaction = anAggregatedReaction(userId = A_USER_ID, key = "👍", isHighlighted = true) private val roomMember = aRoomMember(userId = A_USER_ID, avatarUrl = AN_AVATAR_URL, displayName = A_USER_NAME) private val summaryEvent = ReactionSummaryEvents.ShowReactionSummary(AN_EVENT_ID, listOf(aggregatedReaction), aggregatedReaction.key) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/retrysendmenu/RetrySendMenuPresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/retrysendmenu/RetrySendMenuPresenterTests.kt index 4f4f0a0ee4..5a23eba6da 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/retrysendmenu/RetrySendMenuPresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/components/retrysendmenu/RetrySendMenuPresenterTests.kt @@ -25,11 +25,17 @@ import io.element.android.features.messages.impl.timeline.components.retrysendme import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuPresenter import io.element.android.libraries.matrix.test.A_TRANSACTION_ID import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class RetrySendMenuPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private val room = FakeMatrixRoom() private val presenter = RetrySendMenuPresenter(room) diff --git a/features/onboarding/impl/build.gradle.kts b/features/onboarding/impl/build.gradle.kts index 0f97a0ffeb..9994eacf81 100644 --- a/features/onboarding/impl/build.gradle.kts +++ b/features/onboarding/impl/build.gradle.kts @@ -48,4 +48,5 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.tests.testutils) } diff --git a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt index d336e5b466..c2db28631c 100644 --- a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt +++ b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt @@ -20,10 +20,17 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class OnBoardingPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = OnBoardingPresenter() diff --git a/features/poll/impl/build.gradle.kts b/features/poll/impl/build.gradle.kts index 4e8d36966a..e2139424e1 100644 --- a/features/poll/impl/build.gradle.kts +++ b/features/poll/impl/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt index 9dacc6062d..c54972e9d1 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt @@ -23,12 +23,18 @@ import com.google.common.truth.Truth import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.test.room.CreatePollInvocation import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class CreatePollPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private var navUpInvocationsCount = 0 private val fakeMatrixRoom = FakeMatrixRoom() // private val fakeAnalyticsService = FakeAnalyticsService() // TODO Polls: add analytics diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/about/AboutPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/about/AboutPresenterTest.kt index 4b025c10ad..ad98756992 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/about/AboutPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/about/AboutPresenterTest.kt @@ -20,10 +20,17 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class AboutPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = AboutPresenter() diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsPresenterTest.kt index 2a7fdba258..775ad1b183 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsPresenterTest.kt @@ -23,10 +23,17 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.analytics.impl.preferences.DefaultAnalyticsPreferencesPresenter import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class AnalyticsSettingsPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val analyticsPresenter = DefaultAnalyticsPreferencesPresenter(FakeAnalyticsService(), aBuildMeta()) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index 9b1bda3631..17ffa2fe73 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -28,10 +28,17 @@ import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataSto import io.element.android.libraries.architecture.Async import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class DeveloperSettingsPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - ensures initial state is correct`() = runTest { val rageshakePresenter = DefaultRageshakePreferencesPresenter(FakeRageShake(), FakeRageshakeDataStore()) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt index 979713427e..5388e97e9e 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt @@ -22,11 +22,17 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.matrix.api.tracing.Target +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.waitForPredicate import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class ConfigureTracingPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() @Test fun `present - initial state`() = runTest { val store = InMemoryTracingConfigurationStore() diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt index 9ad5db3d1b..5217519071 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt @@ -30,10 +30,17 @@ import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class PreferencesRootPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val matrixClient = FakeMatrixClient() diff --git a/features/rageshake/impl/build.gradle.kts b/features/rageshake/impl/build.gradle.kts index 464d521689..eced5c78b8 100644 --- a/features/rageshake/impl/build.gradle.kts +++ b/features/rageshake/impl/build.gradle.kts @@ -57,4 +57,5 @@ dependencies { testImplementation(libs.test.mockk) testImplementation(projects.libraries.matrix.test) testImplementation(projects.features.rageshake.test) + testImplementation(projects.tests.testutils) } diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt index c0418783dd..204cd4aea1 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt @@ -26,13 +26,20 @@ import io.element.android.features.rageshake.test.screenshot.A_SCREENSHOT_URI import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.test.A_FAILURE_REASON +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test const val A_SHORT_DESCRIPTION = "bug!" const val A_LONG_DESCRIPTION = "I have seen a bug!" class BugReportPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = BugReportPresenter( diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/crash/ui/CrashDetectionPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/crash/ui/CrashDetectionPresenterTest.kt index b8b8c4b6d0..e77c1fd7e2 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/crash/ui/CrashDetectionPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/crash/ui/CrashDetectionPresenterTest.kt @@ -24,10 +24,17 @@ import io.element.android.features.rageshake.api.crash.CrashDetectionEvents import io.element.android.features.rageshake.impl.crash.DefaultCrashDetectionPresenter import io.element.android.features.rageshake.test.crash.A_CRASH_DATA import io.element.android.features.rageshake.test.crash.FakeCrashDataStore +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class CrashDetectionPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state no crash`() = runTest { val presenter = DefaultCrashDetectionPresenter( diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt index 02a0fc0794..d1d09131ad 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt @@ -28,14 +28,20 @@ import io.element.android.features.rageshake.test.rageshake.FakeRageShake import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.tests.testutils.WarmUpRule import io.mockk.mockk import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.BeforeClass +import org.junit.Rule import org.junit.Test class RageshakeDetectionPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + companion object { private lateinit var aBitmap: Bitmap diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/preferences/RageshakePreferencesPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/preferences/RageshakePreferencesPresenterTest.kt index 56759c360c..74cd1906a9 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/preferences/RageshakePreferencesPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/preferences/RageshakePreferencesPresenterTest.kt @@ -24,10 +24,17 @@ import io.element.android.features.rageshake.api.preferences.RageshakePreference import io.element.android.features.rageshake.test.rageshake.A_SENSITIVITY import io.element.android.features.rageshake.test.rageshake.FakeRageShake import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class RageshakePreferencesPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state available`() = runTest { val presenter = DefaultRageshakePreferencesPresenter( diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt index 08d6a58535..275b4888d1 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt @@ -40,13 +40,19 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test @ExperimentalCoroutinesApi class RoomDetailsPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private fun aRoomDetailsPresenter(room: MatrixRoom, leaveRoomPresenter: LeaveRoomPresenter = LeaveRoomPresenterFake()): RoomDetailsPresenter { val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory { override fun create(roomMemberId: UserId): RoomMemberDetailsPresenter { diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt index e43703e235..587cc34429 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt @@ -32,6 +32,7 @@ import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor +import io.element.android.tests.testutils.WarmUpRule import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -40,12 +41,17 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import java.io.File @ExperimentalCoroutinesApi class RoomDetailsEditPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + private lateinit var fakePickerProvider: FakePickerProvider private lateinit var fakeMediaPreProcessor: FakeMediaPreProcessor diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index ede7342882..175e4ec48c 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -36,14 +36,20 @@ import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult import io.element.android.libraries.usersearch.test.FakeUserRepository +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test internal class RoomInviteMembersPresenterTest { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state has no results and no search`() = runTest { val presenter = RoomInviteMembersPresenter( diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt index 9de035d017..6dd8e5bf56 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt @@ -32,15 +32,21 @@ import io.element.android.libraries.designsystem.theme.components.SearchBarResul import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test @ExperimentalCoroutinesApi class RoomMemberListPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `search is done automatically on start, but is async`() = runTest { val presenter = createPresenter() diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt index 71df3ad633..2fd240237f 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt @@ -29,13 +29,19 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test @ExperimentalCoroutinesApi class RoomMemberDetailsPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - returns the room member's data, then updates it if needed`() = runTest { val roomMember = aRoomMember(displayName = "Alice") diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt index d8524d5834..1a2f32e54d 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt @@ -50,15 +50,21 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService +import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class RoomListPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - should start with no user and then load user with success`() = runTest { val presenter = createRoomListPresenter() diff --git a/features/verifysession/impl/build.gradle.kts b/features/verifysession/impl/build.gradle.kts index cba9f2890e..a85d714d1e 100644 --- a/features/verifysession/impl/build.gradle.kts +++ b/features/verifysession/impl/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt index 82664f0e03..ced2c48e9b 100644 --- a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt +++ b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt @@ -26,13 +26,19 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.verification.VerificationEmoji import io.element.android.libraries.matrix.api.verification.VerificationFlowState import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test @ExperimentalCoroutinesApi class VerifySelfSessionPresenterTests { + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - Initial state is received`() = runTest { val presenter = createPresenter() diff --git a/libraries/permissions/impl/build.gradle.kts b/libraries/permissions/impl/build.gradle.kts index 4ae9fc9fcc..7d05d9a1d7 100644 --- a/libraries/permissions/impl/build.gradle.kts +++ b/libraries/permissions/impl/build.gradle.kts @@ -57,6 +57,7 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.permissions.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index d435e4b89d..c25e8072e7 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -26,12 +26,19 @@ import com.google.accompanist.permissions.PermissionStatus import com.google.common.truth.Truth.assertThat import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.test.InMemoryPermissionsStore +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test const val A_PERMISSION = "A_PERMISSION" class DefaultPermissionsPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val permissionsStore = InMemoryPermissionsStore() diff --git a/libraries/permissions/noop/build.gradle.kts b/libraries/permissions/noop/build.gradle.kts index e4b8963c89..9282d796bf 100644 --- a/libraries/permissions/noop/build.gradle.kts +++ b/libraries/permissions/noop/build.gradle.kts @@ -31,4 +31,5 @@ dependencies { testImplementation(libs.molecule.runtime) testImplementation(libs.test.truth) testImplementation(libs.test.turbine) + testImplementation(projects.tests.testutils) } diff --git a/libraries/permissions/noop/src/test/kotlin/io/element/android/libraries/permissions/noop/NoopPermissionsPresenterTest.kt b/libraries/permissions/noop/src/test/kotlin/io/element/android/libraries/permissions/noop/NoopPermissionsPresenterTest.kt index 912edd9294..f837529515 100644 --- a/libraries/permissions/noop/src/test/kotlin/io/element/android/libraries/permissions/noop/NoopPermissionsPresenterTest.kt +++ b/libraries/permissions/noop/src/test/kotlin/io/element/android/libraries/permissions/noop/NoopPermissionsPresenterTest.kt @@ -20,10 +20,17 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test class NoopPermissionsPresenterTest { + + @Rule + @JvmField + val warmUpRule = WarmUpRule() + @Test fun `present - initial state`() = runTest { val presenter = NoopPermissionsPresenter() diff --git a/tests/testutils/build.gradle.kts b/tests/testutils/build.gradle.kts index 184bbc418a..8275c975d2 100644 --- a/tests/testutils/build.gradle.kts +++ b/tests/testutils/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ plugins { - id("io.element.android-library") + id("io.element.android-compose-library") alias(libs.plugins.ksp) } @@ -31,4 +31,5 @@ dependencies { implementation(libs.coroutines.test) implementation(projects.libraries.core) implementation(libs.test.turbine) + implementation(libs.molecule.runtime) } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/WarmUpRule.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/WarmUpRule.kt new file mode 100644 index 0000000000..a192cfbd63 --- /dev/null +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/WarmUpRule.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 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.tests.testutils + +import app.cash.molecule.RecompositionMode +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import kotlinx.coroutines.test.runTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement +import kotlin.time.Duration.Companion.seconds + +/** + * moleculeFlow can take time to initialise during the first test of any given + * test class. + * + * Applying this test rule ensures that the slow initialisation is not done + * inside runTest which has a short default timeout. + */ +class WarmUpRule: TestRule { + override fun apply(base: Statement, description: Description): Statement = object: Statement() { + override fun evaluate() { + runTest(timeout = 60.seconds) { + moleculeFlow(RecompositionMode.Immediate) { + // Do nothing + }.test { + awaitItem() // Await a Unit composition + } + } + base.evaluate() + } + } +} From 1a1a0f4503788e4e0df205873866ce7e64555658 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Sep 2023 15:25:08 +0200 Subject: [PATCH 065/127] Make links in room topic clickable (#612) --- changelog.d/612.bugfix | 1 + .../features/roomdetails/impl/RoomDetailsView.kt | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 changelog.d/612.bugfix diff --git a/changelog.d/612.bugfix b/changelog.d/612.bugfix new file mode 100644 index 0000000000..390329afa1 --- /dev/null +++ b/changelog.d/612.bugfix @@ -0,0 +1 @@ +Make links in room topic clickable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 51754ca6de..735ed8491a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -16,6 +16,7 @@ package io.element.android.features.roomdetails.impl +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -55,6 +56,7 @@ import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberHeaderSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberMainActionsSection +import io.element.android.libraries.designsystem.components.ClickableLinkText import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -266,11 +268,13 @@ internal fun TopicSection( onClick = { onActionClicked(RoomDetailsAction.AddTopic) }, ) } else if (roomTopic is RoomTopicState.ExistingTopic) { - Text( - roomTopic.topic, + ClickableLinkText( + text = roomTopic.topic, modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 12.dp), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.tertiary + interactionSource = remember { MutableInteractionSource() }, + style = MaterialTheme.typography.bodyMedium.copy( + color = MaterialTheme.colorScheme.tertiary, + ), ) } } From 8504092b1ff3399c14db4d53acf4a60a73162c03 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 6 Sep 2023 13:33:54 +0000 Subject: [PATCH 066/127] Update screenshots --- ....impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png index 0845a2a7be..9ef89a09c3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2673fa6964ac88be99edaa839a8684bc459b029d210b96fdca698fee569d36f3 -size 54613 +oid sha256:6edcc452c76049a978ceb97b46776446790dbdbe30eef1693fafda089cdc3ee7 +size 55527 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png index 57bdb33e14..9610377f28 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29aef78fc92caa5283a6c066088d43512c36364ae01709d5d7182f6bf11f52b3 -size 48496 +oid sha256:d91c291503dc745092b132fec62208e73dcd031822ca21a66a7fb1f48ecfa6e1 +size 49316 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png index 570e9977a1..1fe7df1eaa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20ebfe833d0432d25076c97aaba8007fae940f70ad4e39502e4695e59fdf4c5e -size 60182 +oid sha256:efda43a25fdc2a21a4ad3767b14b4c7a308003f9bcb9e67d64520db13c83f0fd +size 61061 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png index b0dc0b4495..761666b2e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c31e8e9d8971b8ef0e4e5a5b7a909baf4e65faa18d50452b38cb109edd193de2 -size 60401 +oid sha256:31f2d59ad03a4d9ba8efd5f146668162f3c2095ac90e16dd3634d3e817f7263d +size 61238 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png index b0dc0b4495..761666b2e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c31e8e9d8971b8ef0e4e5a5b7a909baf4e65faa18d50452b38cb109edd193de2 -size 60401 +oid sha256:31f2d59ad03a4d9ba8efd5f146668162f3c2095ac90e16dd3634d3e817f7263d +size 61238 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png index c5444af671..f7d782f1b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c159c58e5fa811e63cc8396f0b6910dd62945014c9a645e149b4bc88b0527dee -size 49416 +oid sha256:fba2e76faa5915acf1e9d2ede6b58e1ab73e287aefa6e5ffc643be527350d987 +size 50147 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png index 8e4244ccad..572f6d76e1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55d72a6ef38f3822131425b56fbb02cad52e836a94cbf878fc654b1f893f9571 -size 54866 +oid sha256:1089845cd143d07e0d6a363a9dc490ab6f5ae4711fc99843c01e4f074dbdeb98 +size 55780 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png index 90756f11ad..6620f9dc9f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f1681459983d04b98cfb583679c1c44504e0fb05d9cbcab90c149de04a91ae9 -size 56779 +oid sha256:59054f5692d41c0d6fe65c6f1bc9d0c4e1e3149aedd987e9335fabff7b46d85f +size 57237 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png index 652fc31f8c..95f7e24521 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07dc159ecc1cce762240c06902690098a3f84a651272b3d51bf2ebc00951d16c -size 49655 +oid sha256:edcf03466e38ce3906583f2701f45d2a9538a6fd7e9d1c9d4822a037b833a512 +size 50185 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png index 5496c8b265..2f17f119fc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44f783fc10ca0aaf56827afb1d2d9a24694e5d192441a8a9f9d1507326d7de94 -size 62479 +oid sha256:670f05e0c2861234708c7dee4d919a977bbd3aec3e965db631505957871f19fa +size 62904 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png index 9e791b59b6..d0c76cd680 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6c8cbb0c5ae7a9e4d4426daaa00c2625731fa93d7fc05bf0cca64d1d7833ec0 -size 62536 +oid sha256:9553c9ef84cd1f2e890290e093cb0006f03d1a2f36de5e2b7d104d0eb102b2e2 +size 63045 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png index 9e791b59b6..d0c76cd680 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6c8cbb0c5ae7a9e4d4426daaa00c2625731fa93d7fc05bf0cca64d1d7833ec0 -size 62536 +oid sha256:9553c9ef84cd1f2e890290e093cb0006f03d1a2f36de5e2b7d104d0eb102b2e2 +size 63045 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png index 3e8e0372e9..0e72199eb0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:210a21565a6b4bf56468125338e9270b9ccc48ce06d24c9eb48f32a027ffc0a4 -size 50720 +oid sha256:7ab533a35fbbba8b45d94bcfb0637d0f021ee2ef71230754ed418702ee18f11d +size 51182 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png index 9d9e068cde..159c179d5c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcf896ec4b058043d5b52065ed3e23549d540d2496e94df3c6c8226d68de5dc4 -size 57033 +oid sha256:9ec34df75877b7050ad874905926f5d35fee29d1f8324437b502d7152ef87cdc +size 57494 From 5b5d2b824a7bd2418e38b1b3f6ff9fb7b37a094d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 21:13:29 +0000 Subject: [PATCH 067/127] Update lifecycle to v2.6.2 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f42532ac1b..32a14d1a9c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ datastore = "1.0.0" constraintlayout = "2.1.4" constraintlayout_compose = "1.0.1" recyclerview = "1.3.1" -lifecycle = "2.6.1" +lifecycle = "2.6.2" activity = "1.7.2" startup = "1.1.1" media3 = "1.1.1" From aed598783b357828e3e946eaf758a9bdeaf6b538 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 01:43:49 +0000 Subject: [PATCH 068/127] Update dependency androidx.compose:compose-bom to v2023.09.00 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f42532ac1b..1ce7a09e72 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ media3 = "1.1.1" browser = "1.6.0" # Compose -compose_bom = "2023.08.00" +compose_bom = "2023.09.00" composecompiler = "1.5.3" # Coroutines From 4a5a01d7100a209314df84eeeb9bc84a2712c45f Mon Sep 17 00:00:00 2001 From: Yoan Pintas Date: Thu, 7 Sep 2023 08:24:34 +0000 Subject: [PATCH 069/127] Add room notification settings (#807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add room notification settings --------- Co-authored-by: ElementBot Co-authored-by: Jorge Martín Co-authored-by: Benoit Marty Co-authored-by: David Langley --- changelog.d/506.feature | 2 + .../messages/impl/MessagesPresenter.kt | 13 +- .../messages/MessagesPresenterTest.kt | 12 +- features/roomdetails/impl/build.gradle.kts | 2 + .../roomdetails/impl/RoomDetailsEvent.kt | 2 + .../roomdetails/impl/RoomDetailsFlowNode.kt | 12 ++ .../roomdetails/impl/RoomDetailsNode.kt | 6 + .../roomdetails/impl/RoomDetailsPresenter.kt | 46 ++++- .../roomdetails/impl/RoomDetailsState.kt | 3 + .../impl/RoomDetailsStateProvider.kt | 4 + .../roomdetails/impl/RoomDetailsView.kt | 53 +++++- .../RoomNotificationSettingsEvents.kt | 24 +++ .../RoomNotificationSettingsItem.kt | 52 ++++++ .../RoomNotificationSettingsNode.kt | 57 +++++++ .../RoomNotificationSettingsOption.kt | 97 +++++++++++ .../RoomNotificationSettingsPresenter.kt | 108 ++++++++++++ .../RoomNotificationSettingsState.kt | 26 +++ .../RoomNotificationSettingsStateProvider.kt | 34 ++++ .../RoomNotificationSettingsView.kt | 161 ++++++++++++++++++ .../src/main/res/values-fr/translations.xml | 10 ++ .../src/main/res/values-ru/translations.xml | 11 ++ .../src/main/res/values-sk/translations.xml | 11 ++ .../main/res/values-zh-rTW/translations.xml | 6 + .../impl/src/main/res/values/localazy.xml | 11 ++ .../roomdetails/RoomDetailsPresenterTests.kt | 127 ++++++++++++-- .../RoomNotificationSettingsPresenterTests.kt | 83 +++++++++ .../components/preferences/PreferenceText.kt | 19 ++- .../libraries/featureflag/api/FeatureFlags.kt | 6 + .../impl/BuildtimeFeatureFlagProvider.kt | 1 + .../libraries/matrix/api/MatrixClient.kt | 2 + .../NotificationSettingsService.kt | 36 ++++ .../libraries/matrix/api/room/MatrixRoom.kt | 4 + .../MatrixRoomNotificationSettingsState.kt | 33 ++++ .../api/room/RoomNotificationSettings.kt | 26 +++ .../libraries/matrix/impl/RustMatrixClient.kt | 10 ++ .../matrix/impl/di/SessionMatrixModule.kt | 6 + .../RoomNotificationSettingsMapper.kt | 44 +++++ .../RustNotificationSettingsService.kt | 86 ++++++++++ .../matrix/impl/room/RustMatrixRoom.kt | 24 +++ .../libraries/matrix/test/FakeMatrixClient.kt | 4 + .../android/libraries/matrix/test/TestData.kt | 4 + .../FakeNotificationSettingsService.kt | 64 +++++++ .../matrix/test/room/FakeMatrixRoom.kt | 13 ++ .../src/main/res/values/localazy.xml | 5 + ...nSettingsDark_0_null_0,NEXUS_5,1.0,en].png | 3 + ...SettingsLight_0_null_0,NEXUS_5,1.0,en].png | 3 + ...OptionLight-D-0_1_null,NEXUS_5,1.0,en].png | 3 + ...OptionLight-N-0_2_null,NEXUS_5,1.0,en].png | 3 + ...etailsDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_2,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_3,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_4,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_5,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_6,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_7,NEXUS_5,1.0,en].png | 4 +- ...etailsDark--1_1_null_8,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_6,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_7,NEXUS_5,1.0,en].png | 4 +- ...tailsLight--0_0_null_8,NEXUS_5,1.0,en].png | 4 +- ..._PreferenceText_0_null,NEXUS_5,1.0,en].png | 4 +- tools/localazy/config.json | 3 +- 68 files changed, 1381 insertions(+), 70 deletions(-) create mode 100644 changelog.d/506.feature create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsEvents.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsItem.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsNode.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsOption.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt create mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt create mode 100644 features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/notificationsettings/RoomNotificationSettingsPresenterTests.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomNotificationSettingsState.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomNotificationSettings.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RoomNotificationSettingsMapper.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsDark_0_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsLight_0_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-D-0_1_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-N-0_2_null,NEXUS_5,1.0,en].png diff --git a/changelog.d/506.feature b/changelog.d/506.feature new file mode 100644 index 0000000000..1b4d7c50cc --- /dev/null +++ b/changelog.d/506.feature @@ -0,0 +1,2 @@ + Add a "Mute" shortcut icon and a "Notifications" section in the room details screen + \ No newline at end of file diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 5f67fd1f7c..dc6f3304b1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -59,7 +59,6 @@ import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.androidutils.clipboard.ClipboardHelper import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -215,7 +214,8 @@ class MessagesPresenter @AssistedInject constructor( } private fun CoroutineScope.reinviteOtherUser(inviteProgress: MutableState>) = launch(dispatchers.io) { - suspend { + inviteProgress.value = Async.Loading() + runCatching { room.updateMembers() val memberList = when (val memberState = room.membersStateFlow.value) { @@ -228,7 +228,14 @@ class MessagesPresenter @AssistedInject constructor( room.inviteUserById(member.userId).onFailure { t -> Timber.e(t, "Failed to reinvite DM partner") }.getOrThrow() - }.runCatchingUpdatingState(inviteProgress) + }.fold( + onSuccess = { + inviteProgress.value = Async.Success(Unit) + }, + onFailure = { + inviteProgress.value = Async.Failure(it) + } + ) } private suspend fun handleActionRedact(event: TimelineItem.Event) { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 3d98f665b6..48a8480915 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -51,6 +51,7 @@ import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.utils.SnackbarDispatcher +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.room.MatrixRoom @@ -80,6 +81,7 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test +import kotlin.time.Duration.Companion.milliseconds class MessagesPresenterTest { @@ -380,13 +382,13 @@ class MessagesPresenterTest { assertThat(initialState.showReinvitePrompt).isFalse() // When the input field is focused we show the alert initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) - val focusedState = consumeItemsUntilPredicate { state -> + val focusedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) { state -> state.showReinvitePrompt }.last() assertThat(focusedState.showReinvitePrompt).isTrue() // If it's dismissed then we stop showing the alert initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Cancel)) - val dismissedState = consumeItemsUntilPredicate { state -> + val dismissedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) { state -> !state.showReinvitePrompt }.last() assertThat(dismissedState.showReinvitePrompt).isFalse() @@ -470,7 +472,9 @@ class MessagesPresenterTest { val initialState = consumeItemsUntilTimeout().last() initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) skipItems(1) - val loadingState = awaitItem() + val loadingState = consumeItemsUntilPredicate { state -> + state.inviteProgress.isLoading() + }.last() assertThat(loadingState.inviteProgress.isLoading()).isTrue() val newState = awaitItem() assertThat(newState.inviteProgress.isSuccess()).isTrue() @@ -595,7 +599,7 @@ class MessagesPresenterTest { appCoroutineScope = this, room = matrixRoom, mediaPickerProvider = FakePickerProvider(), - featureFlagService = FakeFeatureFlagService(), + featureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.NotificationSettings.key to true)), localMediaFactory = FakeLocalMediaFactory(mockMediaUrl), mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom), snackbarDispatcher = SnackbarDispatcher(), diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index 0965cf484a..2137b1401d 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) + implementation(projects.libraries.featureflag.api) api(projects.features.roomdetails.api) api(projects.libraries.usersearch.api) api(projects.services.apperror.api) @@ -59,6 +60,7 @@ dependencies { testImplementation(projects.libraries.mediaupload.test) testImplementation(projects.libraries.mediapickers.test) testImplementation(projects.libraries.usersearch.test) + testImplementation(projects.libraries.featureflag.test) testImplementation(projects.tests.testutils) testImplementation(projects.features.leaveroom.fake) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsEvent.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsEvent.kt index 7b18d398df..fdad01d83c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsEvent.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsEvent.kt @@ -18,4 +18,6 @@ package io.element.android.features.roomdetails.impl sealed interface RoomDetailsEvent { data object LeaveRoom : RoomDetailsEvent + data object MuteNotification : RoomDetailsEvent + data object UnmuteNotification : RoomDetailsEvent } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index b456df9f02..675ef7de60 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -33,6 +33,7 @@ import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditNode import io.element.android.features.roomdetails.impl.invite.RoomInviteMembersNode import io.element.android.features.roomdetails.impl.members.RoomMemberListNode import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsNode +import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsNode import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.createNode @@ -66,6 +67,9 @@ class RoomDetailsFlowNode @AssistedInject constructor( @Parcelize data object InviteMembers : NavTarget + @Parcelize + object RoomNotificationSettings : NavTarget + @Parcelize data class RoomMemberDetails(val roomMemberId: UserId) : NavTarget } @@ -85,6 +89,10 @@ class RoomDetailsFlowNode @AssistedInject constructor( override fun openInviteMembers() { backstack.push(NavTarget.InviteMembers) } + + override fun openRoomNotificationSettings() { + backstack.push(NavTarget.RoomNotificationSettings) + } } createNode(buildContext, listOf(roomDetailsCallback)) } @@ -110,6 +118,10 @@ class RoomDetailsFlowNode @AssistedInject constructor( createNode(buildContext) } + NavTarget.RoomNotificationSettings -> { + createNode(buildContext) + } + is NavTarget.RoomMemberDetails -> { val plugins = listOf(RoomMemberDetailsNode.RoomMemberDetailsInput(navTarget.roomMemberId)) createNode(buildContext, plugins) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt index b74cf7aaf1..65c2ed0f89 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt @@ -51,6 +51,7 @@ class RoomDetailsNode @AssistedInject constructor( fun openRoomMemberList() fun openInviteMembers() fun editRoomDetails() + fun openRoomNotificationSettings() } private val callbacks = plugins() @@ -67,6 +68,10 @@ class RoomDetailsNode @AssistedInject constructor( callbacks.forEach { it.openRoomMemberList() } } + private fun openRoomNotificationSettings() { + callbacks.forEach { it.openRoomNotificationSettings() } + } + private fun invitePeople() { callbacks.forEach { it.openInviteMembers() } } @@ -133,6 +138,7 @@ class RoomDetailsNode @AssistedInject constructor( onShareRoom = ::onShareRoom, onShareMember = ::onShareMember, openRoomMemberList = ::openRoomMemberList, + openRoomNotificationSettings = ::openRoomNotificationSettings, invitePeople = ::invitePeople, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 2612c24365..b12d4710a0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -22,31 +22,55 @@ import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomPresenter import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.powerlevels.canInvite import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.roomNotificationSettings import io.element.android.libraries.matrix.ui.room.getDirectRoomMember +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import javax.inject.Inject class RoomDetailsPresenter @Inject constructor( + private val client: MatrixClient, private val room: MatrixRoom, + private val featureFlagService: FeatureFlagService, + private val notificationSettingsService: NotificationSettingsService, private val roomMembersDetailsPresenterFactory: RoomMemberDetailsPresenter.Factory, private val leaveRoomPresenter: LeaveRoomPresenter, + private val dispatchers: CoroutineDispatchers, ) : Presenter { @Composable override fun present(): RoomDetailsState { + val scope = rememberCoroutineScope() val leaveRoomState = leaveRoomPresenter.present() + val canShowNotificationSettings = remember { mutableStateOf(false) } + LaunchedEffect(Unit) { + canShowNotificationSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.NotificationSettings) + if (canShowNotificationSettings.value) { + room.updateRoomNotificationSettings() + observeNotificationSettings() + } room.updateMembers() } @@ -69,10 +93,22 @@ class RoomDetailsPresenter @Inject constructor( } } + val roomNotificationSettingsState by room.roomNotificationSettingsStateFlow.collectAsState() + fun handleEvents(event: RoomDetailsEvent) { when (event) { - is RoomDetailsEvent.LeaveRoom -> + RoomDetailsEvent.LeaveRoom -> leaveRoomState.eventSink(LeaveRoomEvent.ShowConfirmation(room.roomId)) + RoomDetailsEvent.MuteNotification -> { + scope.launch(dispatchers.io) { + client.notificationSettingsService().muteRoom(room.roomId) + } + } + RoomDetailsEvent.UnmuteNotification -> { + scope.launch(dispatchers.io) { + client.notificationSettingsService().unmuteRoom(room.roomId, room.isEncrypted, room.activeMemberCount) + } + } } } @@ -88,9 +124,11 @@ class RoomDetailsPresenter @Inject constructor( isEncrypted = room.isEncrypted, canInvite = canInvite, canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room, + canShowNotificationSettings = canShowNotificationSettings.value, roomType = roomType, roomMemberDetailsState = roomMemberDetailsState, leaveRoomState = leaveRoomState, + roomNotificationSettings = roomNotificationSettingsState.roomNotificationSettings(), eventSink = ::handleEvents, ) } @@ -122,4 +160,10 @@ class RoomDetailsPresenter @Inject constructor( private fun getCanSendState(membersState: MatrixRoomMembersState, type: StateEventType) = produceState(false, membersState) { value = room.canSendState(type).getOrElse { false } } + + private fun CoroutineScope.observeNotificationSettings() { + notificationSettingsService.notificationSettingsChangeFlow.onEach { + room.updateRoomNotificationSettings() + }.launchIn(this) + } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt index 49aa7f6ce0..8dc6f81bf1 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt @@ -19,6 +19,7 @@ package io.element.android.features.roomdetails.impl import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings data class RoomDetailsState( val roomId: String, @@ -32,7 +33,9 @@ data class RoomDetailsState( val roomMemberDetailsState: RoomMemberDetailsState?, val canEdit: Boolean, val canInvite: Boolean, + val canShowNotificationSettings: Boolean, val leaveRoomState: LeaveRoomState, + val roomNotificationSettings: RoomNotificationSettings?, val eventSink: (RoomDetailsEvent) -> Unit ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt index cc4c4a6b1b..c580e6d677 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt @@ -22,6 +22,8 @@ import io.element.android.features.roomdetails.impl.members.details.aRoomMemberD import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings open class RoomDetailsStateProvider : PreviewParameterProvider { override val values: Sequence @@ -75,9 +77,11 @@ fun aRoomDetailsState() = RoomDetailsState( isEncrypted = true, canInvite = false, canEdit = false, + canShowNotificationSettings = true, roomType = RoomDetailsType.Room, roomMemberDetailsState = null, leaveRoomState = LeaveRoomState(), + roomNotificationSettings = RoomNotificationSettings(mode = RoomNotificationMode.MUTE, isDefault = false), eventSink = {} ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 735ed8491a..19aeb7ba0f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -27,12 +27,15 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.Lock +import androidx.compose.material.icons.outlined.Notifications +import androidx.compose.material.icons.outlined.NotificationsOff import androidx.compose.material.icons.outlined.Person import androidx.compose.material.icons.outlined.PersonAddAlt import androidx.compose.material.icons.outlined.Share @@ -75,6 +78,7 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings @@ -87,6 +91,7 @@ fun RoomDetailsView( onShareRoom: () -> Unit, onShareMember: (RoomMember) -> Unit, openRoomMemberList: () -> Unit, + openRoomNotificationSettings: () -> Unit, invitePeople: () -> Unit, modifier: Modifier = Modifier, ) { @@ -120,7 +125,10 @@ fun RoomDetailsView( roomName = state.roomName, roomAlias = state.roomAlias ) - MainActionsSection(onShareRoom = onShareRoom) + MainActionsSection( + state = state, + onShareRoom = onShareRoom + ) } is RoomDetailsType.Dm -> { @@ -142,6 +150,12 @@ fun RoomDetailsView( ) } + if (state.canShowNotificationSettings && state.roomNotificationSettings != null) { + NotificationSection( + isDefaultMode = state.roomNotificationSettings.isDefault, + openRoomNotificationSettings = openRoomNotificationSettings) + } + if (state.roomType is RoomDetailsType.Room) { MembersSection( memberCount = state.memberCount, @@ -211,8 +225,21 @@ internal fun RoomDetailsTopBar( } @Composable -internal fun MainActionsSection(onShareRoom: () -> Unit, modifier: Modifier = Modifier) { +internal fun MainActionsSection(state: RoomDetailsState, onShareRoom: () -> Unit, modifier: Modifier = Modifier) { Row(modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) { + val roomNotificationSettings = state.roomNotificationSettings + if (state.canShowNotificationSettings && roomNotificationSettings != null) { + if (roomNotificationSettings.mode == RoomNotificationMode.MUTE) { + MainActionButton(title = stringResource(CommonStrings.common_unmute), icon = Icons.Outlined.NotificationsOff, onClick = { + state.eventSink(RoomDetailsEvent.UnmuteNotification) + }) + } else { + MainActionButton(title = stringResource(CommonStrings.common_mute), icon = Icons.Outlined.Notifications, onClick = { + state.eventSink(RoomDetailsEvent.MuteNotification) + }) + } + } + Spacer(modifier = Modifier.width(20.dp)) MainActionButton(title = stringResource(R.string.screen_room_details_share_room_title), icon = Icons.Outlined.Share, onClick = onShareRoom) } } @@ -280,6 +307,27 @@ internal fun TopicSection( } } +@Composable +internal fun NotificationSection( + isDefaultMode: Boolean, + openRoomNotificationSettings: () -> Unit, + modifier: Modifier = Modifier +) { + val subtitle = if (isDefaultMode) { + stringResource(R.string.screen_room_details_notification_mode_default) + } else { + stringResource(R.string.screen_room_details_notification_mode_custom) + } + PreferenceCategory(modifier = modifier) { + PreferenceText( + title = stringResource(R.string.screen_room_details_notification_title), + subtitle = subtitle, + icon = Icons.Outlined.Notifications, + onClick = openRoomNotificationSettings, + ) + } +} + @Composable internal fun MembersSection( memberCount: Long, @@ -352,6 +400,7 @@ private fun ContentToPreview(state: RoomDetailsState) { onShareRoom = {}, onShareMember = {}, openRoomMemberList = {}, + openRoomNotificationSettings = {}, invitePeople = {}, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsEvents.kt new file mode 100644 index 0000000000..bbe756b154 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsEvents.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import io.element.android.libraries.matrix.api.room.RoomNotificationMode + +sealed interface RoomNotificationSettingsEvents { + data class RoomNotificationModeChanged(val mode: RoomNotificationMode) : RoomNotificationSettingsEvents + data class SetNotificationMode(val isDefault: Boolean): RoomNotificationSettingsEvents +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsItem.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsItem.kt new file mode 100644 index 0000000000..182944c70e --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsItem.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import io.element.android.features.roomdetails.impl.R +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +data class RoomNotificationSettingsItem( + val mode: RoomNotificationMode, + val title: String, +) + +@Composable +fun roomNotificationSettingsItems(): ImmutableList { + return RoomNotificationMode.values() + .map { + when (it) { + RoomNotificationMode.ALL_MESSAGES -> RoomNotificationSettingsItem( + mode = it, + title = stringResource(R.string.screen_room_notification_settings_mode_all_messages), + ) + RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> RoomNotificationSettingsItem( + mode = it, + title = stringResource(R.string.screen_room_notification_settings_mode_mentions_and_keywords), + ) + RoomNotificationMode.MUTE -> RoomNotificationSettingsItem( + mode = it, + title = stringResource(CommonStrings.common_mute), + ) + } + } + .toImmutableList() +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsNode.kt new file mode 100644 index 0000000000..224f850e28 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsNode.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.lifecycle.subscribe +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import im.vector.app.features.analytics.plan.MobileScreen +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.di.RoomScope +import io.element.android.services.analytics.api.AnalyticsService + +@ContributesNode(RoomScope::class) +class RoomNotificationSettingsNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: RoomNotificationSettingsPresenter, + private val analyticsService: AnalyticsService, +) : Node(buildContext, plugins = plugins) { + + init { + lifecycle.subscribe( + onResume = { + analyticsService.screen(MobileScreen(screenName = MobileScreen.ScreenName.RoomNotifications)) + } + ) + } + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + RoomNotificationSettingsView( + state = state, + modifier = modifier, + onBackPressed = this::navigateUp, + ) + } +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsOption.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsOption.kt new file mode 100644 index 0000000000..28592b3b7e --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsOption.kt @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.selection.selectable +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.theme.components.RadioButton +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.toEnabledColor +import io.element.android.libraries.theme.ElementTheme + +@Composable +fun RoomNotificationSettingsOption( + roomNotificationSettingsItem: RoomNotificationSettingsItem, + modifier: Modifier = Modifier, + enabled: Boolean = true, + isSelected: Boolean = false, + onOptionSelected: (RoomNotificationSettingsItem) -> Unit = {}, +) { + Row( + modifier + .fillMaxWidth() + .selectable( + selected = isSelected, + enabled = enabled, + onClick = { onOptionSelected(roomNotificationSettingsItem) }, + role = Role.RadioButton, + ) + .padding(8.dp), + ) { + Column( + Modifier + .weight(1f) + .padding(horizontal = 8.dp) + .align(Alignment.CenterVertically) + ) { + Text( + text = roomNotificationSettingsItem.title, + style = ElementTheme.typography.fontBodyLgRegular, + color = enabled.toEnabledColor(), + ) + } + + RadioButton( + modifier = Modifier + .align(Alignment.CenterVertically) + .size(48.dp), + selected = isSelected, + enabled = enabled, + onClick = null // null recommended for accessibility with screenreaders + ) + } +} + +@DayNightPreviews +@Composable +internal fun RoomPrivacyOptionLightPreview() = ElementPreview { ContentToPreview() } + +@Composable +private fun ContentToPreview() { + Column { + RoomNotificationSettingsOption( + roomNotificationSettingsItem = roomNotificationSettingsItems().first(), + isSelected = true, + ) + RoomNotificationSettingsOption( + roomNotificationSettingsItem = roomNotificationSettingsItems().last(), + isSelected = false, + enabled = false, + ) + } +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt new file mode 100644 index 0000000000..fd9f0bc930 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService +import io.element.android.libraries.matrix.api.room.MatrixRoom +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.roomNotificationSettings +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import javax.inject.Inject +import kotlin.time.Duration.Companion.seconds + +class RoomNotificationSettingsPresenter @Inject constructor( + private val room: MatrixRoom, + private val notificationSettingsService: NotificationSettingsService, +) : Presenter { + + @Composable + override fun present(): RoomNotificationSettingsState { + val defaultRoomNotificationMode: MutableState = rememberSaveable { + mutableStateOf(null) + } + val localCoroutineScope = rememberCoroutineScope() + + LaunchedEffect(Unit) { + getDefaultRoomNotificationMode(defaultRoomNotificationMode) + observeNotificationSettings() + } + + val roomNotificationSettingsState by room.roomNotificationSettingsStateFlow.collectAsState() + + fun handleEvents(event: RoomNotificationSettingsEvents) { + when (event) { + is RoomNotificationSettingsEvents.RoomNotificationModeChanged -> { + localCoroutineScope.setRoomNotificationMode(event.mode) + } + is RoomNotificationSettingsEvents.SetNotificationMode -> { + if (event.isDefault) { + localCoroutineScope.restoreDefaultRoomNotificationMode() + } else { + defaultRoomNotificationMode.value?.let { + localCoroutineScope.setRoomNotificationMode(it) + } + } + } + } + } + + return RoomNotificationSettingsState( + roomNotificationSettings = roomNotificationSettingsState.roomNotificationSettings(), + defaultRoomNotificationMode = defaultRoomNotificationMode.value, + eventSink = ::handleEvents, + ) + } + + @OptIn(FlowPreview::class) + private fun CoroutineScope.observeNotificationSettings() { + notificationSettingsService.notificationSettingsChangeFlow + .debounce(0.5.seconds) + .onEach { + room.updateRoomNotificationSettings() + } + .launchIn(this) + } + + private fun CoroutineScope.getDefaultRoomNotificationMode(defaultRoomNotificationMode: MutableState) = launch { + defaultRoomNotificationMode.value = notificationSettingsService.getDefaultRoomNotificationMode( + room.isEncrypted, + room.activeMemberCount + ).getOrThrow() + } + + private fun CoroutineScope.setRoomNotificationMode(mode: RoomNotificationMode) = launch { + notificationSettingsService.setRoomNotificationMode(room.roomId, mode) + } + + private fun CoroutineScope.restoreDefaultRoomNotificationMode() = launch { + notificationSettingsService.restoreDefaultRoomNotificationMode(room.roomId) + } +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt new file mode 100644 index 0000000000..04742781b5 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings + +data class RoomNotificationSettingsState( + val roomNotificationSettings: RoomNotificationSettings?, + val defaultRoomNotificationMode: RoomNotificationMode?, + val eventSink: (RoomNotificationSettingsEvents) -> Unit +) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt new file mode 100644 index 0000000000..df1dd7977b --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings + +internal class RoomNotificationSettingsStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + RoomNotificationSettingsState( + RoomNotificationSettings( + mode = RoomNotificationMode.MUTE, + isDefault = true), + RoomNotificationMode.ALL_MESSAGES, + eventSink = { }, + ), + ) +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt new file mode 100644 index 0000000000..3709280477 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.impl.notificationsettings + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.features.roomdetails.impl.R +import io.element.android.libraries.core.bool.orTrue +import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch +import io.element.android.libraries.designsystem.components.preferences.PreferenceText +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.aliasScreenTitle +import io.element.android.libraries.designsystem.theme.components.Scaffold +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun RoomNotificationSettingsView( + state: RoomNotificationSettingsState, + modifier: Modifier = Modifier, + onBackPressed: () -> Unit = {}, +) { + Scaffold( + modifier = modifier, + topBar = { + RoomNotificationSettingsTopBar( + onBackPressed = { onBackPressed() } + ) + } + ) { padding -> + Column( + modifier = Modifier + .fillMaxWidth() + .padding(padding) + .consumeWindowInsets(padding), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + val subtitle = when(state.defaultRoomNotificationMode) { + RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_room_notification_settings_mode_all_messages) + RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> stringResource(id = R.string.screen_room_notification_settings_mode_mentions_and_keywords) + RoomNotificationMode.MUTE -> stringResource(id = CommonStrings.common_mute) + null -> "" + } + + + PreferenceCategory(title = stringResource(id = R.string.screen_room_notification_settings_custom_settings_title)) { + PreferenceSwitch( + isChecked = state.roomNotificationSettings?.isDefault.orTrue(), + onCheckedChange = { + state.eventSink(RoomNotificationSettingsEvents.SetNotificationMode(it)) + }, + title = "Match default setting", + subtitle = subtitle, + enabled = state.roomNotificationSettings != null + ) + + PreferenceText( + title = stringResource(id = R.string.screen_room_notification_settings_allow_custom), + subtitle = stringResource(id = R.string.screen_room_notification_settings_allow_custom_footnote), + enabled = state.roomNotificationSettings != null && !state.roomNotificationSettings.isDefault, + ) + + if (state.roomNotificationSettings != null) { + RoomNotificationSettingsOptions( + selected = state.roomNotificationSettings.mode, + enabled = !state.roomNotificationSettings.isDefault, + onOptionSelected = { + state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode)) + }, + ) + } + } + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun RoomNotificationSettingsTopBar( + modifier: Modifier = Modifier, + onBackPressed: () -> Unit = {}, +) { + TopAppBar( + modifier = modifier, + title = { + Text( + text = stringResource(R.string.screen_room_details_notification_title), + style = ElementTheme.typography.aliasScreenTitle, + ) + }, + navigationIcon = { BackButton(onClick = onBackPressed) }, + ) +} + +@Composable +fun RoomNotificationSettingsOptions( + selected: RoomNotificationMode?, + enabled: Boolean, + modifier: Modifier = Modifier, + onOptionSelected: (RoomNotificationSettingsItem) -> Unit = {}, +) { + val items = roomNotificationSettingsItems() + Column(modifier = modifier.selectableGroup()) { + items.forEach { item -> + RoomNotificationSettingsOption( + roomNotificationSettingsItem = item, + isSelected = selected == item.mode, + onOptionSelected = onOptionSelected, + enabled = enabled + ) + } + } +} + +@Preview +@Composable +internal fun RoomNotificationSettingsLightPreview(@PreviewParameter(RoomNotificationSettingsStateProvider::class) state: RoomNotificationSettingsState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +internal fun RoomNotificationSettingsDarkPreview(@PreviewParameter(RoomNotificationSettingsStateProvider::class) state: RoomNotificationSettingsState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: RoomNotificationSettingsState) { + RoomNotificationSettingsView(state) +} diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 2696cc99ea..34fae4fea9 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -23,6 +23,16 @@ "Partager le salon" "Mise à jour du salon…" "En attente" + "Autoriser les paramètres personnalisés" + "Activer cette option remplacera votre paramètre par défaut" + "Me notifier dans ce chat pour" + "paramètres généraux" + "Paramètre par défaut" + "Une erreur s’est produite lors du chargement des paramètres de notification." + "Impossible de restaurer le mode par défaut, veuillez réessayer." + "Impossible de régler le mode, veuillez réessayer." + "Tous les messages" + "Mentions et mots-clés uniquement" "Bloquer" "Les utilisateurs bloqués ne pourront pas vous envoyer de messages et tous leurs messages seront masqués. Vous pouvez les débloquer à tout moment." "Bloquer l\'utilisateur" diff --git a/features/roomdetails/impl/src/main/res/values-ru/translations.xml b/features/roomdetails/impl/src/main/res/values-ru/translations.xml index 4d2664ab30..4154f041ff 100644 --- a/features/roomdetails/impl/src/main/res/values-ru/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ru/translations.xml @@ -25,6 +25,17 @@ "Обновление комнаты…" "В ожидании" "Участники комнаты" + "Разрешить пользовательские настройки" + "Включение этого параметра отменяет настройки по умолчанию" + "Уведомить меня в этом чате" + "Вы можете изменить его в своем %1$s." + "Основные Настройки" + "Настройка по умолчанию" + "Произошла ошибка при загрузке настроек уведомлений." + "Не удалось восстановить режим по умолчанию, попробуйте еще раз." + "Не удалось настроить режим, попробуйте еще раз." + "Все сообщения" + "Только упоминания и ключевые слова" "Заблокировать" "Заблокированные пользователи не смогут отправлять вам сообщения, а все их сообщения будут скрыты. Вы можете разблокировать их в любое время." "Заблокировать пользователя" diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml index 1d744fba30..687c495ce7 100644 --- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml @@ -25,6 +25,17 @@ "Aktualizácia miestnosti…" "Čaká sa" "Členovia miestnosti" + "Povoliť vlastné nastavenie" + "Zapnutím tohto nastavenia sa prepíše vaše predvolené nastavenie" + "Upozorniť ma v tejto konverzácii na" + "Môžete to zmeniť vo svojich %1$s." + "všeobecných nastaveniach" + "Predvolené nastavenie" + "Pri načítavaní nastavení oznámení došlo k chybe." + "Nepodarilo sa obnoviť predvolený režim, skúste to prosím znova." + "Nepodarilo sa nastaviť režim, skúste to prosím znova." + "Všetky správy" + "Iba zmienky a kľúčové slová" "Zablokovať" "Blokovaní používatelia vám nebudú môcť posielať správy a všetky ich správy budú skryté. Môžete ich kedykoľvek odblokovať." "Zablokovať používateľa" diff --git a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml index fb7872844a..7b4eb895ea 100644 --- a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml @@ -18,6 +18,12 @@ "正在更新聊天室…" "待定" "聊天室成員" + "全域設定" + "預設" + "無法重設為預設模式,請再試一次。" + "無法設定模式,請再試一次。" + "所有訊息" + "只限提及與關鍵字" "封鎖" "封鎖使用者" "解除封鎖" diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index b1f67dab1e..717f503e22 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -24,6 +24,17 @@ "Updating room…" "Pending" "Room members" + "Allow custom setting" + "Turning this on will override your default setting" + "Notify me in this chat for" + "You can change it in your %1$s." + "global settings" + "Default setting" + "An error occurred while loading notification settings." + "Failed restoring the default mode, please try again." + "Failed setting the mode, please try again." + "All messages" + "Mentions and Keywords only" "Block" "Blocked users won\'t be able to send you messages and all their messages will be hidden. You can unblock them anytime." "Block user" diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt index 275b4888d1..71695094b3 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt @@ -29,22 +29,30 @@ import io.element.android.features.roomdetails.impl.RoomDetailsType import io.element.android.features.roomdetails.impl.RoomTopicState import io.element.android.features.roomdetails.impl.members.aRoomMember import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService 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.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState +import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.consumeItemsUntilPredicate +import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test +import kotlin.time.Duration.Companion.milliseconds @ExperimentalCoroutinesApi class RoomDetailsPresenterTests { @@ -52,20 +60,37 @@ class RoomDetailsPresenterTests { @Rule @JvmField val warmUpRule = WarmUpRule() + private fun aRoomDetailsPresenter( + room: MatrixRoom, + leaveRoomPresenter: LeaveRoomPresenter = LeaveRoomPresenterFake(), + dispatchers: CoroutineDispatchers, + notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService() + ): RoomDetailsPresenter { + val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService) - private fun aRoomDetailsPresenter(room: MatrixRoom, leaveRoomPresenter: LeaveRoomPresenter = LeaveRoomPresenterFake()): RoomDetailsPresenter { val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory { override fun create(roomMemberId: UserId): RoomMemberDetailsPresenter { - return RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMemberId) + return RoomMemberDetailsPresenter(matrixClient, room, roomMemberId) } } - return RoomDetailsPresenter(room, roomMemberDetailsPresenterFactory, leaveRoomPresenter) + val featureFlagService = FakeFeatureFlagService( + mapOf(FeatureFlags.NotificationSettings.key to true) + ) + return RoomDetailsPresenter( + matrixClient, + room, + featureFlagService, + matrixClient.notificationSettingsService(), + roomMemberDetailsPresenterFactory, + leaveRoomPresenter, + dispatchers + ) } @Test fun `present - initial state is created from room info`() = runTest { val room = aMatrixRoom() - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -84,7 +109,7 @@ class RoomDetailsPresenterTests { @Test fun `present - initial state with no room name`() = runTest { val room = aMatrixRoom(name = null) - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -106,7 +131,7 @@ class RoomDetailsPresenterTests { val roomMembers = listOf(myRoomMember, otherRoomMember) givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -122,7 +147,7 @@ class RoomDetailsPresenterTests { val room = aMatrixRoom().apply { givenCanInviteResult(Result.success(true)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -140,11 +165,13 @@ class RoomDetailsPresenterTests { val room = aMatrixRoom().apply { givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { assertThat(awaitItem().canInvite).isFalse() + + cancelAndIgnoreRemainingEvents() } } @@ -153,11 +180,13 @@ class RoomDetailsPresenterTests { val room = aMatrixRoom().apply { givenCanInviteResult(Result.failure(Throwable("Whoops"))) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { assertThat(awaitItem().canInvite).isFalse() + + cancelAndIgnoreRemainingEvents() } } @@ -169,7 +198,7 @@ class RoomDetailsPresenterTests { givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Whelp"))) givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -198,7 +227,7 @@ class RoomDetailsPresenterTests { givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true)) givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -227,7 +256,7 @@ class RoomDetailsPresenterTests { givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -248,7 +277,7 @@ class RoomDetailsPresenterTests { givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true)) givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -269,12 +298,14 @@ class RoomDetailsPresenterTests { givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false)) givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { // Initially false, and no further events assertThat(awaitItem().canEdit).isFalse() + + cancelAndIgnoreRemainingEvents() } } @@ -285,12 +316,14 @@ class RoomDetailsPresenterTests { givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { // The initial state is "hidden" and no further state changes happen assertThat(awaitItem().roomTopic).isEqualTo(RoomTopicState.Hidden) + + cancelAndIgnoreRemainingEvents() } } @@ -301,7 +334,7 @@ class RoomDetailsPresenterTests { givenCanInviteResult(Result.success(false)) } - val presenter = aRoomDetailsPresenter(room) + val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -319,7 +352,7 @@ class RoomDetailsPresenterTests { fun `present - leave room event is passed on to leave room presenter`() = runTest { val leaveRoomPresenter = LeaveRoomPresenterFake() val room = aMatrixRoom() - val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter) + val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -330,6 +363,64 @@ class RoomDetailsPresenterTests { cancelAndIgnoreRemainingEvents() } } + + @Test + fun `present - notification mode changes`() = runTest { + val leaveRoomPresenter = LeaveRoomPresenterFake() + val notificationSettingsService = FakeNotificationSettingsService() + val room = aMatrixRoom(notificationSettingsService = notificationSettingsService) + val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + + notificationSettingsService.setRoomNotificationMode(room.roomId, RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) + val updatedState = consumeItemsUntilPredicate { + it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY + }.last() + assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - mute room notifications`() = runTest { + val leaveRoomPresenter = LeaveRoomPresenterFake() + val notificationSettingsService = FakeNotificationSettingsService(initialMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) + val room = aMatrixRoom(notificationSettingsService = notificationSettingsService) + val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + awaitItem().eventSink(RoomDetailsEvent.MuteNotification) + val updatedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) { + it.roomNotificationSettings?.mode == RoomNotificationMode.MUTE + }.last() + assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MUTE) + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - unmute room notifications`() = runTest { + val leaveRoomPresenter = LeaveRoomPresenterFake() + val notificationSettingsService = FakeNotificationSettingsService( + initialMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, + initialDefaultMode = RoomNotificationMode.ALL_MESSAGES + ) + val room = aMatrixRoom(notificationSettingsService = notificationSettingsService) + val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + awaitItem().eventSink(RoomDetailsEvent.UnmuteNotification) + val updatedState = consumeItemsUntilPredicate { + it.roomNotificationSettings?.mode == RoomNotificationMode.ALL_MESSAGES + }.last() + assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.ALL_MESSAGES) + cancelAndIgnoreRemainingEvents() + } + } } fun aMatrixRoom( @@ -341,6 +432,7 @@ fun aMatrixRoom( isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, + notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService() ) = FakeMatrixRoom( roomId = roomId, name = name, @@ -350,5 +442,6 @@ fun aMatrixRoom( isEncrypted = isEncrypted, isPublic = isPublic, isDirect = isDirect, + notificationSettingsService = notificationSettingsService ) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/notificationsettings/RoomNotificationSettingsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/notificationsettings/RoomNotificationSettingsPresenterTests.kt new file mode 100644 index 0000000000..29bec7f622 --- /dev/null +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/notificationsettings/RoomNotificationSettingsPresenterTests.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 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.features.roomdetails.notificationsettings + +import app.cash.molecule.RecompositionMode +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth +import io.element.android.features.roomdetails.aMatrixRoom +import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsEvents +import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsPresenter +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.test.A_ROOM_NOTIFICATION_MODE +import io.element.android.tests.testutils.consumeItemsUntilPredicate +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class RoomNotificationSettingsPresenterTests { + @Test + fun `present - initial state is created from room info`() = runTest { + val presenter = aNotificationPresenter + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + Truth.assertThat(initialState.roomNotificationSettings).isNull() + Truth.assertThat(initialState.defaultRoomNotificationMode).isNull() + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - notification mode changed`() = runTest { + val presenter = aNotificationPresenter + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + awaitItem().eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)) + val updatedState = consumeItemsUntilPredicate { + it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY + }.last() + Truth.assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) + } + } + + @Test + fun `present - notification settings restore default`() = runTest { + val presenter = aNotificationPresenter + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)) + initialState.eventSink(RoomNotificationSettingsEvents.SetNotificationMode(true)) + val defaultState = consumeItemsUntilPredicate { + it.roomNotificationSettings?.mode == A_ROOM_NOTIFICATION_MODE + }.last() + Truth.assertThat(defaultState.roomNotificationSettings?.mode).isEqualTo(A_ROOM_NOTIFICATION_MODE) + } + } + + private val aNotificationPresenter: RoomNotificationSettingsPresenter get() { + val room = aMatrixRoom() + return RoomNotificationSettingsPresenter( + room = room, + notificationSettingsService = room.notificationSettingsService + ) + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt index 3f204ee847..9a5f6b9a41 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt @@ -39,6 +39,8 @@ import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.toEnabledColor +import io.element.android.libraries.designsystem.toSecondaryEnabledColor import io.element.android.libraries.theme.ElementTheme /** @@ -48,6 +50,7 @@ import io.element.android.libraries.theme.ElementTheme fun PreferenceText( title: String, modifier: Modifier = Modifier, + enabled: Boolean = true, subtitle: String? = null, currentValue: String? = null, loadingCurrentValue: Boolean = false, @@ -68,8 +71,9 @@ fun PreferenceText( ) { PreferenceIcon( icon = icon, + enabled = enabled, isVisible = showIconAreaIfNoIcon, - tintColor = tintColor ?: ElementTheme.materialColors.secondary + tintColor = tintColor ?: enabled.toSecondaryEnabledColor(), ) Column( modifier = Modifier @@ -79,13 +83,13 @@ fun PreferenceText( Text( style = ElementTheme.typography.fontBodyLgRegular, text = title, - color = tintColor ?: ElementTheme.materialColors.primary, + color = tintColor ?: enabled.toEnabledColor(), ) if (subtitle != null) { Text( style = ElementTheme.typography.fontBodyMdRegular, text = subtitle, - color = tintColor ?: ElementTheme.materialColors.secondary, + color = tintColor ?: enabled.toSecondaryEnabledColor(), ) } } @@ -96,7 +100,7 @@ fun PreferenceText( .padding(start = 16.dp, end = 8.dp), text = currentValue, style = ElementTheme.typography.fontBodyXsMedium, - color = ElementTheme.materialColors.secondary, + color = enabled.toSecondaryEnabledColor(), ) } else if (loadingCurrentValue) { CircularProgressIndicator( @@ -135,6 +139,13 @@ private fun ContentToPreview() { icon = Icons.Default.BugReport, currentValue = "123", ) + PreferenceText( + title = "Title", + subtitle = "Some content", + icon = Icons.Default.BugReport, + currentValue = "123", + enabled = false, + ) PreferenceText( title = "Title", subtitle = "Some content", diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index c28dc28144..6490b4e357 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -30,5 +30,11 @@ enum class FeatureFlags( key = "feature.polls", title = "Polls", description = "Create poll and render poll events in the timeline", + defaultValue = false, + ), + NotificationSettings( + key = "feature.notificationsettings", + title = "Show notification settings", + defaultValue = false, ), } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt index 83913cbac5..0117a4aa22 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt @@ -31,6 +31,7 @@ class BuildtimeFeatureFlagProvider @Inject constructor() : when (feature) { FeatureFlags.LocationSharing -> true FeatureFlags.Polls -> false + FeatureFlags.NotificationSettings -> false } } else { false diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 2ca4420145..63093064b6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.notification.NotificationService +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.RoomMembershipObserver @@ -49,6 +50,7 @@ interface MatrixClient : Closeable { fun sessionVerificationService(): SessionVerificationService fun pushersService(): PushersService fun notificationService(): NotificationService + fun notificationSettingsService(): NotificationSettingsService suspend fun getCacheSize(): Long /** diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt new file mode 100644 index 0000000000..0f82604aba --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.api.notificationsettings + +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.MatrixRoomNotificationSettingsState +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import kotlinx.coroutines.flow.SharedFlow + +interface NotificationSettingsService { + /** + * State of the current room notification settings flow ([MatrixRoomNotificationSettingsState.Unknown] if not started). + */ + val notificationSettingsChangeFlow : SharedFlow + suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, membersCount: Long): Result + suspend fun getDefaultRoomNotificationMode(isEncrypted: Boolean, membersCount: Long): Result + suspend fun setRoomNotificationMode(roomId: RoomId, mode: RoomNotificationMode): Result + suspend fun restoreDefaultRoomNotificationMode(roomId: RoomId): Result + suspend fun muteRoom(roomId: RoomId): Result + suspend fun unmuteRoom(roomId: RoomId, isEncrypted: Boolean, membersCount: Long): Result +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 41f105df8e..60c8b1ddd5 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -56,11 +56,15 @@ interface MatrixRoom : Closeable { */ val membersStateFlow: StateFlow + val roomNotificationSettingsStateFlow: StateFlow + /** * Try to load the room members and update the membersFlow. */ suspend fun updateMembers(): Result + suspend fun updateRoomNotificationSettings(): Result + val syncUpdateFlow: StateFlow val timeline: MatrixTimeline diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomNotificationSettingsState.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomNotificationSettingsState.kt new file mode 100644 index 0000000000..d98a3a83d2 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomNotificationSettingsState.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.api.room + +sealed interface MatrixRoomNotificationSettingsState { + object Unknown : MatrixRoomNotificationSettingsState + data class Pending(val prevRoomNotificationSettings: RoomNotificationSettings? = null) : MatrixRoomNotificationSettingsState + data class Error(val failure: Throwable, val prevRoomNotificationSettings: RoomNotificationSettings? = null) : MatrixRoomNotificationSettingsState + data class Ready(val roomNotificationSettings: RoomNotificationSettings) : MatrixRoomNotificationSettingsState +} + +fun MatrixRoomNotificationSettingsState.roomNotificationSettings(): RoomNotificationSettings? { + return when (this) { + is MatrixRoomNotificationSettingsState.Ready -> roomNotificationSettings + is MatrixRoomNotificationSettingsState.Pending -> prevRoomNotificationSettings + is MatrixRoomNotificationSettingsState.Error -> prevRoomNotificationSettings + else -> null + } +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomNotificationSettings.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomNotificationSettings.kt new file mode 100644 index 0000000000..23f2b41797 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomNotificationSettings.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.api.room + +data class RoomNotificationSettings( + val mode: RoomNotificationMode, + val isDefault: Boolean, +) + +enum class RoomNotificationMode { + ALL_MESSAGES, MENTIONS_AND_KEYWORDS_ONLY, MUTE +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 54641f785b..22f1e9af3f 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.notification.NotificationService +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.RoomMembershipObserver @@ -42,6 +43,7 @@ import io.element.android.libraries.matrix.impl.core.toProgressWatcher import io.element.android.libraries.matrix.impl.mapper.toSessionData import io.element.android.libraries.matrix.impl.media.RustMediaLoader import io.element.android.libraries.matrix.impl.notification.RustNotificationService +import io.element.android.libraries.matrix.impl.notificationsettings.RustNotificationSettingsService import io.element.android.libraries.matrix.impl.pushers.RustPushersService import io.element.android.libraries.matrix.impl.room.RoomContentForwarder import io.element.android.libraries.matrix.impl.room.RustMatrixRoom @@ -99,6 +101,7 @@ class RustMatrixClient constructor( client = client, dispatchers = dispatchers, ) + private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(syncService) private val notificationClient = client.notificationClient(notificationProcessSetup) .use { builder -> @@ -106,8 +109,10 @@ class RustMatrixClient constructor( .filterByPushRules() .finish() } + private val notificationSettings = client.getNotificationSettings() private val notificationService = RustNotificationService(sessionId, notificationClient, dispatchers, clock) + private val notificationSettingsService = RustNotificationSettingsService(notificationSettings, dispatchers) private val isLoggingOut = AtomicBoolean(false) @@ -173,6 +178,7 @@ class RustMatrixClient constructor( sessionId = sessionId, roomListItem = roomListItem, innerRoom = fullRoom, + roomNotificationSettingsService = notificationSettingsService, sessionCoroutineScope = sessionCoroutineScope, coroutineDispatchers = dispatchers, systemClock = clock, @@ -277,9 +283,13 @@ class RustMatrixClient constructor( override fun notificationService(): NotificationService = notificationService + override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService + override fun close() { sessionCoroutineScope.cancel() client.setDelegate(null) + notificationSettings.setDelegate(null) + notificationSettings.destroy() verificationService.destroy() syncService.destroy() innerRoomListService.destroy() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt index dba1dbd0a3..1159f668e6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt @@ -22,6 +22,7 @@ import dagger.Provides import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.verification.SessionVerificationService @@ -34,6 +35,11 @@ object SessionMatrixModule { return matrixClient.sessionVerificationService() } + @Provides + fun providesNotificationSettingsService(matrixClient: MatrixClient): NotificationSettingsService { + return matrixClient.notificationSettingsService() + } + @Provides fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver { return matrixClient.roomMembershipObserver() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RoomNotificationSettingsMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RoomNotificationSettingsMapper.kt new file mode 100644 index 0000000000..084a6f973e --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RoomNotificationSettingsMapper.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.impl.notificationsettings + +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode +import org.matrix.rustcomponents.sdk.RoomNotificationSettings as RustRoomNotificationSettings + +object RoomNotificationSettingsMapper { + fun map(roomNotificationSettings: RustRoomNotificationSettings): RoomNotificationSettings = + RoomNotificationSettings( + mode = mapMode(roomNotificationSettings.mode), + isDefault = roomNotificationSettings.isDefault + ) + + fun mapMode(mode: RustRoomNotificationMode): RoomNotificationMode = + when (mode) { + RustRoomNotificationMode.ALL_MESSAGES -> RoomNotificationMode.ALL_MESSAGES + RustRoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY + RustRoomNotificationMode.MUTE -> RoomNotificationMode.MUTE + } + + fun mapMode(mode: RoomNotificationMode): RustRoomNotificationMode = + when (mode) { + RoomNotificationMode.ALL_MESSAGES -> RustRoomNotificationMode.ALL_MESSAGES + RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> RustRoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY + RoomNotificationMode.MUTE -> RustRoomNotificationMode.MUTE + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt new file mode 100644 index 0000000000..1b1d51214f --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.impl.notificationsettings + +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.withContext +import org.matrix.rustcomponents.sdk.NotificationSettings +import org.matrix.rustcomponents.sdk.NotificationSettingsDelegate + +class RustNotificationSettingsService( + private val notificationSettings: NotificationSettings, + private val dispatchers: CoroutineDispatchers, +) : NotificationSettingsService { + + private val _notificationSettingsChangeFlow = MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) + override val notificationSettingsChangeFlow: SharedFlow = _notificationSettingsChangeFlow.asSharedFlow() + + private var notificationSettingsDelegate = object : NotificationSettingsDelegate { + override fun settingsDidChange() { + _notificationSettingsChangeFlow.tryEmit(Unit) + } + } + + init { + notificationSettings.setDelegate(notificationSettingsDelegate) + } + + override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, membersCount: Long): Result = + runCatching { + notificationSettings.getRoomNotificationSettings(roomId.value, isEncrypted, isOneToOne(membersCount)).let(RoomNotificationSettingsMapper::map) + } + + override suspend fun getDefaultRoomNotificationMode(isEncrypted: Boolean, membersCount: Long): Result = + runCatching { + notificationSettings.getDefaultRoomNotificationMode(isEncrypted, isOneToOne(membersCount)).let(RoomNotificationSettingsMapper::mapMode) + } + + override suspend fun setRoomNotificationMode(roomId: RoomId, mode: RoomNotificationMode): Result = withContext(dispatchers.io) { + runCatching { + notificationSettings.setRoomNotificationMode(roomId.value, mode.let(RoomNotificationSettingsMapper::mapMode)) + } + } + + override suspend fun restoreDefaultRoomNotificationMode(roomId: RoomId): Result = withContext(dispatchers.io) { + runCatching { + notificationSettings.restoreDefaultRoomNotificationMode(roomId.value) + } + } + + override suspend fun muteRoom(roomId: RoomId): Result = setRoomNotificationMode(roomId, RoomNotificationMode.MUTE) + + override suspend fun unmuteRoom(roomId: RoomId, isEncrypted: Boolean, membersCount: Long) = withContext(dispatchers.io) { + runCatching { + notificationSettings.unmuteRoom(roomId.value, isEncrypted, isOneToOne(membersCount)) + } + } + + /** + * A one-to-one is a room with exactly 2 members. + * See [the Matrix spec](https://spec.matrix.org/latest/client-server-api/#default-underride-rules). + * @param membersCount The active members count in a room + */ + private fun isOneToOne(membersCount: Long) = membersCount == 2L +} 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 71caed8f19..461e43931e 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 @@ -33,16 +33,19 @@ import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState +import io.element.android.libraries.matrix.api.room.MatrixRoomNotificationSettingsState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.roomMembers +import io.element.android.libraries.matrix.api.room.roomNotificationSettings import io.element.android.libraries.matrix.api.timeline.MatrixTimeline import io.element.android.libraries.matrix.api.timeline.item.event.EventType import io.element.android.libraries.matrix.impl.core.toProgressWatcher import io.element.android.libraries.matrix.impl.media.MediaUploadHandlerImpl import io.element.android.libraries.matrix.impl.media.map import io.element.android.libraries.matrix.impl.poll.toInner +import io.element.android.libraries.matrix.impl.notificationsettings.RustNotificationSettingsService import io.element.android.libraries.matrix.impl.room.location.toInner import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline import io.element.android.libraries.matrix.impl.util.destroyAll @@ -72,6 +75,7 @@ class RustMatrixRoom( override val sessionId: SessionId, private val roomListItem: RoomListItem, private val innerRoom: Room, + private val roomNotificationSettingsService: RustNotificationSettingsService, sessionCoroutineScope: CoroutineScope, private val coroutineDispatchers: CoroutineDispatchers, private val systemClock: SystemClock, @@ -90,6 +94,10 @@ class RustMatrixRoom( private val roomCoroutineScope = sessionCoroutineScope.childScope(coroutineDispatchers.main, "RoomScope-$roomId") private val _membersStateFlow = MutableStateFlow(MatrixRoomMembersState.Unknown) private val _syncUpdateFlow = MutableStateFlow(0L) + + private val _roomNotificationSettingsStateFlow = MutableStateFlow(MatrixRoomNotificationSettingsState.Unknown) + override val roomNotificationSettingsStateFlow: StateFlow = _roomNotificationSettingsStateFlow + private val _timeline by lazy { RustMatrixTimeline( matrixRoom = this, @@ -197,6 +205,22 @@ class RustMatrixRoom( } } + override suspend fun updateRoomNotificationSettings(): Result = withContext(coroutineDispatchers.io) { + val currentState = _roomNotificationSettingsStateFlow.value + val currentRoomNotificationSettings = currentState.roomNotificationSettings() + _roomNotificationSettingsStateFlow.value = MatrixRoomNotificationSettingsState.Pending(prevRoomNotificationSettings = currentRoomNotificationSettings) + runCatching { + roomNotificationSettingsService.getRoomNotificationSettings(roomId, isEncrypted, activeMemberCount).getOrThrow() + }.map { + _roomNotificationSettingsStateFlow.value = MatrixRoomNotificationSettingsState.Ready(it) + }.onFailure { + _roomNotificationSettingsStateFlow.value = MatrixRoomNotificationSettingsState.Error( + prevRoomNotificationSettings = currentRoomNotificationSettings, + failure = it + ) + } + } + override suspend fun userAvatarUrl(userId: UserId): Result = withContext(roomDispatcher) { runCatching { innerRoom.memberAvatarUrl(userId.value) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 83f7f3ad79..9ef50ecda5 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.notification.NotificationService +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.RoomMembershipObserver @@ -33,6 +34,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.test.media.FakeMediaLoader import io.element.android.libraries.matrix.test.notification.FakeNotificationService +import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.pushers.FakePushersService import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService @@ -50,6 +52,7 @@ class FakeMatrixClient( private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), private val pushersService: FakePushersService = FakePushersService(), private val notificationService: FakeNotificationService = FakeNotificationService(), + private val notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), private val syncService: FakeSyncService = FakeSyncService(), private val accountManagementUrlString: Result = Result.success(null), ) : MatrixClient { @@ -142,6 +145,7 @@ class FakeMatrixClient( override fun pushersService(): PushersService = pushersService override fun notificationService(): NotificationService = notificationService + override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService override fun roomMembershipObserver(): RoomMembershipObserver { return RoomMembershipObserver() diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index f6b6e1645f..cae5df4dc4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -24,6 +24,8 @@ import io.element.android.libraries.matrix.api.core.SpaceId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.TransactionId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings const val A_USER_NAME = "alice" const val A_PASSWORD = "password" @@ -59,6 +61,8 @@ const val A_HOMESERVER_URL_2 = "matrix-client.org" val A_HOMESERVER = MatrixHomeServerDetails(A_HOMESERVER_URL, supportsPasswordLogin = true, supportsOidcLogin = false) val A_HOMESERVER_OIDC = MatrixHomeServerDetails(A_HOMESERVER_URL, supportsPasswordLogin = false, supportsOidcLogin = true) +val A_ROOM_NOTIFICATION_MODE = RoomNotificationMode.MUTE +val A_ROOM_NOTIFICATION_SETTINGS = RoomNotificationSettings(mode = A_ROOM_NOTIFICATION_MODE, isDefault = false) const val AN_AVATAR_URL = "mxc://data" diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt new file mode 100644 index 0000000000..852496e0b3 --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 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.libraries.matrix.test.notificationsettings + +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService +import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.room.RoomNotificationSettings +import io.element.android.libraries.matrix.test.A_ROOM_NOTIFICATION_MODE +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow + +class FakeNotificationSettingsService( + initialMode: RoomNotificationMode = A_ROOM_NOTIFICATION_MODE, + initialDefaultMode: RoomNotificationMode = A_ROOM_NOTIFICATION_MODE +) : NotificationSettingsService { + private var _roomNotificationSettingsStateFlow = MutableStateFlow(Unit) + private var defaultRoomNotificationMode: RoomNotificationMode = initialDefaultMode + private var roomNotificationMode: RoomNotificationMode = initialMode + override val notificationSettingsChangeFlow: SharedFlow + get() = _roomNotificationSettingsStateFlow + + override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, membersCount: Long): Result { + return Result.success(RoomNotificationSettings(mode = roomNotificationMode, isDefault = roomNotificationMode == defaultRoomNotificationMode)) + } + + override suspend fun getDefaultRoomNotificationMode(isEncrypted: Boolean, membersCount: Long): Result { + return Result.success(defaultRoomNotificationMode) + } + + override suspend fun setRoomNotificationMode(roomId: RoomId, mode: RoomNotificationMode): Result { + roomNotificationMode = mode + _roomNotificationSettingsStateFlow.emit(Unit) + return Result.success(Unit) + } + + override suspend fun restoreDefaultRoomNotificationMode(roomId: RoomId): Result { + roomNotificationMode = defaultRoomNotificationMode + _roomNotificationSettingsStateFlow.emit(Unit) + return Result.success(Unit) + } + + override suspend fun muteRoom(roomId: RoomId): Result { + return setRoomNotificationMode(roomId, RoomNotificationMode.MUTE) + } + + override suspend fun unmuteRoom(roomId: RoomId, isEncrypted: Boolean, membersCount: Long): Result { + return restoreDefaultRoomNotificationMode(roomId) + } +} 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 7bffb985bb..761e479816 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 @@ -27,16 +27,19 @@ import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaUploadHandler import io.element.android.libraries.matrix.api.media.VideoInfo +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.MatrixRoomNotificationSettingsState import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.MatrixTimeline import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler +import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline import io.element.android.tests.testutils.simulateLongTask import kotlinx.coroutines.delay @@ -58,6 +61,7 @@ class FakeMatrixRoom( override val isDirect: Boolean = false, override val joinedMemberCount: Long = 123L, override val activeMemberCount: Long = 234L, + val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(), private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(), canRedact: Boolean = false, ) : MatrixRoom { @@ -136,10 +140,19 @@ class FakeMatrixRoom( override val membersStateFlow: MutableStateFlow = MutableStateFlow(MatrixRoomMembersState.Unknown) + override val roomNotificationSettingsStateFlow: MutableStateFlow = + MutableStateFlow(MatrixRoomNotificationSettingsState.Unknown) + override suspend fun updateMembers(): Result = simulateLongTask { updateMembersResult } + override suspend fun updateRoomNotificationSettings(): Result = simulateLongTask { + val notificationSettings = notificationSettingsService.getRoomNotificationSettings(roomId, isEncrypted, activeMemberCount).getOrThrow() + roomNotificationSettingsStateFlow.value = MatrixRoomNotificationSettingsState.Ready(notificationSettings) + return Result.success(Unit) + } + override val syncUpdateFlow: StateFlow = MutableStateFlow(0L) override val timeline: MatrixTimeline = matrixTimeline diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 8a9f1cee2f..d6f9f2cbaf 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -1,5 +1,6 @@ + "Use an identity server to invite by email. ""Use the default (%(defaultIdentityServerName)s)"" or manage in ""Settings""." "Hide password" "Mentions only" "Muted" @@ -161,6 +162,10 @@ "Are you sure that you want to leave this room? This room is not public and you won\'t be able to rejoin without an invite." "Are you sure that you want to leave the room?" "%1$s Android" + + "%(count)s room" + "%(count)s rooms" + "%1$d member" "%1$d members" diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsDark_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..352d1a95e1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsDark_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d1c7b862db8afe25dd958c9011de82e1439d298a95ec15a86dfbae0457f7937 +size 36436 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsLight_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..4dc3771f2f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomNotificationSettingsLight_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1900985fb6b9d25eee44af5cdc0c6fcdee994ffc3da8dae5a6e742c3d0b7127 +size 40016 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-D-0_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-D-0_1_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..38c517ea47 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-D-0_1_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62418ebe7afa2c1c7eda2b1251fb189a75527aa7a4289a9478c531fac7dee8bd +size 10666 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-N-0_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-N-0_2_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..cecfc09f64 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_null_RoomPrivacyOptionLight-N-0_2_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5a32b1baaaad0bf266e190084a64b3d382a2d6d472a55b1c3653ee948e100c9 +size 9756 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png index 9ef89a09c3..211bbf07bc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6edcc452c76049a978ceb97b46776446790dbdbe30eef1693fafda089cdc3ee7 -size 55527 +oid sha256:49bd51a32dbd3615364a6039163a36c08d0096a8c511a7084e21b7c1780131db +size 52810 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png index 0dc50f37c2..19f56b887f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20e630b0f3bb9fddd5f11e4e9f2a92b5d35c4bbe182662e8d0fde27451297006 -size 45247 +oid sha256:2c61e5d0eabb1f9cae83c3df0f73f14545e0c61bd7393d6e2862e0f48b9e3d7a +size 51272 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png index ca7b6913d5..ec15315140 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:553b498247e9da02ad037716a67c080a3da2fb07602b0c0c44de8f16a4891eda -size 46086 +oid sha256:adf48ade91c22ce7f98bf2773ec4e14ce0c290f7ba25e8c76d9f722677c46277 +size 44388 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png index 9610377f28..d72802868e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d91c291503dc745092b132fec62208e73dcd031822ca21a66a7fb1f48ecfa6e1 -size 49316 +oid sha256:262ba970549c3c137ab90ffc607279479dfc4fbf86468e18b08ea6c5ef5b0710 +size 53634 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png index 1fe7df1eaa..04edeb3284 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efda43a25fdc2a21a4ad3767b14b4c7a308003f9bcb9e67d64520db13c83f0fd -size 61061 +oid sha256:49d92579bffadd59f89e79217b5e6148bbfeda0c5750a06ad7aa36f8125d6d29 +size 50616 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png index 761666b2e3..2150b91f12 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31f2d59ad03a4d9ba8efd5f146668162f3c2095ac90e16dd3634d3e817f7263d -size 61238 +oid sha256:b742f507ba11be8bdf733e5e751fc5d9fe1c0cc2eb070abf9abcffb605783ab3 +size 52151 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png index 761666b2e3..2150b91f12 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31f2d59ad03a4d9ba8efd5f146668162f3c2095ac90e16dd3634d3e817f7263d -size 61238 +oid sha256:b742f507ba11be8bdf733e5e751fc5d9fe1c0cc2eb070abf9abcffb605783ab3 +size 52151 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png index f7d782f1b8..f94aa99b7b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fba2e76faa5915acf1e9d2ede6b58e1ab73e287aefa6e5ffc643be527350d987 -size 50147 +oid sha256:467ca1b17857b053881cb9999c3d6b099949c6b4279188da57383fdb9083041f +size 53946 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png index 572f6d76e1..dbddc54999 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1089845cd143d07e0d6a363a9dc490ab6f5ae4711fc99843c01e4f074dbdeb98 -size 55780 +oid sha256:d8e1ede8c0ea34595e90b2031c9607b99e72c3d7d1e9a778bbfbece98eb23875 +size 53035 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png index 6620f9dc9f..ca3e37d42a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59054f5692d41c0d6fe65c6f1bc9d0c4e1e3149aedd987e9335fabff7b46d85f -size 57237 +oid sha256:a9f1d200ef2c93d557a67a29700918bd70439c7d7d8d247d60473b26f0c44eb3 +size 53851 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png index 852e18b044..c27ccdc333 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f65151d983057ca185c53b4045fb33675f12730fee1b40e3df6d269e2290a05 -size 47290 +oid sha256:b06e1652745ceff912734b9bf74543c95f4d420eaf3aec4b388dd101ea1428f8 +size 53838 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png index 89ce9d4604..087bd78cc4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de6a5ac50e8b30364b9e630d2edbe49c18cc3684da080e2167f41bd689f17700 -size 48369 +oid sha256:5d4a381a3c99a7f04a11a2e93cd7c4145fa0bd33a1f7461038b3918c5cd94571 +size 46676 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png index 95f7e24521..0ebb4bdfc9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:edcf03466e38ce3906583f2701f45d2a9538a6fd7e9d1c9d4822a037b833a512 -size 50185 +oid sha256:61add95d28096c65f94764df109d253c7b589058cea324d908616312e7dffc3e +size 54723 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png index 2f17f119fc..8a3a6dddf4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:670f05e0c2861234708c7dee4d919a977bbd3aec3e965db631505957871f19fa -size 62904 +oid sha256:3197e871e4b4c39dc714610b54e351c4061149bfc0b5511f78a0c73e8ec2236b +size 51824 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png index d0c76cd680..6547257b66 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9553c9ef84cd1f2e890290e093cb0006f03d1a2f36de5e2b7d104d0eb102b2e2 -size 63045 +oid sha256:a0cf7d5d0c91aa7946586e5258077b07b329f387f46b0df0a29c49cc211ed584 +size 54021 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png index d0c76cd680..6547257b66 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9553c9ef84cd1f2e890290e093cb0006f03d1a2f36de5e2b7d104d0eb102b2e2 -size 63045 +oid sha256:a0cf7d5d0c91aa7946586e5258077b07b329f387f46b0df0a29c49cc211ed584 +size 54021 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png index 0e72199eb0..6879d4dfb5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ab533a35fbbba8b45d94bcfb0637d0f021ee2ef71230754ed418702ee18f11d -size 51182 +oid sha256:cd4be4f49a78aba83c4b5f9c350f8b64cfe96d50890df16154cd7b0e20546d25 +size 55020 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png index 159c179d5c..92a37ad86d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ec34df75877b7050ad874905926f5d35fee29d1f8324437b502d7152ef87cdc -size 57494 +oid sha256:da79bef2bd54301f2724269719d93d1d9212fd17b9dc0d2a7ba935693c6170ac +size 54107 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences_null_Preferences_PreferenceText_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences_null_Preferences_PreferenceText_0_null,NEXUS_5,1.0,en].png index 15e7b55fa2..f757da3a86 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences_null_Preferences_PreferenceText_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences_null_Preferences_PreferenceText_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08af9a706d579b4632c70265b6f1529008bd483cb4924c341e3a9f0172cc8cd4 -size 39251 +oid sha256:bd05144d4b3527a44e1c9f3fb92d227ccc38fd7afce5436f32b59f14f0b54e27 +size 39028 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 05d1ced2c6..cf29033d88 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -92,7 +92,8 @@ "includeRegex": [ "screen_room_details_.*", "screen_room_member_list_.*", - "screen_dm_details_.*" + "screen_dm_details_.*", + "screen_room_notification_settings_.*" ] }, { From c16c875e68cd7650b8285276a3d1c9e2faaf937f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 10:29:10 +0200 Subject: [PATCH 070/127] Rework the feature flag module. Fix typo, rename class and interface, add doc, do small refacto, to improve code clarity. --- .../featureflag/api/FeatureFlagService.kt | 3 ++- .../impl/DefaultFeatureFlagService.kt | 2 +- ...ovider.kt => MutableFeatureFlagProvider.kt} | 2 +- .../impl/PreferencesFeatureFlagProvider.kt | 9 +++++---- ...rovider.kt => StaticFeatureFlagProvider.kt} | 9 ++++++--- .../featureflag/impl/di/FeatureFlagModule.kt | 18 +++++++++++------- .../impl/DefaultFeatureFlagServiceTest.kt | 14 +++++++------- ...er.kt => FakeMutableFeatureFlagProvider.kt} | 2 +- 8 files changed, 34 insertions(+), 25 deletions(-) rename libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/{RuntimeFeatureFlagProvider.kt => MutableFeatureFlagProvider.kt} (92%) rename libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/{BuildtimeFeatureFlagProvider.kt => StaticFeatureFlagProvider.kt} (84%) rename libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/{FakeRuntimeFeatureFlagProvider.kt => FakeMutableFeatureFlagProvider.kt} (92%) diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt index 59e224a1ae..8089c837ff 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt @@ -28,7 +28,8 @@ interface FeatureFlagService { * @param feature the feature to enable or disable * @param enabled true to enable the feature * - * @return true if the method succeeds, ie if a RuntimeFeatureFlagProvider is registered + * @return true if the method succeeds, ie if a [io.element.android.libraries.featureflag.impl.MutableFeatureFlagProvider] + * is registered */ suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean): Boolean } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt index 7298929aea..b445599693 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt @@ -38,7 +38,7 @@ class DefaultFeatureFlagService @Inject constructor( } override suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean): Boolean { - return providers.filterIsInstance(RuntimeFeatureFlagProvider::class.java) + return providers.filterIsInstance(MutableFeatureFlagProvider::class.java) .sortedBy(FeatureFlagProvider::priority) .firstOrNull() ?.setFeatureEnabled(feature, enabled) diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/RuntimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/MutableFeatureFlagProvider.kt similarity index 92% rename from libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/RuntimeFeatureFlagProvider.kt rename to libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/MutableFeatureFlagProvider.kt index 1238ad354c..7e2da181b6 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/RuntimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/MutableFeatureFlagProvider.kt @@ -18,6 +18,6 @@ package io.element.android.libraries.featureflag.impl import io.element.android.libraries.featureflag.api.Feature -interface RuntimeFeatureFlagProvider : FeatureFlagProvider { +interface MutableFeatureFlagProvider : FeatureFlagProvider { suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean) } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/PreferencesFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/PreferencesFeatureFlagProvider.kt index 15ab08b338..ddffdebd34 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/PreferencesFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/PreferencesFeatureFlagProvider.kt @@ -30,12 +30,13 @@ import javax.inject.Inject private val Context.dataStore: DataStore by preferencesDataStore(name = "elementx_featureflag") -class PreferencesFeatureFlagProvider @Inject constructor(@ApplicationContext context: Context) : RuntimeFeatureFlagProvider { - +/** + * Note: this will be used only in the nightly and in the debug build. + */ +class PreferencesFeatureFlagProvider @Inject constructor(@ApplicationContext context: Context) : MutableFeatureFlagProvider { private val store = context.dataStore - override val priority: Int - get() = MEDIUM_PRIORITY + override val priority = MEDIUM_PRIORITY override suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean) { store.edit { prefs -> diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt similarity index 84% rename from libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt rename to libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt index 0117a4aa22..2d66d3be21 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/BuildtimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt @@ -20,11 +20,14 @@ import io.element.android.libraries.featureflag.api.Feature import io.element.android.libraries.featureflag.api.FeatureFlags import javax.inject.Inject -class BuildtimeFeatureFlagProvider @Inject constructor() : +/** + * This provider is used for release build. + * Change the value return by [isFeatureEnabled] to enable/disable features. + */ +class StaticFeatureFlagProvider @Inject constructor() : FeatureFlagProvider { - override val priority: Int - get() = LOW_PRIORITY + override val priority = LOW_PRIORITY override suspend fun isFeatureEnabled(feature: Feature): Boolean { return if (feature is FeatureFlags) { diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/di/FeatureFlagModule.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/di/FeatureFlagModule.kt index 07ee53ceee..b2f0a4106d 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/di/FeatureFlagModule.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/di/FeatureFlagModule.kt @@ -22,7 +22,7 @@ import dagger.Provides import dagger.multibindings.ElementsIntoSet import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.di.AppScope -import io.element.android.libraries.featureflag.impl.BuildtimeFeatureFlagProvider +import io.element.android.libraries.featureflag.impl.StaticFeatureFlagProvider import io.element.android.libraries.featureflag.impl.FeatureFlagProvider import io.element.android.libraries.featureflag.impl.PreferencesFeatureFlagProvider @@ -35,14 +35,18 @@ object FeatureFlagModule { @ElementsIntoSet fun providesFeatureFlagProvider( buildType: BuildType, - runtimeFeatureFlagProvider: PreferencesFeatureFlagProvider, - buildtimeFeatureFlagProvider: BuildtimeFeatureFlagProvider, + mutableFeatureFlagProvider: PreferencesFeatureFlagProvider, + staticFeatureFlagProvider: StaticFeatureFlagProvider, ): Set { val providers = HashSet() - if (buildType == BuildType.RELEASE) { - providers.add(buildtimeFeatureFlagProvider) - } else { - providers.add(runtimeFeatureFlagProvider) + when (buildType) { + BuildType.RELEASE -> { + providers.add(staticFeatureFlagProvider) + } + BuildType.NIGHTLY, + BuildType.DEBUG -> { + providers.add(mutableFeatureFlagProvider) + } } return providers } diff --git a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt index ea9b03acdf..890959639f 100644 --- a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt +++ b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt @@ -39,7 +39,7 @@ class DefaultFeatureFlagServiceTest { @Test fun `given service with a runtime provider when set enabled feature is called then it returns true`() = runTest { - val featureFlagProvider = FakeRuntimeFeatureFlagProvider(0) + val featureFlagProvider = FakeMutableFeatureFlagProvider(0) val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider)) val result = featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true) assertThat(result).isEqualTo(true) @@ -47,7 +47,7 @@ class DefaultFeatureFlagServiceTest { @Test fun `given service with a runtime provider and feature enabled when feature is checked then it returns the correct value`() = runTest { - val featureFlagProvider = FakeRuntimeFeatureFlagProvider(0) + val featureFlagProvider = FakeMutableFeatureFlagProvider(0) val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider)) featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true) assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing)).isEqualTo(true) @@ -57,11 +57,11 @@ class DefaultFeatureFlagServiceTest { @Test fun `given service with 2 runtime providers when feature is checked then it uses the priority correctly`() = runTest { - val lowPriorityfeatureFlagProvider = FakeRuntimeFeatureFlagProvider(LOW_PRIORITY) - val highPriorityfeatureFlagProvider = FakeRuntimeFeatureFlagProvider(HIGH_PRIORITY) - val featureFlagService = DefaultFeatureFlagService(setOf(lowPriorityfeatureFlagProvider, highPriorityfeatureFlagProvider)) - lowPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, false) - highPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, true) + val lowPriorityFeatureFlagProvider = FakeMutableFeatureFlagProvider(LOW_PRIORITY) + val highPriorityFeatureFlagProvider = FakeMutableFeatureFlagProvider(HIGH_PRIORITY) + val featureFlagService = DefaultFeatureFlagService(setOf(lowPriorityFeatureFlagProvider, highPriorityFeatureFlagProvider)) + lowPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, false) + highPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, true) assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing)).isEqualTo(true) } } diff --git a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeRuntimeFeatureFlagProvider.kt b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeMutableFeatureFlagProvider.kt similarity index 92% rename from libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeRuntimeFeatureFlagProvider.kt rename to libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeMutableFeatureFlagProvider.kt index 5ff5cf932f..f1d075ace2 100644 --- a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeRuntimeFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/FakeMutableFeatureFlagProvider.kt @@ -18,7 +18,7 @@ package io.element.android.libraries.featureflag.impl import io.element.android.libraries.featureflag.api.Feature -class FakeRuntimeFeatureFlagProvider(override val priority: Int) : RuntimeFeatureFlagProvider { +class FakeMutableFeatureFlagProvider(override val priority: Int) : MutableFeatureFlagProvider { private val enabledFeatures = HashMap() From aacfa0d83a3983d09dba457c047f72e8ca08b7b1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 10:44:32 +0200 Subject: [PATCH 071/127] To avoid mistake, FeatureFlags does not have `defaultValue` set to true, and `StaticFeatureFlagProvider` return the default value. This fixes #1241. --- changelog.d/1241.bugfix | 1 + .../android/libraries/featureflag/api/FeatureFlags.kt | 9 +++++++-- .../featureflag/impl/StaticFeatureFlagProvider.kt | 8 ++------ 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 changelog.d/1241.bugfix diff --git a/changelog.d/1241.bugfix b/changelog.d/1241.bugfix new file mode 100644 index 0000000000..d2339b3158 --- /dev/null +++ b/changelog.d/1241.bugfix @@ -0,0 +1 @@ +Enable polls in release build. diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 6490b4e357..36113389a4 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -16,21 +16,26 @@ package io.element.android.libraries.featureflag.api +/** + * To enable or disable a FeatureFlags, change the `defaultValue` value. + * It will impact all the build types. + */ enum class FeatureFlags( override val key: String, override val title: String, override val description: String? = null, - override val defaultValue: Boolean = true + override val defaultValue: Boolean ) : Feature { LocationSharing( key = "feature.locationsharing", title = "Allow user to share location", + defaultValue = true, ), Polls( key = "feature.polls", title = "Polls", description = "Create poll and render poll events in the timeline", - defaultValue = false, + defaultValue = true, ), NotificationSettings( key = "feature.notificationsettings", diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt index 2d66d3be21..50a1ac4dd5 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt @@ -22,7 +22,7 @@ import javax.inject.Inject /** * This provider is used for release build. - * Change the value return by [isFeatureEnabled] to enable/disable features. + * [isFeatureEnabled] just returns the default value of the FeatureFlags. */ class StaticFeatureFlagProvider @Inject constructor() : FeatureFlagProvider { @@ -31,11 +31,7 @@ class StaticFeatureFlagProvider @Inject constructor() : override suspend fun isFeatureEnabled(feature: Feature): Boolean { return if (feature is FeatureFlags) { - when (feature) { - FeatureFlags.LocationSharing -> true - FeatureFlags.Polls -> false - FeatureFlags.NotificationSettings -> false - } + feature.defaultValue } else { false } From 762a03259b9d24f65e7cff8eadad98532691776e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 12:32:21 +0200 Subject: [PATCH 072/127] Make a diff between `FeatureFlags.defaultValue` and value returned by `StaticFeatureFlagProvider.isFeatureEnabled()`. Iterate after Ganfra's review. --- .../android/libraries/featureflag/api/FeatureFlags.kt | 4 +++- .../featureflag/impl/StaticFeatureFlagProvider.kt | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 36113389a4..fc13a8a1cc 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -18,7 +18,8 @@ package io.element.android.libraries.featureflag.api /** * To enable or disable a FeatureFlags, change the `defaultValue` value. - * It will impact all the build types. + * Warning: to enable a flog for the release app, you MUST update the file + * [io.element.android.libraries.featureflag.impl.StaticFeatureFlagProvider] */ enum class FeatureFlags( override val key: String, @@ -40,6 +41,7 @@ enum class FeatureFlags( NotificationSettings( key = "feature.notificationsettings", title = "Show notification settings", + // Do not forget to edit StaticFeatureFlagProvider when enabling the feature. defaultValue = false, ), } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt index 50a1ac4dd5..50efdb9fc3 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt @@ -22,7 +22,7 @@ import javax.inject.Inject /** * This provider is used for release build. - * [isFeatureEnabled] just returns the default value of the FeatureFlags. + * This is the place to enable or disable feature for the release build. */ class StaticFeatureFlagProvider @Inject constructor() : FeatureFlagProvider { @@ -31,7 +31,11 @@ class StaticFeatureFlagProvider @Inject constructor() : override suspend fun isFeatureEnabled(feature: Feature): Boolean { return if (feature is FeatureFlags) { - feature.defaultValue + when(feature) { + FeatureFlags.LocationSharing -> true + FeatureFlags.Polls -> true + FeatureFlags.NotificationSettings -> false + } } else { false } From e19b27badf965c46b676f13be7a5cfb5d95c82ca Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Thu, 7 Sep 2023 13:19:13 +0200 Subject: [PATCH 073/127] De-duplicate sonar job in the CI (#1238) * De-duplicate sonar job in the CI * Remove workaround for `src/*/kotlin` folders * Downgrade the sonarqube plugin version * Try increasing workers for this job, since it's quite slow * Warn about regression in latest sonarqube release * Forbid backups to prevent cryptographic issues --- .github/workflows/quality.yml | 6 ------ .github/workflows/sonar.yml | 12 +++--------- app/src/main/AndroidManifest.xml | 2 +- app/src/main/res/xml/backup_rules.xml | 11 ++--------- app/src/main/res/xml/data_extraction_rules.xml | 16 ++++------------ build.gradle.kts | 16 ---------------- gradle/libs.versions.toml | 5 ++++- 7 files changed, 14 insertions(+), 54 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 9c0aac7aef..37648a5403 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -52,12 +52,6 @@ jobs: name: linting-report path: | */build/reports/**/*.* - - name: 🔊 Publish results to Sonar - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} - if: ${{ always() && env.SONAR_TOKEN != '' && env.ORG_GRADLE_PROJECT_SONAR_LOGIN != '' }} - run: ./gradlew sonar $CI_GRADLE_ARG_PROPERTIES - name: Prepare Danger if: always() run: | diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 42846c2cd5..e8efe99d28 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -1,4 +1,4 @@ -name: Code Quality Checks +name: Sonar on: workflow_dispatch: @@ -10,11 +10,11 @@ on: # Enrich gradle.properties for CI/CD env: GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -XX:MaxMetaspaceSize=512m -Dkotlin.daemon.jvm.options="-Xmx2g" -Dkotlin.incremental=false - CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon --warn + CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 4 --no-daemon --warn jobs: sonar: - name: Project Check Suite + name: Sonar Quality Checks runs-on: ubuntu-latest # Allow all jobs on main and develop. Just one per PR. concurrency: @@ -41,9 +41,3 @@ jobs: ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} if: ${{ always() && env.SONAR_TOKEN != '' && env.ORG_GRADLE_PROJECT_SONAR_LOGIN != '' }} run: ./gradlew sonar $CI_GRADLE_ARG_PROPERTIES - - name: Prepare Danger - if: always() - run: | - npm install --save-dev @babel/core - npm install --save-dev @babel/plugin-transform-flow-strip-types - yarn add danger-plugin-lint-report --dev diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ffd0265584..7d1c45b1b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,7 +22,7 @@ - + diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml index a6ecda4638..9b4bbfff1c 100644 --- a/app/src/main/res/xml/data_extraction_rules.xml +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -1,5 +1,5 @@ - + - diff --git a/build.gradle.kts b/build.gradle.kts index 69f5676e72..bd0f84177a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -143,22 +143,6 @@ sonar { } } -allprojects { - val projectDir = projectDir.toString() - sonar { - properties { - // Note: folders `kotlin` are not supported (yet), I asked on their side: https://community.sonarsource.com/t/82824 - // As a workaround provide the path in `sonar.sources` property. - if (File("$projectDir/src/main/kotlin").exists()) { - property("sonar.sources", "src/main/kotlin") - } - if (File("$projectDir/src/test/kotlin").exists()) { - property("sonar.tests", "src/test/kotlin") - } - } - } -} - allprojects { tasks.withType { maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1ce7a09e72..b1e068613d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -203,6 +203,9 @@ dependencygraph = { id = "com.savvasdalkitsis.module-dependency-graph", version. dependencycheck = { id = "org.owasp.dependencycheck", version.ref = "dependencycheck" } dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyanalysis" } paparazzi = "app.cash.paparazzi:1.3.1" -sonarqube = "org.sonarqube:4.3.1.3277" kover = "org.jetbrains.kotlinx.kover:0.6.1" sqldelight = { id = "com.squareup.sqldelight", version.ref = "sqldelight" } + +# Version '4.3.1.3277' introduced some regressions in CI time (more than 2x slower), so make sure +# this is no longer the case before upgrading. +sonarqube = "org.sonarqube:4.2.1.3168" From c44b7eb81c060b0de3a7869f7219b72b7a7a1bb2 Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Thu, 7 Sep 2023 14:05:11 +0100 Subject: [PATCH 074/127] Fix crash in error tracking (#1248) --- changelog.d/1248.bugfix | 1 + .../analyticsproviders/posthog/PosthogAnalyticsProvider.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1248.bugfix diff --git a/changelog.d/1248.bugfix b/changelog.d/1248.bugfix new file mode 100644 index 0000000000..c36862df63 --- /dev/null +++ b/changelog.d/1248.bugfix @@ -0,0 +1 @@ +Fix crash in error tracking \ No newline at end of file diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt index fb2e341e1e..1f21c0beb5 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt @@ -71,7 +71,7 @@ class PosthogAnalyticsProvider @Inject constructor( } override fun trackError(throwable: Throwable) { - TODO("Not yet implemented") + // Not implemented } private fun createPosthog(): PostHog = postHogFactory.createPosthog() From b9896bab8034d7450eb248d30d85bd7f117a0311 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 15:10:10 +0200 Subject: [PATCH 075/127] Use CircleShape by default on FAB, for coherency with other platforms. --- .../designsystem/theme/components/FloatingActionButton.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt index e126a429d8..16af6203ca 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt @@ -19,6 +19,7 @@ package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.FloatingActionButtonDefaults @@ -38,7 +39,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup fun FloatingActionButton( onClick: () -> Unit, modifier: Modifier = Modifier, - shape: Shape = FloatingActionButtonDefaults.shape, + shape: Shape = CircleShape, // FloatingActionButtonDefaults.shape, containerColor: Color = FloatingActionButtonDefaults.containerColor, contentColor: Color = contentColorFor(containerColor), elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(), From 33dd0b202065976229cbd5525f576ad31b682e97 Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Thu, 7 Sep 2023 14:30:55 +0100 Subject: [PATCH 076/127] Remove changelog (#1249) --- changelog.d/1248.bugfix | 1 - 1 file changed, 1 deletion(-) delete mode 100644 changelog.d/1248.bugfix diff --git a/changelog.d/1248.bugfix b/changelog.d/1248.bugfix deleted file mode 100644 index c36862df63..0000000000 --- a/changelog.d/1248.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash in error tracking \ No newline at end of file From 3d6b5976e3d8d245fff5701405c8735d71f8509d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 15:49:51 +0200 Subject: [PATCH 077/127] Iterate on icon in Fab in the room list. --- .../features/roomlist/impl/RoomListView.kt | 3 +-- .../src/main/res/drawable/ic_edit_square.xml | 17 +++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index 176962ca2a..f7eb5aa4eb 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -219,8 +219,7 @@ fun RoomListContent( onClick = onCreateRoomClicked ) { Icon( - // Correct icon alignment for better rendering. - modifier = Modifier.padding(start = 1.dp, bottom = 1.dp), + // Note cannot use Icons.Outlined.EditSquare, it does not exist :/ resourceId = DrawableR.drawable.ic_edit_square, contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message) ) diff --git a/libraries/designsystem/src/main/res/drawable/ic_edit_square.xml b/libraries/designsystem/src/main/res/drawable/ic_edit_square.xml index 73b092ea47..121486a4a2 100644 --- a/libraries/designsystem/src/main/res/drawable/ic_edit_square.xml +++ b/libraries/designsystem/src/main/res/drawable/ic_edit_square.xml @@ -15,12 +15,13 @@ --> - + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + + From d0a36b5e64d9ec74e487e8516c086b6cec3adf4c Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 7 Sep 2023 13:59:56 +0000 Subject: [PATCH 078/127] Update screenshots --- ...end_null_SendLocationView-D-0_1_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-D-0_1_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-D-0_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-D-0_1_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-D-0_1_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-N-0_2_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-N-0_2_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-N-0_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-N-0_2_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...end_null_SendLocationView-N-0_2_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...how_null_ShowLocationViewDark_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...ow_null_ShowLocationViewLight_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ionButtons_FloatingActionButton_0_null,NEXUS_5,1.0,en].png | 4 ++-- 39 files changed, 78 insertions(+), 78 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_0,NEXUS_5,1.0,en].png index 8e5282128a..8d2683d552 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1625b6184c01ab75efcfe4c8d1594af1ffb84f0416219580adce5a9371fabe7d -size 21292 +oid sha256:ad8519086ae725ac7b1aeae9cd628237afeb489c6000c814b4d8e3f644592e58 +size 22278 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_1,NEXUS_5,1.0,en].png index 135577ac2f..173cc88678 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91d1b5d5c58a4f2cbf048ad20b3a9742c209ea19703eafaf6d3e6f542caf2111 -size 40640 +oid sha256:f4cc5cd0ba741aa217ee000749ec4041186c2c83d13f6c87023d16f16689a9ed +size 41359 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_2,NEXUS_5,1.0,en].png index 8f41e9cece..153b681988 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe37eb6328241c70b4219c9fde9118593b1354fe99628e106af828868f9cc4c6 -size 39178 +oid sha256:1ff04ca56c00e2bbf4858bcf6f8faed596e2c538937ec26d61abac7922cda2e1 +size 39890 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_3,NEXUS_5,1.0,en].png index 8e5282128a..8d2683d552 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1625b6184c01ab75efcfe4c8d1594af1ffb84f0416219580adce5a9371fabe7d -size 21292 +oid sha256:ad8519086ae725ac7b1aeae9cd628237afeb489c6000c814b4d8e3f644592e58 +size 22278 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_4,NEXUS_5,1.0,en].png index 6c7b3227a0..95dff5613b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-D-0_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c94b320a8a6e1bbf2824eaa66d80476a293405b6bd0e7c2c96ce3b016be8f291 -size 21430 +oid sha256:b461bb08151c6efb41b0c4d7a40c33b3710dc5a1d0a32cb707ba90f0ef1ee2d1 +size 22419 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_0,NEXUS_5,1.0,en].png index 34ad716b56..ba420c0094 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eba27416d7da08fbd8c47a172f3b54a603c893e1d07faff443417e4949fbc985 -size 19849 +oid sha256:0a59281bb44aea2e220f48f1229afd6b4d2d0551dc0a7dd6e19b7a6ff3984f09 +size 20742 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_1,NEXUS_5,1.0,en].png index 685b83696c..ed4299da45 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40184d796909922b4316ee027e4500fa183d275bc73d7f69e51801e3f956333b -size 37569 +oid sha256:ac124e959b3c2303ecabe6eeba7c4faf7de55929757c0b69ceb4c0021cc1a390 +size 38197 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_2,NEXUS_5,1.0,en].png index 7d313adf76..29f176bdf8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5647bd3d7605f49358a4e1a76bf5fa86ab9a3ad32d180a134ea5e5271d8d8093 -size 36026 +oid sha256:7e064103aa27ef0b2765962bb5d21f24387ac215d27691570991a75dd85f8725 +size 36633 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_3,NEXUS_5,1.0,en].png index 34ad716b56..ba420c0094 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eba27416d7da08fbd8c47a172f3b54a603c893e1d07faff443417e4949fbc985 -size 19849 +oid sha256:0a59281bb44aea2e220f48f1229afd6b4d2d0551dc0a7dd6e19b7a6ff3984f09 +size 20742 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_4,NEXUS_5,1.0,en].png index b418af4d4e..4a37a3011c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.send_null_SendLocationView-N-0_2_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:434170541079e63b9c606e592407168f8e7e1e695f5f3e188428570ec364e2c6 -size 20047 +oid sha256:5b7db80ee7f9c4a4d74b0665803c1cf85a391b6af0643f7cc823de5e8897ba6e +size 20904 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_0,NEXUS_5,1.0,en].png index fe9329c1ed..f2ece2ce45 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d502b465f6f70ead5b9bc373b443d548053bc1d0867b4cbfb52d84e59fa253f1 -size 11596 +oid sha256:905d574bc64f14e309072a508732281c87dd00f8fa756bbd20b6d59c9b50eee6 +size 12428 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_1,NEXUS_5,1.0,en].png index 5d205c3650..cc035b2513 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81c29f9bb336e74a97189d8361490a3a29c4f4678d80f62c2e384396cb90a871 -size 32465 +oid sha256:1cb7669bfe98a30d0658c4444f08c11de6b8589a8a81163cb9a83366343c3aea +size 33113 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_2,NEXUS_5,1.0,en].png index 24894be572..b5ee476b1e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:daf1ab743402e503ff6a5d0ec5f7a599b531c23fcbd9767570527828530bf5b3 -size 30817 +oid sha256:520a4053273d7d72a7339fdc609355ffbca183cbf151a24c701b9674e806306d +size 31453 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_3,NEXUS_5,1.0,en].png index fe9329c1ed..f2ece2ce45 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d502b465f6f70ead5b9bc373b443d548053bc1d0867b4cbfb52d84e59fa253f1 -size 11596 +oid sha256:905d574bc64f14e309072a508732281c87dd00f8fa756bbd20b6d59c9b50eee6 +size 12428 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_4,NEXUS_5,1.0,en].png index cdb697c87c..535f1e9742 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:03769782960e9fc1abf6c609a318ca90debb03484d7b8d61d0703ef1374a0b55 -size 11786 +oid sha256:71e4415423627091abedfccd7a03e20afa27fc9f599de70dd82be1571c4131a0 +size 12616 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_5,NEXUS_5,1.0,en].png index 2cad2a5615..7d9397fdf7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c113e7eb9d495ab2fa3d03a945fd6fac35810af2df4571703a8a3f2b55a079 -size 15018 +oid sha256:ca76be1bf0a76e93614c5bca704269932d690f6133f53d09275e2f08d3d27200 +size 15843 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_6,NEXUS_5,1.0,en].png index 36cf496a43..a30c830e66 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92da6c43ebe2da8ad035e0f03ddd5261491e846212396240aee8287d4f4d9a10 -size 22631 +oid sha256:4d0e5e459ed40f12fa3d2897a53928bc6808903bc8a36938e7954be41eab80b2 +size 23415 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_7,NEXUS_5,1.0,en].png index aa84f464a9..7186047697 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewDark_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c23fded123579979a9b6acf41def9a864ff99de6adbf224014c6d77a552fb2fe -size 24754 +oid sha256:adb557b5ccc00a8bbb5b605e372c892f6c0b7d194ed3e6e352f05b975e2e0eab +size 25525 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_0,NEXUS_5,1.0,en].png index a4889e3b27..2c284aec09 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6519ea26cb85aa1cecdab38d9f3cd54f3e986d33a9d411c576714fb070835d6f -size 12503 +oid sha256:c581e4cf30caec4e5039f11091417780ab0decf779ec7b31112a94fec0a596e1 +size 13524 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_1,NEXUS_5,1.0,en].png index 1cae9d483f..09e3c2f716 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cdb9c379d685e7664c76f4ae7c712665de8dc8ad1f65441121dde4475a92f57 -size 35269 +oid sha256:e82b0029ac4e23aacfde992e36267eec369108d6ef9021138510d4b421017bd3 +size 36033 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_2,NEXUS_5,1.0,en].png index b0da61c4b7..b346f9e4a7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c5285cb82229e84a7cf2c1f2ce375060ec4f99577c88a9840b6db3b8d0966cb -size 33736 +oid sha256:9229d55e1a109abacfa82f066a48fa60606a0d0ed0d155634b4c31fb2c7be98c +size 34501 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_3,NEXUS_5,1.0,en].png index a4889e3b27..2c284aec09 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6519ea26cb85aa1cecdab38d9f3cd54f3e986d33a9d411c576714fb070835d6f -size 12503 +oid sha256:c581e4cf30caec4e5039f11091417780ab0decf779ec7b31112a94fec0a596e1 +size 13524 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_4,NEXUS_5,1.0,en].png index cb89527934..60d4ccb3c9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d33eeef612e03599f835991ad70c5f128c51e0ac49e67fff445b2e98ed3b71ef -size 12706 +oid sha256:9703d279e6401268fd066984d4cc91403c7f8f8e2c248c6ba2ea4c242694170f +size 13729 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_5,NEXUS_5,1.0,en].png index aafeea9a40..ca5503a3e0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b47af4d036f0cf1275773fb8b81d3cae847626b49f5197e2249df1d9d9be2cbb -size 16501 +oid sha256:11a6fd8151812c8733bab26904f53754899db2caeaa0f4f24ea010dd2d54b538 +size 17522 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_6,NEXUS_5,1.0,en].png index c1de14e11e..81bf0e3914 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1aca2f20b99dbbdbd70ca437c06949b634d10c30701f7634cfebaf78593c34d8 -size 25515 +oid sha256:0083578f572e51de0a0464caf90ec68e8a82930b97e0217d20a550ce269f7519 +size 26504 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_7,NEXUS_5,1.0,en].png index 0833282d1f..050b78e680 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.location.impl.show_null_ShowLocationViewLight_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f612c17dedc33b8c4089828673dd58d6f1b51faa0c6df3edb1a0f3398c4c55e2 -size 27885 +oid sha256:1a5e11eed79ab3f92c130c3055e70e5cf0df2b22200e8e73e2180c0114ff5b04 +size 28881 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png index 40e658fe68..50d588999b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e045c8686effc435e5d31b7ef034d93bca64a226d2e6ebae941afeb36dbad099 -size 35534 +oid sha256:4482b15d928567822dc984a1f19c698f6a9d981d907b70635b3054795292306a +size 36543 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png index 8a8da5a453..9ffc58dd11 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a62f8d9a50f7d23bc355dfe98be0bc5eeb2b68866e3035b79b51591eae2f781f -size 58626 +oid sha256:8b22df92cc4ec3e9622f23f6fb7e800e17afbe3a12f9f3d4121b1981ac0350f8 +size 59635 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png index 40e658fe68..50d588999b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e045c8686effc435e5d31b7ef034d93bca64a226d2e6ebae941afeb36dbad099 -size 35534 +oid sha256:4482b15d928567822dc984a1f19c698f6a9d981d907b70635b3054795292306a +size 36543 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png index 28ec864478..58940cb17b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76b43763ca93e7bf31e49aa4ba98e9c9cb6d5ee2ab6dba573e69315084884859 -size 37433 +oid sha256:c78072a5ab2e95aaf7abb085db0d66761eb987b22c0e1dcd6da901f3fbe2a3d7 +size 38438 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png index a26740c566..98f9563247 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0451e8d5939e9c90ccef22a8384d80e7d83cf8faa8a7df4bcd6032d9f3ef394c -size 36884 +oid sha256:2cbf0a4e9ca5d3471d361890737d5aa9636abe3143f5de9218e0568951d59bf5 +size 37887 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png index e7cb3b98e5..3db493ae46 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9220e4a8dca8924d574e9a5511f25f6c41d14163b58cb4d8f622d7fd8fc71ae -size 37238 +oid sha256:12cac3731fd61b4cbfec09b0f439b2744a5374b6d9ee2b79880507af2224b969 +size 38241 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png index 7f84966744..7b757a00fd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d24c1170affdcae6f189ba2e6646fb61e01f8eed4d83340297f3f189c2f3470 -size 38225 +oid sha256:b03c0240edcc58f64bd1dc7e9ef619081f4019c5825c6e4133f3aab4b7cf9b7a +size 39711 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png index 6a5f613b72..b624add247 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cca9ca327d8a64cb04489cd52c52d3871bd583de9835eb266a1e60db8e53f84 -size 62191 +oid sha256:f2ca4bee47e6beaf4b79c0417dbfe132f6e92974c33484bb0440929a35ada794 +size 63618 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png index 7f84966744..7b757a00fd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d24c1170affdcae6f189ba2e6646fb61e01f8eed4d83340297f3f189c2f3470 -size 38225 +oid sha256:b03c0240edcc58f64bd1dc7e9ef619081f4019c5825c6e4133f3aab4b7cf9b7a +size 39711 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png index 7ea53599fb..d046533d4d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fcfec887ae55ce77b049ef49880f1858e7a0a0ea2a7c81140c8c66069a598a14 -size 40265 +oid sha256:19e78d44954b0cde8ea83873f40e6b0a5cf53a02b4bd523e8b8710a483471e32 +size 41698 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png index dfc6c1155f..479929ff78 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5716646f8c5d8e9488f79b033ffce5f337133eb78a63328ec616b8eb35d1c70b -size 39534 +oid sha256:6ff479b11d48f3bdf5adc02d466b6427cbf778b2d2184d6e88d7abe8c12043c5 +size 40960 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png index d947e91005..7d8cdf7415 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a8723f12c2884d20c195a779cf6d48a08191f1caa0acdaa2324e478ecac92b2 -size 39898 +oid sha256:1f9e4cc9f63f4414fbe1f82e82b9eca7b5071e26aa057b1137daa75cecccf150 +size 41329 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_FloatingActionButtons_FloatingActionButton_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_FloatingActionButtons_FloatingActionButton_0_null,NEXUS_5,1.0,en].png index 9d9156d829..a09bf2aa83 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_FloatingActionButtons_FloatingActionButton_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_FloatingActionButtons_FloatingActionButton_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5931cf1a6098e1b3011d81e544b65b6612a603ec3f5fc46de55b73a115ed5f8 -size 9692 +oid sha256:63f00a1f3ec151b25e481f9ac389944d457e08b2c5ed21912dbcdbb2b47a579d +size 11510 From 1dbecaac7975d88b9a8215c9bd25948bfcb71e19 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 17:02:45 +0200 Subject: [PATCH 079/127] Fix typo --- .../element/android/libraries/featureflag/api/FeatureFlags.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index fc13a8a1cc..c7744f486d 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -18,7 +18,7 @@ package io.element.android.libraries.featureflag.api /** * To enable or disable a FeatureFlags, change the `defaultValue` value. - * Warning: to enable a flog for the release app, you MUST update the file + * Warning: to enable a flag for the release app, you MUST update the file * [io.element.android.libraries.featureflag.impl.StaticFeatureFlagProvider] */ enum class FeatureFlags( From 6f86fca2c2256630cdade2197572b339cca34112 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 7 Sep 2023 17:03:52 +0200 Subject: [PATCH 080/127] Sync: use the new SyncIndicator api --- .../appnav/loggedin/LoggedInPresenter.kt | 20 +++++-------------- .../matrix/api/roomlist/RoomListService.kt | 10 ++++++++++ .../impl/roomlist/RoomListExtensions.kt | 14 +++++++++++++ .../impl/roomlist/RustRoomListService.kt | 17 ++++++++++++++++ .../test/roomlist/FakeRoomListService.kt | 3 +++ 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt index f2af582c25..49253edc99 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt @@ -19,17 +19,15 @@ package io.element.android.appnav.loggedin import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.push.api.PushService -import kotlinx.coroutines.delay import javax.inject.Inject private const val DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS = 1500L @@ -50,19 +48,11 @@ class LoggedInPresenter @Inject constructor( pushService.registerWith(matrixClient, pushProvider, distributor) } - val roomListState by matrixClient.roomListService.state.collectAsState() + val syncIndicator by matrixClient.roomListService.syncIndicator.collectAsState() val networkStatus by networkMonitor.connectivity.collectAsState() - var showSyncSpinner by remember { - mutableStateOf(false) - } - LaunchedEffect(roomListState, networkStatus) { - showSyncSpinner = when { - networkStatus == NetworkStatus.Offline -> false - roomListState == RoomListService.State.Running -> false - else -> { - delay(DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS) - true - } + val showSyncSpinner by remember { + derivedStateOf { + networkStatus == NetworkStatus.Online && syncIndicator == RoomListService.SyncIndicator.Show } } return LoggedInState( diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt index 9ae6c22e7d..de7f1f3918 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt @@ -32,6 +32,11 @@ interface RoomListService { data object Terminated : State() } + sealed class SyncIndicator { + data object Show : SyncIndicator() + data object Hide : SyncIndicator() + } + /** * returns a [RoomList] object of all rooms we want to display. * This will exclude some rooms like the invites, or spaces. @@ -49,6 +54,11 @@ interface RoomListService { */ fun updateAllRoomsVisibleRange(range: IntRange) + /** + * The sync indicator as a flow. + */ + val syncIndicator: StateFlow + /** * The state of the service as a flow. */ diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index 8d96990a9e..ea932be896 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -33,6 +33,8 @@ import org.matrix.rustcomponents.sdk.RoomListLoadingStateListener import org.matrix.rustcomponents.sdk.RoomListService import org.matrix.rustcomponents.sdk.RoomListServiceState import org.matrix.rustcomponents.sdk.RoomListServiceStateListener +import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator +import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicatorListener import timber.log.Timber fun RoomList.loadingStateFlow(): Flow = @@ -83,6 +85,18 @@ fun RoomListService.stateFlow(): Flow = } }.buffer(Channel.UNLIMITED) +fun RoomListService.syncIndicator(): Flow = + mxCallbackFlow { + val listener = object : RoomListServiceSyncIndicatorListener { + override fun onUpdate(indicator: RoomListServiceSyncIndicator) { + trySendBlocking(indicator) + } + } + tryOrNull { + syncIndicator(listener) + } + }.buffer(Channel.UNLIMITED) + fun RoomListService.roomOrNull(roomId: String): RoomListItem? { return try { room(roomId) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt index 655c634502..0a828affd4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt @@ -38,6 +38,7 @@ import org.matrix.rustcomponents.sdk.RoomListInput import org.matrix.rustcomponents.sdk.RoomListLoadingState import org.matrix.rustcomponents.sdk.RoomListRange import org.matrix.rustcomponents.sdk.RoomListServiceState +import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator import timber.log.Timber import org.matrix.rustcomponents.sdk.RoomListService as InnerRustRoomListService @@ -106,6 +107,15 @@ class RustRoomListService( } } + override val syncIndicator: StateFlow = + innerRoomListService.syncIndicator() + .map { it.toSyncIndicator() } + .onEach { syncIndicator -> + Timber.d("SyncIndicator = $syncIndicator") + } + .distinctUntilChanged() + .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, RoomListService.SyncIndicator.Hide) + override val state: StateFlow = innerRoomListService.stateFlow() .map { it.toRoomListState() } @@ -134,6 +144,13 @@ private fun RoomListServiceState.toRoomListState(): RoomListService.State { } } +private fun RoomListServiceSyncIndicator.toSyncIndicator(): RoomListService.SyncIndicator { + return when (this) { + RoomListServiceSyncIndicator.SHOW -> RoomListService.SyncIndicator.Show + RoomListServiceSyncIndicator.HIDE -> RoomListService.SyncIndicator.Hide + } +} + private fun org.matrix.rustcomponents.sdk.RoomList.observeEntriesWithProcessor(processor: RoomSummaryListProcessor): Flow> { return entriesFlow { roomListEntries -> processor.postEntries(roomListEntries) 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 fa2e347e3b..7e0f3e8891 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 @@ -29,6 +29,7 @@ class FakeRoomListService : RoomListService { private val allRoomsLoadingStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) private val inviteRoomsLoadingStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) private val roomListStateFlow = MutableStateFlow(RoomListService.State.Idle) + private val syncIndicatorStateFlow = MutableStateFlow(RoomListService.SyncIndicator.Hide) suspend fun postAllRooms(roomSummaries: List) { allRoomSummariesFlow.emit(roomSummaries) @@ -72,4 +73,6 @@ class FakeRoomListService : RoomListService { } override val state: StateFlow = roomListStateFlow + + override val syncIndicator: StateFlow = syncIndicatorStateFlow } From f214493c9da729145a60767124ac3ca7360eadef Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Thu, 7 Sep 2023 16:21:29 +0100 Subject: [PATCH 081/127] [Rich text editor] Integrate rich text editor library (#1172) * Integrate rich text editor * Also increase swapfile size in test CI Fixes issue where screenshot tests are terminated due to lack of CI resources. See https://github.com/actions/runner-images/discussions/7188#discussioncomment-6750749 --------- Co-authored-by: ElementBot --- .github/workflows/tests.yml | 10 + changelog.d/1172.feature | 2 + features/messages/api/build.gradle.kts | 2 +- features/messages/impl/build.gradle.kts | 3 +- .../messages/impl/MessagesPresenter.kt | 6 +- .../messages/impl/MessagesStateProvider.kt | 5 +- .../impl/actionlist/ActionListPresenter.kt | 2 +- .../messagecomposer/MessageComposerEvents.kt | 6 +- .../MessageComposerPresenter.kt | 43 ++-- .../messagecomposer/MessageComposerState.kt | 9 +- .../MessageComposerStateProvider.kt | 8 +- .../messagecomposer/MessageComposerView.kt | 19 +- .../RichTextEditorStateFactory.kt | 38 ++++ .../impl/timeline/TimelinePresenter.kt | 5 +- .../customreaction/CustomReactionPresenter.kt | 2 +- .../ReactionSummaryPresenter.kt | 2 +- .../retrysendmenu/RetrySendMenuPresenter.kt | 2 +- .../event/TimelineItemTextBasedContent.kt | 2 + .../messages/MessagesPresenterTest.kt | 11 +- .../MessageComposerPresenterTest.kt | 124 ++++++----- .../TestRichTextEditorStateFactory.kt | 29 +++ gradle/libs.versions.toml | 3 + .../libraries/matrix/api/room/MatrixRoom.kt | 6 +- .../matrix/impl/room/RustMatrixRoom.kt | 31 +-- .../matrix/test/room/FakeMatrixRoom.kt | 14 +- .../impl/DefaultPermissionsPresenter.kt | 2 +- .../textcomposer/{ => impl}/build.gradle.kts | 6 +- .../android/libraries/textcomposer/Message.kt | 22 ++ .../textcomposer/MessageComposerMode.kt | 0 .../libraries/textcomposer/TextComposer.kt | 210 ++++++++---------- .../main/res/drawable/ic_add_attachment.xml | 0 .../src/main/res/drawable/ic_send.xml | 0 .../src/main/res/drawable/ic_tick.xml | 0 .../src/main/res/values-cs/translations.xml | 0 .../src/main/res/values-de/translations.xml | 0 .../src/main/res/values-ro/translations.xml | 0 .../src/main/res/values-ru/translations.xml | 0 .../src/main/res/values-sk/translations.xml | 0 .../main/res/values-zh-rTW/translations.xml | 0 .../src/main/res/values/localazy.xml | 0 libraries/textcomposer/test/build.gradle.kts | 28 +++ .../kotlin/extension/DependencyHandleScope.kt | 2 +- .../analytics/test/FakeAnalyticsService.kt | 2 + ...poserViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...oserViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...omposerEdit-D-1_2_null,NEXUS_5,1.0,en].png | 4 +- ...omposerEdit-N-1_3_null,NEXUS_5,1.0,en].png | 4 +- ...mposerReply-D-2_3_null,NEXUS_5,1.0,en].png | 4 +- ...mposerReply-N-2_4_null,NEXUS_5,1.0,en].png | 4 +- ...poserSimple-D-0_1_null,NEXUS_5,1.0,en].png | 4 +- ...poserSimple-N-0_2_null,NEXUS_5,1.0,en].png | 4 +- tools/localazy/config.json | 2 +- 62 files changed, 441 insertions(+), 289 deletions(-) create mode 100644 changelog.d/1172.feature create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/RichTextEditorStateFactory.kt create mode 100644 features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/TestRichTextEditorStateFactory.kt rename libraries/textcomposer/{ => impl}/build.gradle.kts (89%) create mode 100644 libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/Message.kt rename libraries/textcomposer/{ => impl}/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt (100%) rename libraries/textcomposer/{ => impl}/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt (74%) rename libraries/textcomposer/{ => impl}/src/main/res/drawable/ic_add_attachment.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/drawable/ic_send.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/drawable/ic_tick.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-cs/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-de/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-ro/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-ru/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-sk/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values-zh-rTW/translations.xml (100%) rename libraries/textcomposer/{ => impl}/src/main/res/values/localazy.xml (100%) create mode 100644 libraries/textcomposer/test/build.gradle.kts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 460e57b4e3..f662e5352d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,6 +22,16 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }} cancel-in-progress: true steps: + # Increase swapfile size to prevent screenshot tests getting terminated + # https://github.com/actions/runner-images/discussions/7188#discussioncomment-6750749 + - name: 💽 Increase swapfile size + run: | + sudo swapoff -a + sudo fallocate -l 8G /mnt/swapfile + sudo chmod 600 /mnt/swapfile + sudo mkswap /mnt/swapfile + sudo swapon /mnt/swapfile + sudo swapon --show - name: ⏬ Checkout with LFS uses: nschloe/action-cached-lfs-checkout@v1.2.2 with: diff --git a/changelog.d/1172.feature b/changelog.d/1172.feature new file mode 100644 index 0000000000..ea03101f0c --- /dev/null +++ b/changelog.d/1172.feature @@ -0,0 +1,2 @@ +[Rich text editor] Integrate rich text editor library. Note that markdown is now not supported and further formatting support will be introduced through the rich text editor. + diff --git a/features/messages/api/build.gradle.kts b/features/messages/api/build.gradle.kts index 756014e97d..9e890265ec 100644 --- a/features/messages/api/build.gradle.kts +++ b/features/messages/api/build.gradle.kts @@ -25,5 +25,5 @@ android { dependencies { implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) - api(projects.libraries.textcomposer) + api(projects.libraries.textcomposer.impl) } diff --git a/features/messages/impl/build.gradle.kts b/features/messages/impl/build.gradle.kts index 1a61a2d8b6..00d65eba6a 100644 --- a/features/messages/impl/build.gradle.kts +++ b/features/messages/impl/build.gradle.kts @@ -41,7 +41,7 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrixui) implementation(projects.libraries.designsystem) - implementation(projects.libraries.textcomposer) + implementation(projects.libraries.textcomposer.impl) implementation(projects.libraries.uiStrings) implementation(projects.libraries.dateformatter.api) implementation(projects.libraries.eventformatter.api) @@ -76,6 +76,7 @@ dependencies { testImplementation(projects.libraries.featureflag.test) testImplementation(projects.libraries.mediaupload.test) testImplementation(projects.libraries.mediapickers.test) + testImplementation(projects.libraries.textcomposer.test) testImplementation(libs.test.mockk) ksp(libs.showkase.processor) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index dc6f3304b1..b0ff403984 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -175,7 +175,7 @@ class MessagesPresenter @AssistedInject constructor( snackbarMessage = snackbarMessage, showReinvitePrompt = showReinvitePrompt, inviteProgress = inviteProgress.value, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } @@ -250,7 +250,9 @@ class MessagesPresenter @AssistedInject constructor( private fun handleActionEdit(targetEvent: TimelineItem.Event, composerState: MessageComposerState) { val composerMode = MessageComposerMode.Edit( targetEvent.eventId, - (targetEvent.content as? TimelineItemTextBasedContent)?.body.orEmpty(), + (targetEvent.content as? TimelineItemTextBasedContent)?.let { + it.htmlBody ?: it.body + }.orEmpty(), targetEvent.transactionId, ) composerState.eventSink( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 7eb1a0984e..6ca799dc84 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.textcomposer.MessageComposerMode +import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.collections.immutable.persistentSetOf open class MessagesStateProvider : PreviewParameterProvider { @@ -54,7 +55,9 @@ fun aMessagesState() = MessagesState( userHasPermissionToSendMessage = true, userHasPermissionToRedact = false, composerState = aMessageComposerState().copy( - text = "Hello", + richTextEditorState = RichTextEditorState("Hello", fake = true).apply { + requestFocus() + }, isFullScreen = false, mode = MessageComposerMode.Normal("Hello"), ), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index f5e28818c9..d0fa46175a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -70,7 +70,7 @@ class ActionListPresenter @Inject constructor( return ActionListState( target = target.value, displayEmojiReactions = displayEmojiReactions, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt index d99eb3c158..4bfd290a77 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt @@ -17,16 +17,15 @@ package io.element.android.features.messages.impl.messagecomposer import androidx.compose.runtime.Immutable +import io.element.android.libraries.textcomposer.Message import io.element.android.libraries.textcomposer.MessageComposerMode @Immutable sealed interface MessageComposerEvents { data object ToggleFullScreenState : MessageComposerEvents - data class FocusChanged(val hasFocus: Boolean) : MessageComposerEvents - data class SendMessage(val message: String) : MessageComposerEvents + data class SendMessage(val message: Message) : MessageComposerEvents data object CloseSpecialMode : MessageComposerEvents data class SetMode(val composerMode: MessageComposerMode) : MessageComposerEvents - data class UpdateText(val text: String) : MessageComposerEvents data object AddAttachment : MessageComposerEvents data object DismissAttachmentMenu : MessageComposerEvents sealed interface PickAttachmentSource : MessageComposerEvents { @@ -38,4 +37,5 @@ sealed interface MessageComposerEvents { data object Poll : PickAttachmentSource } data object CancelSendAttachment : MessageComposerEvents + data class Error(val error: Throwable) : MessageComposerEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index cc735dc008..687e951933 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -44,8 +44,10 @@ import io.element.android.libraries.matrix.api.core.ProgressCallback import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaSender +import io.element.android.libraries.textcomposer.Message import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope @@ -67,6 +69,7 @@ class MessageComposerPresenter @Inject constructor( private val snackbarDispatcher: SnackbarDispatcher, private val analyticsService: AnalyticsService, private val messageComposerContext: MessageComposerContextImpl, + private val richTextEditorStateFactory: RichTextEditorStateFactory, ) : Presenter { @SuppressLint("UnsafeOptInUsageError") @@ -103,19 +106,15 @@ class MessageComposerPresenter @Inject constructor( val isFullScreen = rememberSaveable { mutableStateOf(false) } - val hasFocus = remember { - mutableStateOf(false) - } - val text: MutableState = rememberSaveable { - mutableStateOf("") - } + val richTextEditorState = richTextEditorStateFactory.create() val ongoingSendAttachmentJob = remember { mutableStateOf(null) } var showAttachmentSourcePicker: Boolean by remember { mutableStateOf(false) } LaunchedEffect(messageComposerContext.composerMode) { when (val modeValue = messageComposerContext.composerMode) { - is MessageComposerMode.Edit -> text.value = modeValue.defaultContent + is MessageComposerMode.Edit -> + richTextEditorState.setHtml(modeValue.defaultContent) else -> Unit } } @@ -136,18 +135,15 @@ class MessageComposerPresenter @Inject constructor( when (event) { MessageComposerEvents.ToggleFullScreenState -> isFullScreen.value = !isFullScreen.value - is MessageComposerEvents.FocusChanged -> hasFocus.value = event.hasFocus - - is MessageComposerEvents.UpdateText -> text.value = event.text MessageComposerEvents.CloseSpecialMode -> { - text.value = "" + richTextEditorState.setHtml("") messageComposerContext.composerMode = MessageComposerMode.Normal("") } is MessageComposerEvents.SendMessage -> appCoroutineScope.sendMessage( - text = event.message, + message = event.message, updateComposerMode = { messageComposerContext.composerMode = it }, - textState = text + richTextEditorState = richTextEditorState, ) is MessageComposerEvents.SetMode -> { messageComposerContext.composerMode = event.composerMode @@ -194,43 +190,46 @@ class MessageComposerPresenter @Inject constructor( ongoingSendAttachmentJob.value == null } } + is MessageComposerEvents.Error -> { + analyticsService.trackError(event.error) + } } } return MessageComposerState( - text = text.value, + richTextEditorState = richTextEditorState, isFullScreen = isFullScreen.value, - hasFocus = hasFocus.value, mode = messageComposerContext.composerMode, showAttachmentSourcePicker = showAttachmentSourcePicker, canShareLocation = canShareLocation.value, canCreatePoll = canCreatePoll.value, attachmentsState = attachmentsState.value, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } private fun CoroutineScope.sendMessage( - text: String, + message: Message, updateComposerMode: (newComposerMode: MessageComposerMode) -> Unit, - textState: MutableState + richTextEditorState: RichTextEditorState, ) = launch { val capturedMode = messageComposerContext.composerMode // Reset composer right away - textState.value = "" + richTextEditorState.setHtml("") updateComposerMode(MessageComposerMode.Normal("")) when (capturedMode) { - is MessageComposerMode.Normal -> room.sendMessage(text) + is MessageComposerMode.Normal -> room.sendMessage(body = message.markdown, htmlBody = message.html) is MessageComposerMode.Edit -> { val eventId = capturedMode.eventId val transactionId = capturedMode.transactionId - room.editMessage(eventId, transactionId, text) + room.editMessage(eventId, transactionId, message.markdown, message.html) } is MessageComposerMode.Quote -> TODO() is MessageComposerMode.Reply -> room.replyMessage( capturedMode.eventId, - text + message.markdown, + message.html, ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index dbbc62ca47..bdff621521 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -19,21 +19,22 @@ package io.element.android.features.messages.impl.messagecomposer import androidx.compose.runtime.Immutable import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.libraries.textcomposer.MessageComposerMode +import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.collections.immutable.ImmutableList @Immutable data class MessageComposerState( - val text: String?, + val richTextEditorState: RichTextEditorState, val isFullScreen: Boolean, - val hasFocus: Boolean, val mode: MessageComposerMode, val showAttachmentSourcePicker: Boolean, val canShareLocation: Boolean, val canCreatePoll: Boolean, val attachmentsState: AttachmentsState, - val eventSink: (MessageComposerEvents) -> Unit + val eventSink: (MessageComposerEvents) -> Unit, ) { - val isSendButtonVisible: Boolean = text.isNullOrEmpty().not() + val canSendMessage: Boolean = richTextEditorState.messageHtml.isNotEmpty() + val hasFocus: Boolean = richTextEditorState.hasFocus } @Immutable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt index 2217b574b4..ab15d8ccd8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt @@ -18,6 +18,7 @@ package io.element.android.features.messages.impl.messagecomposer import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.textcomposer.MessageComposerMode +import io.element.android.wysiwyg.compose.RichTextEditorState open class MessageComposerStateProvider : PreviewParameterProvider { override val values: Sequence @@ -27,18 +28,17 @@ open class MessageComposerStateProvider : PreviewParameterProvider(null) } val timelineItems by timelineItemsFactory.collectItemsAsState() @@ -119,7 +120,7 @@ class TimelinePresenter @Inject constructor( paginationState = paginationState, timelineItems = timelineItems, hasNewItems = hasNewItems.value, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt index b048383b1f..8bbd6cbff7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenter.kt @@ -63,7 +63,7 @@ class CustomReactionPresenter @Inject constructor( return CustomReactionState( target = target.value, selectedEmoji = selectedEmoji, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenter.kt index 456ac5f548..e75e49c1e3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenter.kt @@ -61,7 +61,7 @@ class ReactionSummaryPresenter @Inject constructor( } return ReactionSummaryState( target = targetWithAvatars.value, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt index 237dc5683d..c9ebd9be8c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt @@ -66,7 +66,7 @@ class RetrySendMenuPresenter @Inject constructor( return RetrySendMenuState( selectedEvent = selectedEvent, - eventSink = ::handleEvent, + eventSink = { handleEvent(it) }, ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt index ec6ee16675..10fca53261 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt @@ -22,4 +22,6 @@ sealed interface TimelineItemTextBasedContent : TimelineItemEventContent { val body: String val htmlDocument: Document? val isEdited: Boolean + val htmlBody: String? + get() = htmlDocument?.body()?.html() } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 48a8480915..ed7c4a8064 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -30,7 +30,6 @@ import io.element.android.features.messages.impl.actionlist.ActionListPresenter import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.messagecomposer.MessageComposerContextImpl -import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter import io.element.android.features.messages.impl.timeline.TimelinePresenter import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter @@ -41,6 +40,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent import io.element.android.features.messages.media.FakeLocalMediaFactory +import io.element.android.features.messages.textcomposer.TestRichTextEditorStateFactory import io.element.android.features.messages.timeline.components.customreaction.FakeEmojibaseProvider import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter import io.element.android.features.networkmonitor.test.FakeNetworkMonitor @@ -325,6 +325,7 @@ class MessagesPresenterTest { initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Redact, aMessageEvent())) assertThat(matrixRoom.redactEventEventIdParam).isEqualTo(AN_EVENT_ID) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) + skipItems(1) // back paginating } } @@ -381,7 +382,7 @@ class MessagesPresenterTest { // Initially the composer doesn't have focus, so we don't show the alert assertThat(initialState.showReinvitePrompt).isFalse() // When the input field is focused we show the alert - initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) + initialState.composerState.richTextEditorState.requestFocus() val focusedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) { state -> state.showReinvitePrompt }.last() @@ -405,7 +406,7 @@ class MessagesPresenterTest { skipItems(1) val initialState = awaitItem() assertThat(initialState.showReinvitePrompt).isFalse() - initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) + initialState.composerState.richTextEditorState.requestFocus() val focusedState = awaitItem() assertThat(focusedState.showReinvitePrompt).isFalse() } @@ -421,7 +422,7 @@ class MessagesPresenterTest { skipItems(1) val initialState = awaitItem() assertThat(initialState.showReinvitePrompt).isFalse() - initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) + initialState.composerState.richTextEditorState.requestFocus() val focusedState = awaitItem() assertThat(focusedState.showReinvitePrompt).isFalse() } @@ -605,6 +606,8 @@ class MessagesPresenterTest { snackbarDispatcher = SnackbarDispatcher(), analyticsService = FakeAnalyticsService(), messageComposerContext = MessageComposerContextImpl(), + richTextEditorStateFactory = TestRichTextEditorStateFactory(), + ) val timelinePresenter = TimelinePresenter( timelineItemsFactory = aTimelineItemsFactory(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index d89a0392ad..7284fb3b7e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -53,6 +53,7 @@ import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaSender import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor +import io.element.android.libraries.textcomposer.Message import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule @@ -80,6 +81,7 @@ class MessageComposerPresenterTest { private val snackbarDispatcher = SnackbarDispatcher() private val mockMediaUrl: Uri = mockk("localMediaUri") private val localMediaFactory = FakeLocalMediaFactory(mockMediaUrl) + private val analyticsService = FakeAnalyticsService() @Test fun `present - initial state`() = runTest { @@ -90,12 +92,12 @@ class MessageComposerPresenterTest { skipItems(1) val initialState = awaitItem() assertThat(initialState.isFullScreen).isFalse() - assertThat(initialState.text).isEqualTo("") + assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("") assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal("")) assertThat(initialState.showAttachmentSourcePicker).isFalse() assertThat(initialState.canShareLocation).isTrue() assertThat(initialState.attachmentsState).isEqualTo(AttachmentsState.None) - assertThat(initialState.isSendButtonVisible).isFalse() + assertThat(initialState.canSendMessage).isFalse() } } @@ -124,14 +126,14 @@ class MessageComposerPresenterTest { }.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke(MessageComposerEvents.UpdateText(A_MESSAGE)) + initialState.richTextEditorState.setHtml(A_MESSAGE) val withMessageState = awaitItem() - assertThat(withMessageState.text).isEqualTo(A_MESSAGE) - assertThat(withMessageState.isSendButtonVisible).isTrue() - withMessageState.eventSink.invoke(MessageComposerEvents.UpdateText("")) + assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE) + assertThat(withMessageState.canSendMessage).isTrue() + withMessageState.richTextEditorState.setHtml("") val withEmptyMessageState = awaitItem() - assertThat(withEmptyMessageState.text).isEqualTo("") - assertThat(withEmptyMessageState.isSendButtonVisible).isFalse() + assertThat(withEmptyMessageState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(withEmptyMessageState.canSendMessage).isFalse() } } @@ -148,8 +150,8 @@ class MessageComposerPresenterTest { state = awaitItem() assertThat(state.mode).isEqualTo(mode) state = awaitItem() - assertThat(state.text).isEqualTo(A_MESSAGE) - assertThat(state.isSendButtonVisible).isTrue() + assertThat(state.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE) + assertThat(state.canSendMessage).isTrue() backToNormalMode(state, skipCount = 1) } } @@ -166,8 +168,8 @@ class MessageComposerPresenterTest { state.eventSink.invoke(MessageComposerEvents.SetMode(mode)) state = awaitItem() assertThat(state.mode).isEqualTo(mode) - assertThat(state.text).isEqualTo("") - assertThat(state.isSendButtonVisible).isFalse() + assertThat(state.richTextEditorState.messageHtml).isEqualTo("") + assertThat(state.canSendMessage).isFalse() backToNormalMode(state) } } @@ -184,8 +186,8 @@ class MessageComposerPresenterTest { state.eventSink.invoke(MessageComposerEvents.SetMode(mode)) state = awaitItem() assertThat(state.mode).isEqualTo(mode) - assertThat(state.text).isEqualTo("") - assertThat(state.isSendButtonVisible).isFalse() + assertThat(state.richTextEditorState.messageHtml).isEqualTo("") + assertThat(state.canSendMessage).isFalse() backToNormalMode(state) } } @@ -198,14 +200,14 @@ class MessageComposerPresenterTest { }.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke(MessageComposerEvents.UpdateText(A_MESSAGE)) + initialState.richTextEditorState.setHtml(A_MESSAGE) val withMessageState = awaitItem() - assertThat(withMessageState.text).isEqualTo(A_MESSAGE) - assertThat(withMessageState.isSendButtonVisible).isTrue() - withMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(A_MESSAGE)) + assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE) + assertThat(withMessageState.canSendMessage).isTrue() + withMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(A_MESSAGE.toMessage())) val messageSentState = awaitItem() - assertThat(messageSentState.text).isEqualTo("") - assertThat(messageSentState.isSendButtonVisible).isFalse() + assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(messageSentState.canSendMessage).isFalse() } } @@ -221,23 +223,23 @@ class MessageComposerPresenterTest { }.test { skipItems(1) val initialState = awaitItem() - assertThat(initialState.text).isEqualTo("") + assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("") val mode = anEditMode() initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode)) skipItems(1) val withMessageState = awaitItem() assertThat(withMessageState.mode).isEqualTo(mode) - assertThat(withMessageState.text).isEqualTo(A_MESSAGE) - assertThat(withMessageState.isSendButtonVisible).isTrue() - withMessageState.eventSink.invoke(MessageComposerEvents.UpdateText(ANOTHER_MESSAGE)) + assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE) + assertThat(withMessageState.canSendMessage).isTrue() + withMessageState.richTextEditorState.setHtml(ANOTHER_MESSAGE) val withEditedMessageState = awaitItem() - assertThat(withEditedMessageState.text).isEqualTo(ANOTHER_MESSAGE) - withEditedMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(ANOTHER_MESSAGE)) + assertThat(withEditedMessageState.richTextEditorState.messageHtml).isEqualTo(ANOTHER_MESSAGE) + withEditedMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(ANOTHER_MESSAGE.toMessage())) skipItems(1) val messageSentState = awaitItem() - assertThat(messageSentState.text).isEqualTo("") - assertThat(messageSentState.isSendButtonVisible).isFalse() - assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE) + assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(messageSentState.canSendMessage).isFalse() + assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE to ANOTHER_MESSAGE) } } @@ -253,23 +255,23 @@ class MessageComposerPresenterTest { }.test { skipItems(1) val initialState = awaitItem() - assertThat(initialState.text).isEqualTo("") + assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("") val mode = anEditMode(eventId = null, transactionId = A_TRANSACTION_ID) initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode)) skipItems(1) val withMessageState = awaitItem() assertThat(withMessageState.mode).isEqualTo(mode) - assertThat(withMessageState.text).isEqualTo(A_MESSAGE) - assertThat(withMessageState.isSendButtonVisible).isTrue() - withMessageState.eventSink.invoke(MessageComposerEvents.UpdateText(ANOTHER_MESSAGE)) + assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE) + assertThat(withMessageState.canSendMessage).isTrue() + withMessageState.richTextEditorState.setHtml(ANOTHER_MESSAGE) val withEditedMessageState = awaitItem() - assertThat(withEditedMessageState.text).isEqualTo(ANOTHER_MESSAGE) - withEditedMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(ANOTHER_MESSAGE)) + assertThat(withEditedMessageState.richTextEditorState.messageHtml).isEqualTo(ANOTHER_MESSAGE) + withEditedMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(ANOTHER_MESSAGE.toMessage())) skipItems(1) val messageSentState = awaitItem() - assertThat(messageSentState.text).isEqualTo("") - assertThat(messageSentState.isSendButtonVisible).isFalse() - assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE) + assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(messageSentState.canSendMessage).isFalse() + assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE to ANOTHER_MESSAGE) } } @@ -285,23 +287,23 @@ class MessageComposerPresenterTest { }.test { skipItems(1) val initialState = awaitItem() - assertThat(initialState.text).isEqualTo("") + assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("") val mode = aReplyMode() initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode)) val state = awaitItem() assertThat(state.mode).isEqualTo(mode) - assertThat(state.text).isEqualTo("") - assertThat(state.isSendButtonVisible).isFalse() - initialState.eventSink.invoke(MessageComposerEvents.UpdateText(A_REPLY)) + assertThat(state.richTextEditorState.messageHtml).isEqualTo("") + assertThat(state.canSendMessage).isFalse() + state.richTextEditorState.setHtml(A_REPLY) val withMessageState = awaitItem() - assertThat(withMessageState.text).isEqualTo(A_REPLY) - assertThat(withMessageState.isSendButtonVisible).isTrue() - withMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(A_REPLY)) + assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_REPLY) + assertThat(withMessageState.canSendMessage).isTrue() + withMessageState.eventSink.invoke(MessageComposerEvents.SendMessage(A_REPLY.toMessage())) skipItems(1) val messageSentState = awaitItem() - assertThat(messageSentState.text).isEqualTo("") - assertThat(messageSentState.isSendButtonVisible).isFalse() - assertThat(fakeMatrixRoom.replyMessageParameter).isEqualTo(A_REPLY) + assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(messageSentState.canSendMessage).isFalse() + assertThat(fakeMatrixRoom.replyMessageParameter).isEqualTo(A_REPLY to A_REPLY) } } @@ -523,13 +525,27 @@ class MessageComposerPresenterTest { } } + @Test + fun `present - errors are tracked`() = runTest { + val testException = Exception("Test error") + val presenter = createPresenter(this) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + initialState.eventSink(MessageComposerEvents.Error(testException)) + assertThat(analyticsService.trackedErrors).containsExactly(testException) + } + } + private suspend fun ReceiveTurbine.backToNormalMode(state: MessageComposerState, skipCount: Int = 0) { state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode) skipItems(skipCount) val normalState = awaitItem() assertThat(normalState.mode).isEqualTo(MessageComposerMode.Normal("")) - assertThat(normalState.text).isEqualTo("") - assertThat(normalState.isSendButtonVisible).isFalse() + assertThat(normalState.richTextEditorState.messageHtml).isEqualTo("") + assertThat(normalState.canSendMessage).isFalse() } private fun createPresenter( @@ -547,8 +563,9 @@ class MessageComposerPresenterTest { localMediaFactory, MediaSender(mediaPreProcessor, room), snackbarDispatcher, - FakeAnalyticsService(), + analyticsService, MessageComposerContextImpl(), + TestRichTextEditorStateFactory(), ) } @@ -560,3 +577,8 @@ fun anEditMode( fun aReplyMode() = MessageComposerMode.Reply(A_USER_NAME, null, AN_EVENT_ID, A_MESSAGE) fun aQuoteMode() = MessageComposerMode.Quote(AN_EVENT_ID, A_MESSAGE) + +private fun String.toMessage() = Message( + html = this, + markdown = this, +) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/TestRichTextEditorStateFactory.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/TestRichTextEditorStateFactory.kt new file mode 100644 index 0000000000..762d144cd6 --- /dev/null +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/TestRichTextEditorStateFactory.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 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.features.messages.textcomposer + +import androidx.compose.runtime.Composable +import io.element.android.features.messages.impl.messagecomposer.RichTextEditorStateFactory +import io.element.android.wysiwyg.compose.RichTextEditorState +import io.element.android.wysiwyg.compose.rememberRichTextEditorState + +class TestRichTextEditorStateFactory : RichTextEditorStateFactory { + @Composable + override fun create(): RichTextEditorState { + return rememberRichTextEditorState("", fake = true) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 877dd7955f..ebbc937bfa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,6 +46,7 @@ dependencyanalysis = "1.21.0" stem = "2.3.0" sqldelight = "1.5.5" telephoto = "0.6.0" +wysiwyg = "2.9.0" # DI dagger = "2.48" @@ -147,6 +148,8 @@ appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" } timber = "com.jakewharton.timber:timber:5.0.1" matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.49" +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 = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-jvm = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqldelight" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 60c8b1ddd5..169381f25e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -79,11 +79,11 @@ interface MatrixRoom : Closeable { suspend fun userAvatarUrl(userId: UserId): Result - suspend fun sendMessage(message: String): Result + suspend fun sendMessage(body: String, htmlBody: String): Result - suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, message: String): Result + suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, body: String, htmlBody: String): Result - suspend fun replyMessage(eventId: EventId, message: String): Result + suspend fun replyMessage(eventId: EventId, body: String, htmlBody: String): Result suspend fun redactEvent(eventId: EventId, reason: String? = null): Result 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 461e43931e..9e75d10aad 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 @@ -66,7 +66,7 @@ import org.matrix.rustcomponents.sdk.RoomMember import org.matrix.rustcomponents.sdk.RoomSubscription import org.matrix.rustcomponents.sdk.SendAttachmentJoinHandle import org.matrix.rustcomponents.sdk.genTransactionId -import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown +import org.matrix.rustcomponents.sdk.messageEventContentFromHtml import timber.log.Timber import java.io.File @@ -227,31 +227,32 @@ class RustMatrixRoom( } } - override suspend fun sendMessage(message: String): Result = withContext(roomDispatcher) { + override suspend fun sendMessage(body: String, htmlBody: String): Result = withContext(roomDispatcher) { val transactionId = genTransactionId() - messageEventContentFromMarkdown(message).use { content -> + messageEventContentFromHtml(body, htmlBody).use { content -> runCatching { innerRoom.send(content, transactionId) } } } - override suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, message: String): Result = withContext(roomDispatcher) { - if (originalEventId != null) { - runCatching { - innerRoom.edit(messageEventContentFromMarkdown(message), originalEventId.value, transactionId?.value) - } - } else { - runCatching { - transactionId?.let { cancelSend(it) } - innerRoom.send(messageEventContentFromMarkdown(message), genTransactionId()) + override suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, body: String, htmlBody: String): Result = + withContext(roomDispatcher) { + if (originalEventId != null) { + runCatching { + innerRoom.edit(messageEventContentFromHtml(body, htmlBody), originalEventId.value, transactionId?.value) + } + } else { + runCatching { + transactionId?.let { cancelSend(it) } + innerRoom.send(messageEventContentFromHtml(body, htmlBody), genTransactionId()) + } } } - } - override suspend fun replyMessage(eventId: EventId, message: String): Result = withContext(roomDispatcher) { + override suspend fun replyMessage(eventId: EventId, body: String, htmlBody: String): Result = withContext(roomDispatcher) { runCatching { - innerRoom.sendReply(messageEventContentFromMarkdown(message), eventId.value, genTransactionId()) + innerRoom.sendReply(messageEventContentFromHtml(body, htmlBody), eventId.value, genTransactionId()) } } 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 761e479816..24f0e68d10 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 @@ -92,7 +92,7 @@ class FakeMatrixRoom( private var sendPollResponseResult = Result.success(Unit) private var endPollResult = Result.success(Unit) private var progressCallbackValues = emptyList>() - val editMessageCalls = mutableListOf() + val editMessageCalls = mutableListOf>() var sendMediaCount = 0 private set @@ -171,7 +171,7 @@ class FakeMatrixRoom( userAvatarUrlResult } - override suspend fun sendMessage(message: String): Result = simulateLongTask { + override suspend fun sendMessage(body: String, htmlBody: String) = simulateLongTask { Result.success(Unit) } @@ -200,16 +200,16 @@ class FakeMatrixRoom( return cancelSendResult } - override suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, message: String): Result { - editMessageCalls += message + override suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, body: String, htmlBody: String): Result { + editMessageCalls += body to htmlBody return Result.success(Unit) } - var replyMessageParameter: String? = null + var replyMessageParameter: Pair? = null private set - override suspend fun replyMessage(eventId: EventId, message: String): Result { - replyMessageParameter = message + override suspend fun replyMessage(eventId: EventId, body: String, htmlBody: String): Result { + replyMessageParameter = body to htmlBody return Result.success(Unit) } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt index ddd45f865f..1684833d70 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt @@ -124,7 +124,7 @@ class DefaultPermissionsPresenter @AssistedInject constructor( showDialog = showDialog.value, permissionAlreadyAsked = isAlreadyAsked, permissionAlreadyDenied = isAlreadyDenied, - eventSink = ::handleEvents + eventSink = { handleEvents(it) } ) } diff --git a/libraries/textcomposer/build.gradle.kts b/libraries/textcomposer/impl/build.gradle.kts similarity index 89% rename from libraries/textcomposer/build.gradle.kts rename to libraries/textcomposer/impl/build.gradle.kts index 76d7d00a03..3aaae7ca6e 100644 --- a/libraries/textcomposer/build.gradle.kts +++ b/libraries/textcomposer/impl/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -31,5 +31,9 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrixui) implementation(projects.libraries.designsystem) + + implementation(libs.matrix.richtexteditor) + api(libs.matrix.richtexteditor.compose) + ksp(libs.showkase.processor) } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/Message.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/Message.kt new file mode 100644 index 0000000000..0f3a213427 --- /dev/null +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/Message.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 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.libraries.textcomposer + +data class Message( + val html: String, + val markdown: String, +) diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt similarity index 100% rename from libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt rename to libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt similarity index 74% rename from libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt rename to libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 3c0e0fa723..04fa08c9ce 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -37,38 +37,25 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -88,23 +75,23 @@ import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.wysiwyg.compose.RichTextEditor +import io.element.android.wysiwyg.compose.RichTextEditorDefaults +import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.coroutines.android.awaitFrame -@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class) @Composable fun TextComposer( - composerText: String?, + state: RichTextEditorState, composerMode: MessageComposerMode, - composerCanSendMessage: Boolean, + canSendMessage: Boolean, modifier: Modifier = Modifier, - focusRequester: FocusRequester = FocusRequester(), - onSendMessage: (String) -> Unit = {}, + onRequestFocus: () -> Unit = {}, + onSendMessage: (Message) -> Unit = {}, onResetComposerMode: () -> Unit = {}, - onComposerTextChange: (String) -> Unit = {}, onAddAttachment: () -> Unit = {}, - onFocusChanged: (Boolean) -> Unit = {}, + onError: (Throwable) -> Unit = {}, ) { - val text = composerText.orEmpty() Row( modifier.padding( horizontal = 12.dp, @@ -115,10 +102,9 @@ fun TextComposer( Spacer(modifier = Modifier.width(12.dp)) val roundCornerSmall = 20.dp.applyScaleUp() val roundCornerLarge = 28.dp.applyScaleUp() - var lineCount by remember { mutableIntStateOf(0) } - val roundedCornerSize = remember(lineCount, composerMode) { - if (lineCount > 1 || composerMode is MessageComposerMode.Special) { + val roundedCornerSize = remember(state.lineCount, composerMode) { + if (state.lineCount > 1 || composerMode is MessageComposerMode.Special) { roundCornerSmall } else { roundCornerLarge @@ -132,10 +118,15 @@ fun TextComposer( ) val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value) val minHeight = 42.dp.applyScaleUp() - val bgColor = ElementTheme.colors.bgSubtleSecondary - // Change border color depending on focus - var hasFocus by remember { mutableStateOf(false) } - val borderColor = if (hasFocus) ElementTheme.colors.borderDisabled else bgColor + val colors = ElementTheme.colors + val bgColor = colors.bgSubtleSecondary + + val borderColor by remember(state.hasFocus, colors) { + derivedStateOf { + if (state.hasFocus) colors.borderDisabled else bgColor + } + } + Column( modifier = Modifier .fillMaxWidth() @@ -147,66 +138,56 @@ fun TextComposer( ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode) } val defaultTypography = ElementTheme.typography.fontBodyLgRegular + Box { - BasicTextField( + Box( modifier = Modifier - .fillMaxWidth() .heightIn(min = minHeight) - .focusRequester(focusRequester) - .onFocusEvent { - hasFocus = it.hasFocus - onFocusChanged(it.hasFocus) - }, - value = text, - onValueChange = { onComposerTextChange(it) }, - onTextLayout = { - lineCount = it.lineCount - }, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.Sentences, - ), - textStyle = defaultTypography.copy(color = MaterialTheme.colorScheme.primary), - cursorBrush = SolidColor(ElementTheme.colors.iconAccentTertiary), - decorationBox = { innerTextField -> - TextFieldDefaults.DecorationBox( - value = text, - innerTextField = innerTextField, - enabled = true, - singleLine = false, - visualTransformation = VisualTransformation.None, - shape = roundedCorners, - contentPadding = PaddingValues( - top = 10.dp.applyScaleUp(), - bottom = 10.dp.applyScaleUp(), + .background(color = bgColor, shape = roundedCorners) + .padding( + PaddingValues( + top = 4.dp.applyScaleUp(), + bottom = 4.dp.applyScaleUp(), start = 12.dp.applyScaleUp(), - end = 42.dp.applyScaleUp(), - ), - interactionSource = remember { MutableInteractionSource() }, - placeholder = { - Text(stringResource(CommonStrings.common_message), style = defaultTypography) - }, - colors = TextFieldDefaults.colors( - unfocusedTextColor = MaterialTheme.colorScheme.secondary, - focusedTextColor = MaterialTheme.colorScheme.primary, - unfocusedPlaceholderColor = ElementTheme.colors.textDisabled, - focusedPlaceholderColor = ElementTheme.colors.textDisabled, - unfocusedIndicatorColor = Color.Transparent, - focusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent, - errorIndicatorColor = Color.Transparent, - unfocusedContainerColor = bgColor, - focusedContainerColor = bgColor, - errorContainerColor = bgColor, - disabledContainerColor = bgColor, + end = 42.dp.applyScaleUp() ) + ), + contentAlignment = Alignment.CenterStart, + ) { + + // Placeholder + if (state.messageHtml.isEmpty()) { + Text( + stringResource(CommonStrings.common_message), + style = defaultTypography.copy( + color = ElementTheme.colors.textDisabled, + ), ) } - ) + + RichTextEditor( + state = state, + modifier = Modifier + .fillMaxWidth(), + style = RichTextEditorDefaults.style( + text = RichTextEditorDefaults.textStyle( + color = if (state.hasFocus) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.secondary + } + ), + cursor = RichTextEditorDefaults.cursorStyle( + color = ElementTheme.colors.iconAccentTertiary, + ) + ), + onError = onError + ) + } SendButton( - text = text, - canSendMessage = composerCanSendMessage, - onSendMessage = onSendMessage, + canSendMessage = canSendMessage, + onClick = { onSendMessage(Message(html = state.messageHtml, markdown = state.messageMarkdown)) }, composerMode = composerMode, modifier = Modifier.padding(end = 6.dp.applyScaleUp(), bottom = 6.dp.applyScaleUp()) ) @@ -218,7 +199,7 @@ fun TextComposer( val keyboard = LocalSoftwareKeyboardController.current LaunchedEffect(composerMode) { if (composerMode is MessageComposerMode.Special) { - focusRequester.requestFocus() + onRequestFocus() keyboard?.let { awaitFrame() it.show() @@ -241,7 +222,7 @@ private fun ComposerModeView( ReplyToModeView( modifier = modifier.padding(8.dp), senderName = composerMode.senderName, - text = composerMode.defaultContent.toString(), + text = composerMode.defaultContent, attachmentThumbnailInfo = composerMode.attachmentThumbnailInfo, onResetComposerMode = onResetComposerMode, ) @@ -385,9 +366,8 @@ private fun AttachmentButton( @Composable private fun BoxScope.SendButton( - text: String, canSendMessage: Boolean, - onSendMessage: (String) -> Unit, + onClick: () -> Unit, composerMode: MessageComposerMode, modifier: Modifier = Modifier, ) { @@ -405,9 +385,8 @@ private fun BoxScope.SendButton( enabled = canSendMessage, interactionSource = interactionSource, indication = rememberRipple(bounded = false), - onClick = { - onSendMessage(text) - }), + onClick = onClick, + ), contentAlignment = Alignment.Center, ) { val iconId = when (composerMode) { @@ -433,28 +412,37 @@ private fun BoxScope.SendButton( internal fun TextComposerSimplePreview() = ElementPreview { Column { TextComposer( + RichTextEditorState("", fake = true).apply { requestFocus() }, + canSendMessage = false, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Normal(""), onResetComposerMode = {}, - composerCanSendMessage = false, - composerText = "", ) TextComposer( + RichTextEditorState("A message", fake = true).apply { requestFocus() }, + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Normal(""), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) TextComposer( + RichTextEditorState( + "A message\nWith several lines\nTo preview larger textfields and long lines with overflow", + fake = true + ).apply { + requestFocus() + }, + canSendMessage = true, + onSendMessage = {}, + composerMode = MessageComposerMode.Normal(""), + onResetComposerMode = {}, + ) + TextComposer( + RichTextEditorState("A message without focus", fake = true), + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Normal(""), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message\nWith several lines\nTo preview larger textfields and long lines with overflow", ) } } @@ -463,12 +451,11 @@ internal fun TextComposerSimplePreview() = ElementPreview { @Composable internal fun TextComposerEditPreview() = ElementPreview { TextComposer( + RichTextEditorState("A message", fake = true).apply { requestFocus() }, + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Edit(EventId("$1234"), "Some text", TransactionId("1234")), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) } @@ -477,8 +464,9 @@ internal fun TextComposerEditPreview() = ElementPreview { internal fun TextComposerReplyPreview() = ElementPreview { Column { TextComposer( + RichTextEditorState("", fake = true), + canSendMessage = false, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Reply( senderName = "Alice", eventId = EventId("$1234"), @@ -488,12 +476,11 @@ internal fun TextComposerReplyPreview() = ElementPreview { "To preview larger textfields and long lines with overflow" ), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) TextComposer( + RichTextEditorState("A message", fake = true), + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Reply( senderName = "Alice", eventId = EventId("$1234"), @@ -506,12 +493,11 @@ internal fun TextComposerReplyPreview() = ElementPreview { defaultContent = "image.jpg" ), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) TextComposer( + RichTextEditorState("A message", fake = true), + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Reply( senderName = "Alice", eventId = EventId("$1234"), @@ -524,12 +510,11 @@ internal fun TextComposerReplyPreview() = ElementPreview { defaultContent = "video.mp4" ), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) TextComposer( + RichTextEditorState("A message", fake = true), + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Reply( senderName = "Alice", eventId = EventId("$1234"), @@ -542,12 +527,11 @@ internal fun TextComposerReplyPreview() = ElementPreview { defaultContent = "logs.txt" ), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) TextComposer( + RichTextEditorState("A message", fake = true).apply { requestFocus() }, + canSendMessage = true, onSendMessage = {}, - onComposerTextChange = {}, composerMode = MessageComposerMode.Reply( senderName = "Alice", eventId = EventId("$1234"), @@ -560,8 +544,6 @@ internal fun TextComposerReplyPreview() = ElementPreview { defaultContent = "Shared location" ), onResetComposerMode = {}, - composerCanSendMessage = true, - composerText = "A message", ) } } diff --git a/libraries/textcomposer/src/main/res/drawable/ic_add_attachment.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml similarity index 100% rename from libraries/textcomposer/src/main/res/drawable/ic_add_attachment.xml rename to libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml diff --git a/libraries/textcomposer/src/main/res/drawable/ic_send.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml similarity index 100% rename from libraries/textcomposer/src/main/res/drawable/ic_send.xml rename to libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml diff --git a/libraries/textcomposer/src/main/res/drawable/ic_tick.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_tick.xml similarity index 100% rename from libraries/textcomposer/src/main/res/drawable/ic_tick.xml rename to libraries/textcomposer/impl/src/main/res/drawable/ic_tick.xml diff --git a/libraries/textcomposer/src/main/res/values-cs/translations.xml b/libraries/textcomposer/impl/src/main/res/values-cs/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-cs/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-cs/translations.xml diff --git a/libraries/textcomposer/src/main/res/values-de/translations.xml b/libraries/textcomposer/impl/src/main/res/values-de/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-de/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-de/translations.xml diff --git a/libraries/textcomposer/src/main/res/values-ro/translations.xml b/libraries/textcomposer/impl/src/main/res/values-ro/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-ro/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-ro/translations.xml diff --git a/libraries/textcomposer/src/main/res/values-ru/translations.xml b/libraries/textcomposer/impl/src/main/res/values-ru/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-ru/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-ru/translations.xml diff --git a/libraries/textcomposer/src/main/res/values-sk/translations.xml b/libraries/textcomposer/impl/src/main/res/values-sk/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-sk/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-sk/translations.xml diff --git a/libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml b/libraries/textcomposer/impl/src/main/res/values-zh-rTW/translations.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values-zh-rTW/translations.xml rename to libraries/textcomposer/impl/src/main/res/values-zh-rTW/translations.xml diff --git a/libraries/textcomposer/src/main/res/values/localazy.xml b/libraries/textcomposer/impl/src/main/res/values/localazy.xml similarity index 100% rename from libraries/textcomposer/src/main/res/values/localazy.xml rename to libraries/textcomposer/impl/src/main/res/values/localazy.xml diff --git a/libraries/textcomposer/test/build.gradle.kts b/libraries/textcomposer/test/build.gradle.kts new file mode 100644 index 0000000000..04e36e337d --- /dev/null +++ b/libraries/textcomposer/test/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.libraries.textcomposer.test" +} + +dependencies { + api(projects.libraries.textcomposer.impl) + implementation(projects.tests.testutils) +} diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index fb082e27a7..592cf3c52a 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -99,7 +99,7 @@ fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:mediapickers:impl")) implementation(project(":libraries:mediaupload:impl")) implementation(project(":libraries:usersearch:impl")) - implementation(project(":libraries:textcomposer")) + implementation(project(":libraries:textcomposer:impl")) } fun DependencyHandlerScope.allServicesImpl() { diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index f3b3a7fab2..c52f66ef2d 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -32,6 +32,7 @@ class FakeAnalyticsService( private val isEnabledFlow = MutableStateFlow(isEnabled) private val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent) val capturedEvents = mutableListOf() + val trackedErrors = mutableListOf() override fun getAvailableAnalyticsProviders(): Set = emptySet() @@ -66,6 +67,7 @@ class FakeAnalyticsService( } override fun trackError(throwable: Throwable) { + trackedErrors += throwable } override suspend fun reset() { diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png index f11cec4281..fa68f3bd24 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:906c643393af8d290f0635d7560eaa54339fc0498744f9ab8139932986d73a8c -size 9740 +oid sha256:4013454094701004f3c132df1ea1c3db2aa56a025b9edea80417fdd16fe55b19 +size 10422 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png index eb5a63601c..f6040d0e1a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd57f885f161316550712dcb471ed213537a395539ed5b9975e17465310803b7 -size 9823 +oid sha256:db74b1655e377e4fd8c35aa18c22ef5f5641586b64d5e582ab2079afeac4b8c3 +size 10775 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png index 08734109fb..2a10272dac 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39b527075df2b3f7afa4f3ecfca1ac93a180855b20d2bd64cb763fb98b0a7b69 -size 51340 +oid sha256:cfc6f54988e4fab08ff443f0c2ea285d47e3d030a8e6c92a1294ee0f85dc1269 +size 51967 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png index 60f606fe58..5cf07497cd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81f196dc08f4de31f4257f6ba89c52ea41a97b107e7c5c04261188e6c572d4d0 -size 52594 +oid sha256:d2ffd4fc93e7da38836fd860ce5e505c5f0c25fdd6558efef480aaeb05d00dd5 +size 53327 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index 6b3be5e81e..41f0170682 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a648d286a3b0536fc97801c3281bb8df432c7ffa28efff66f67cd6cf4c546c10 -size 51579 +oid sha256:96864552336c65b464251c262f330856fc82c69a5f92f89b1357a185d654fccd +size 52252 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index e2266026d1..a022fb7675 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34f9eacfd61965cfde4f420fe6a0fc0d637a21aca0d4b12c6a6f1642bd44556d -size 50586 +oid sha256:2411212e87f95415e0b4ed6732387922faed891cde5e78fa9f0691a185873129 +size 51026 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png index 040fa6c12a..5fe74737cf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c336a9cbc803eb314aa9333719d813ae64994a75344aa363b25aee8d52551b21 -size 48928 +oid sha256:255560f478c093f4ca7d021646f4cf9064c16b420d5eeec7cbce97d26c751d92 +size 49540 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png index a178b31231..caf6d5a3da 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d7148068516b5e3299cce2924ea3cb54c8f1ddd6378e48b0fa746217a547d22 -size 52940 +oid sha256:a384aa84ae514aa4989d4b4a5ef8048cb8810f1f37056137c77fd0ee798a0bab +size 53941 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png index f4a3738cf8..93163a476e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8aaf2c70473711a24bf587ff524fd71d43c2610ade1c3d4ff2013705d5670b3 -size 54314 +oid sha256:a48badf15c59ab5c42fc7cc200971f00cefa7838461ad0cb59537c2b4065bfff +size 55409 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index f40d649d64..1ff65d3301 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:566d5b197091d4b740e1241eab54017fd31e65f570def4b8c24ade19ea78ccc8 -size 53254 +oid sha256:88a498b9070653513b3e27aa2b597367ee85c8526c6e4c3712a4cb0c06e5313b +size 54353 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index 4e0d1ce4bc..be91f54717 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8353077959916fa85046d3a81d1479d552748635f1286bb8bacc6d922ba30f28 -size 55312 +oid sha256:bf493a9cb7325b4f68924abd86864b37c72226afcf1c4179a06c17e923cfd0ae +size 55837 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png index d2ac508bf8..432e114fd5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a84dabfdcbaff8de5c30472676dee2cee8dc0f77469f2802dfc796a87bc10dff -size 50328 +oid sha256:8ac3dbf36380fa273d82ebe8836c525bbeee004d6348822d965b216f9bcdb920 +size 51335 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png index 4e97d85b18..b1144213da 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8c4dfcbfb6c97b9bb8a33df6fd1ef57ef436b2c7e7e9bfa5d6a59fcae2515be -size 14140 +oid sha256:ce08e8c81d5494d2d803da43612a137df881e359646878b1d38cdfe77e0857ff +size 13829 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png index 4fe86c030b..62264fcf27 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4fd3c3f554bd668552863a6f7cd3b43cd15cf4a29b2fd67265e3a9a8a05d4258 -size 13216 +oid sha256:3c2ba0ac13c81c707f0d00e3ff69737163dfc450a3d21aa468dd0b34deeeb7e1 +size 12916 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png index 26c038b0a4..3e872eda82 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:049d237aa3e2ba18df462caca17d059fa47e25de9bee8f1fbfd310106a1de07c -size 81319 +oid sha256:f15bc37e2a3d052e8d79e663f2c03223c27ddff3c02cd69f95a140c33fc6952c +size 79320 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png index 0e609116be..8bd9e09c69 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d45e4a53b9280b295b731ac1287ea31a8c2b653e0ae5dedd82fd2c0a6c2078ba -size 78323 +oid sha256:6aa9b8849a2bbd7b487de6fee7fd355300091bc14d647973c4beea02e6009ac4 +size 76465 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png index ef4d9ab56c..8afc6fc94a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a817f9c6e2d9823dc7f4d20669c80a3cf8f39e6a4468d7dde7159cb7920f20fd -size 35134 +oid sha256:501734b297cec566a008d3492690cf75b46ab68e662d2835a0b195fd0740c13f +size 42912 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png index 9b3ff03b0b..de57e08951 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a67d75e43fff35eaa3fff9c17245738b16cb7687f6915c1857a2ba85a61037bf -size 33576 +oid sha256:ff69ed7056380df3279a39b7544bc1887d2e455b43fb069b547e32cf5c92dc0f +size 40229 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index cf29033d88..b92e02f670 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -45,7 +45,7 @@ ] }, { - "name": ":libraries:textcomposer", + "name": ":libraries:textcomposer:impl", "includeRegex": [ "rich_text_editor_.*" ] From 54968f98ed5ef9f4c4bfd0b7c1c3700ff0bcb93b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 17:25:50 +0200 Subject: [PATCH 082/127] Add a last Spacer item to ensure that the FAB does not hide the last room item --- .../android/features/roomlist/impl/RoomListView.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index f7eb5aa4eb..f7f712fbc3 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -20,8 +20,10 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed @@ -52,8 +54,8 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.search.RoomListSearchResultView import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight -import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.designsystem.theme.components.FloatingActionButton +import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.utils.LogCompositions @@ -210,6 +212,11 @@ fun RoomListContent( HorizontalDivider() } } + // Add a last Spacer item to ensure that the FAB does not hide the last room item + // FAB height is 56dp, bottom padding is 16dp, we add 8dp as extra margin -> 56+16+8 = 80 + item { + Spacer(modifier = Modifier.height(80.dp)) + } } }, floatingActionButton = { From a3940ddc5b9bfb97e6a464f7a4dbfef1b66c3957 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 7 Sep 2023 15:52:41 +0200 Subject: [PATCH 083/127] Use roomInfo instead of individually access roomListItem properties --- changelog.d/1251.misc | 1 + .../roomlist/RoomSummaryDetailsFactory.kt | 23 ++++++++++--------- .../impl/roomlist/RoomSummaryListProcessor.kt | 16 +++---------- .../impl/roomlist/RustRoomListService.kt | 4 ++-- 4 files changed, 18 insertions(+), 26 deletions(-) create mode 100644 changelog.d/1251.misc diff --git a/changelog.d/1251.misc b/changelog.d/1251.misc new file mode 100644 index 0000000000..ba3b37b8ff --- /dev/null +++ b/changelog.d/1251.misc @@ -0,0 +1 @@ +Improve RoomSummary mapping by using RoomInfo. 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 b57eb892e0..d33e2f58fc 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 @@ -20,25 +20,26 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.impl.room.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory -import org.matrix.rustcomponents.sdk.Room -import org.matrix.rustcomponents.sdk.RoomListItem +import org.matrix.rustcomponents.sdk.RoomInfo +import org.matrix.rustcomponents.sdk.use class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) { - suspend fun create(roomListItem: RoomListItem, room: Room?): RoomSummaryDetails { - val latestRoomMessage = roomListItem.latestEvent()?.use { + fun create(roomInfo: RoomInfo): RoomSummaryDetails { + val latestRoomMessage = roomInfo.latestEvent?.use { roomMessageFactory.create(it) } return RoomSummaryDetails( - roomId = RoomId(roomListItem.id()), - name = roomListItem.name() ?: roomListItem.id(), - canonicalAlias = roomListItem.canonicalAlias(), - isDirect = roomListItem.isDirect(), - avatarURLString = roomListItem.avatarUrl(), - unreadNotificationCount = roomListItem.unreadNotifications().use { it.notificationCount().toInt() }, + roomId = RoomId(roomInfo.id), + name = roomInfo.name ?: roomInfo.id, + canonicalAlias = roomInfo.canonicalAlias, + isDirect = roomInfo.isDirect, + avatarURLString = roomInfo.avatarUrl, + unreadNotificationCount = roomInfo.notificationCount.toInt(), lastMessage = latestRoomMessage, lastMessageTimestamp = latestRoomMessage?.originServerTs, - inviter = room?.inviter()?.let(RoomMemberMapper::map), + inviter = roomInfo.inviter?.let(RoomMemberMapper::map), ) } } + 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 9a67ff1f30..03b58ed2ce 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 @@ -22,11 +22,10 @@ import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate import org.matrix.rustcomponents.sdk.RoomListEntry -import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.RoomListService +import org.matrix.rustcomponents.sdk.use import timber.log.Timber import java.util.UUID @@ -34,7 +33,6 @@ class RoomSummaryListProcessor( private val roomSummaries: MutableStateFlow>, private val roomListService: RoomListService, private val roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(), - private val shouldFetchFullRoom: Boolean = false, ) { private val roomSummariesByIdentifier = HashMap() @@ -120,9 +118,9 @@ class RoomSummaryListProcessor( private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary { val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> - roomListItem.fullRoomOrNull().use { fullRoom -> + roomListItem.roomInfo().use { roomInfo -> RoomSummary.Filled( - details = roomSummaryDetailsFactory.create(roomListItem, fullRoom) + details = roomSummaryDetailsFactory.create(roomInfo) ) } } ?: buildEmptyRoomSummary() @@ -130,14 +128,6 @@ class RoomSummaryListProcessor( return builtRoomSummary } - private fun RoomListItem.fullRoomOrNull(): Room? { - return if (shouldFetchFullRoom) { - fullRoom() - } else { - null - } - } - private suspend fun updateRoomSummaries(block: suspend MutableList.() -> Unit) = mutex.withLock { val mutableRoomSummaries = roomSummaries.value.toMutableList() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt index 655c634502..5dade3b1c7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt @@ -52,9 +52,9 @@ class RustRoomListService( private val inviteRooms = MutableStateFlow>(emptyList()) private val allRoomsLoadingState: MutableStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) - private val allRoomsListProcessor = RoomSummaryListProcessor(allRooms, innerRoomListService, roomSummaryDetailsFactory, shouldFetchFullRoom = false) + private val allRoomsListProcessor = RoomSummaryListProcessor(allRooms, innerRoomListService, roomSummaryDetailsFactory) private val invitesLoadingState: MutableStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) - private val inviteRoomsListProcessor = RoomSummaryListProcessor(inviteRooms, innerRoomListService, roomSummaryDetailsFactory, shouldFetchFullRoom = true) + private val inviteRoomsListProcessor = RoomSummaryListProcessor(inviteRooms, innerRoomListService, roomSummaryDetailsFactory) init { sessionCoroutineScope.launch(dispatcher) { From f503eba02105d4bd198448958f7683cd625012f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 19:01:23 +0000 Subject: [PATCH 084/127] Update dependency org.matrix.rustcomponents:sdk-android to v0.1.50 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ebbc937bfa..be044a9e13 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -147,7 +147,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" } timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.49" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.50" 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 = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" } From d2898d2bcaa9c9000f9b18c2833bebe4f88759e3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 7 Sep 2023 21:59:17 +0200 Subject: [PATCH 085/127] Add changelog. --- changelog.d/1244.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1244.misc diff --git a/changelog.d/1244.misc b/changelog.d/1244.misc new file mode 100644 index 0000000000..ab0bbf5178 --- /dev/null +++ b/changelog.d/1244.misc @@ -0,0 +1 @@ +Use the new SyncIndicator API. From 61f5983b2ba6e184e53865f29f71bef46162d024 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 22:59:56 +0200 Subject: [PATCH 086/127] Remove unused val. --- .../io/element/android/appnav/loggedin/LoggedInPresenter.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt index 49253edc99..7683b7278f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt @@ -30,8 +30,6 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.push.api.PushService import javax.inject.Inject -private const val DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS = 1500L - class LoggedInPresenter @Inject constructor( private val matrixClient: MatrixClient, private val networkMonitor: NetworkMonitor, From 26118a968d088558272e70c081adcd3e5a38c899 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 01:27:46 +0000 Subject: [PATCH 087/127] Update anvil to v2.4.8-1-8 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6bf00e9c02..6d415faf59 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -50,7 +50,7 @@ wysiwyg = "2.9.0" # DI dagger = "2.48" -anvil = "2.4.7-1-8" +anvil = "2.4.8-1-8" # Auto service autoservice = "1.1.1" From 0e1d61bc12c0274dccfd7397b682478aabb8c279 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 08:22:41 +0200 Subject: [PATCH 088/127] rename parameter to match parent name. --- .../libraries/matrix/impl/roomlist/RoomListExtensions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index ea932be896..1e599a184d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -88,8 +88,8 @@ fun RoomListService.stateFlow(): Flow = fun RoomListService.syncIndicator(): Flow = mxCallbackFlow { val listener = object : RoomListServiceSyncIndicatorListener { - override fun onUpdate(indicator: RoomListServiceSyncIndicator) { - trySendBlocking(indicator) + override fun onUpdate(syncIndicator: RoomListServiceSyncIndicator) { + trySendBlocking(syncIndicator) } } tryOrNull { From 896c2325db5b64ce9abe691079ad054574c69e8c Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Fri, 8 Sep 2023 17:23:15 +0100 Subject: [PATCH 089/127] [Rich text editor] Add formatting menu (#1261) --------- Co-authored-by: ElementBot --- changelog.d/1261.feature | 1 + .../messagecomposer/AttachmentsBottomSheet.kt | 6 + .../messagecomposer/MessageComposerEvents.kt | 1 + .../MessageComposerPresenter.kt | 6 + .../messagecomposer/MessageComposerState.kt | 1 + .../MessageComposerStateProvider.kt | 2 + .../messagecomposer/MessageComposerView.kt | 6 + .../MessageComposerPresenterTest.kt | 23 + .../libraries/designsystem/VectorIcons.kt | 12 + .../src/main/res/drawable/ic_bold.xml | 9 + .../src/main/res/drawable/ic_bullet_list.xml | 9 + .../src/main/res/drawable/ic_code_block.xml | 9 + .../main/res/drawable/ic_indent_decrease.xml | 9 + .../main/res/drawable/ic_indent_increase.xml | 9 + .../src/main/res/drawable/ic_inline_code.xml | 15 + .../src/main/res/drawable/ic_italic.xml | 9 + .../src/main/res/drawable/ic_link.xml | 9 + .../main/res/drawable/ic_numbered_list.xml | 9 + .../src/main/res/drawable/ic_quote.xml | 18 + .../main/res/drawable/ic_strikethrough.xml | 9 + .../src/main/res/drawable/ic_underline.xml | 9 + libraries/textcomposer/impl/build.gradle.kts | 2 + .../libraries/textcomposer/TextComposer.kt | 508 ++++++++++++------ .../components/FormattingOption.kt | 69 +++ .../components/FormattingOptionState.kt | 22 + .../main/res/drawable/ic_add_attachment.xml | 10 - .../impl/src/main/res/drawable/ic_cancel.xml | 9 + .../impl/src/main/res/drawable/ic_plus.xml | 9 + .../impl/src/main/res/drawable/ic_send.xml | 12 +- ...ePickerMenu-D-1_2_null,NEXUS_5,1.0,en].png | 4 +- ...ePickerMenu-N-1_3_null,NEXUS_5,1.0,en].png | 4 +- ...poserViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...oserViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...sagesViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...agesViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...omposerEdit-D-1_2_null,NEXUS_5,1.0,en].png | 3 - ...omposerEdit-D-2_3_null,NEXUS_5,1.0,en].png | 3 + ...omposerEdit-N-1_3_null,NEXUS_5,1.0,en].png | 3 - ...omposerEdit-N-2_4_null,NEXUS_5,1.0,en].png | 3 + ...rFormatting-D-1_2_null,NEXUS_5,1.0,en].png | 3 + ...rFormatting-N-1_3_null,NEXUS_5,1.0,en].png | 3 + ...mposerReply-D-2_3_null,NEXUS_5,1.0,en].png | 3 - ...mposerReply-D-3_4_null,NEXUS_5,1.0,en].png | 3 + ...mposerReply-N-2_4_null,NEXUS_5,1.0,en].png | 3 - ...mposerReply-N-3_5_null,NEXUS_5,1.0,en].png | 3 + ...poserSimple-D-0_1_null,NEXUS_5,1.0,en].png | 4 +- ...poserSimple-N-0_2_null,NEXUS_5,1.0,en].png | 4 +- 55 files changed, 706 insertions(+), 210 deletions(-) create mode 100644 changelog.d/1261.feature create mode 100644 libraries/designsystem/src/main/res/drawable/ic_bold.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_bullet_list.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_code_block.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_indent_decrease.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_indent_increase.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_inline_code.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_italic.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_link.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_numbered_list.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_quote.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_strikethrough.xml create mode 100644 libraries/designsystem/src/main/res/drawable/ic_underline.xml create mode 100644 libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt create mode 100644 libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOptionState.kt delete mode 100644 libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml create mode 100644 libraries/textcomposer/impl/src/main/res/drawable/ic_cancel.xml create mode 100644 libraries/textcomposer/impl/src/main/res/drawable/ic_plus.xml delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-2_3_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-2_4_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-D-1_2_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-N-1_3_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png diff --git a/changelog.d/1261.feature b/changelog.d/1261.feature new file mode 100644 index 0000000000..bf7dd2399d --- /dev/null +++ b/changelog.d/1261.feature @@ -0,0 +1 @@ +[Rich text editor] Add formatting menu (accessible via the '+' button) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt index 43805bb5c0..38ef458bd9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt @@ -26,6 +26,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AttachFile import androidx.compose.material.icons.filled.BarChart import androidx.compose.material.icons.filled.Collections +import androidx.compose.material.icons.filled.FormatColorText import androidx.compose.material.icons.filled.LocationOn import androidx.compose.material.icons.filled.PhotoCamera import androidx.compose.material.icons.filled.Videocam @@ -145,6 +146,11 @@ internal fun AttachmentSourcePickerMenu( text = { Text(stringResource(R.string.screen_room_attachment_source_poll)) }, ) } + ListItem( + modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.ToggleTextFormatting(enabled = true)) }, + icon = { Icon(Icons.Default.FormatColorText, null) }, + text = { Text(stringResource(R.string.screen_room_attachment_text_formatting)) }, + ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt index 4bfd290a77..92b180f326 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt @@ -36,6 +36,7 @@ sealed interface MessageComposerEvents { data object Location : PickAttachmentSource data object Poll : PickAttachmentSource } + data class ToggleTextFormatting(val enabled: Boolean) : MessageComposerEvents data object CancelSendAttachment : MessageComposerEvents data class Error(val error: Throwable) : MessageComposerEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 687e951933..3c3ebc2db9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -110,6 +110,7 @@ class MessageComposerPresenter @Inject constructor( val ongoingSendAttachmentJob = remember { mutableStateOf(null) } var showAttachmentSourcePicker: Boolean by remember { mutableStateOf(false) } + var showTextFormatting: Boolean by remember { mutableStateOf(false) } LaunchedEffect(messageComposerContext.composerMode) { when (val modeValue = messageComposerContext.composerMode) { @@ -190,6 +191,10 @@ class MessageComposerPresenter @Inject constructor( ongoingSendAttachmentJob.value == null } } + is MessageComposerEvents.ToggleTextFormatting -> { + showAttachmentSourcePicker = false + showTextFormatting = event.enabled + } is MessageComposerEvents.Error -> { analyticsService.trackError(event.error) } @@ -201,6 +206,7 @@ class MessageComposerPresenter @Inject constructor( isFullScreen = isFullScreen.value, mode = messageComposerContext.composerMode, showAttachmentSourcePicker = showAttachmentSourcePicker, + showTextFormatting = showTextFormatting, canShareLocation = canShareLocation.value, canCreatePoll = canCreatePoll.value, attachmentsState = attachmentsState.value, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index bdff621521..65fac53fdc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -28,6 +28,7 @@ data class MessageComposerState( val isFullScreen: Boolean, val mode: MessageComposerMode, val showAttachmentSourcePicker: Boolean, + val showTextFormatting: Boolean, val canShareLocation: Boolean, val canCreatePoll: Boolean, val attachmentsState: AttachmentsState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt index ab15d8ccd8..d86969fc19 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt @@ -32,6 +32,7 @@ fun aMessageComposerState( composerState: RichTextEditorState = RichTextEditorState("", fake = true), isFullScreen: Boolean = false, mode: MessageComposerMode = MessageComposerMode.Normal(content = ""), + showTextFormatting: Boolean = false, showAttachmentSourcePicker: Boolean = false, canShareLocation: Boolean = true, canCreatePoll: Boolean = true, @@ -40,6 +41,7 @@ fun aMessageComposerState( richTextEditorState = composerState.apply { if(requestFocus) requestFocus() }, isFullScreen = isFullScreen, mode = mode, + showTextFormatting = showTextFormatting, showAttachmentSourcePicker = showAttachmentSourcePicker, canShareLocation = canShareLocation, canCreatePoll = canCreatePoll, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt index 5106a3359b..4ea5a7cf76 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt @@ -49,6 +49,10 @@ fun MessageComposerView( state.eventSink(MessageComposerEvents.CloseSpecialMode) } + fun onDismissTextFormatting() { + state.eventSink(MessageComposerEvents.ToggleTextFormatting(enabled = false)) + } + fun onError(error: Throwable) { state.eventSink(MessageComposerEvents.Error(error)) } @@ -66,8 +70,10 @@ fun MessageComposerView( onRequestFocus = { state.richTextEditorState.requestFocus() }, onSendMessage = ::sendMessage, composerMode = state.mode, + showTextFormatting = state.showTextFormatting, onResetComposerMode = ::onCloseSpecialMode, onAddAttachment = ::onAddAttachment, + onDismissTextFormatting = ::onDismissTextFormatting, onError = ::onError, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index 7284fb3b7e..d1d4a54073 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -539,6 +539,29 @@ class MessageComposerPresenterTest { } } + @Test + fun `present - ToggleTextFormatting toggles text formatting`() = runTest { + val presenter = createPresenter(this) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.showTextFormatting).isFalse() + initialState.eventSink(MessageComposerEvents.AddAttachment) + val composerOptions = awaitItem() + assertThat(composerOptions.showAttachmentSourcePicker).isTrue() + composerOptions.eventSink(MessageComposerEvents.ToggleTextFormatting(true)) + awaitItem() // composer options closed + val showTextFormatting = awaitItem() + assertThat(showTextFormatting.showAttachmentSourcePicker).isFalse() + assertThat(showTextFormatting.showTextFormatting).isTrue() + showTextFormatting.eventSink(MessageComposerEvents.ToggleTextFormatting(false)) + val finished = awaitItem() + assertThat(finished.showTextFormatting).isFalse() + } + } + private suspend fun ReceiveTurbine.backToNormalMode(state: MessageComposerState, skipCount: Int = 0) { state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode) skipItems(skipCount) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt index 4f06b3ebcb..cd1b408a99 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt @@ -28,4 +28,16 @@ object VectorIcons { val Groups = R.drawable.ic_groups val Share = R.drawable.ic_share val EndPoll = R.drawable.ic_poll_end + val Bold = R.drawable.ic_bold + val BulletList = R.drawable.ic_bullet_list + val CodeBlock = R.drawable.ic_code_block + val IndentIncrease = R.drawable.ic_indent_increase + val IndentDecrease = R.drawable.ic_indent_decrease + val InlineCode = R.drawable.ic_inline_code + val Italic = R.drawable.ic_italic + val Link = R.drawable.ic_link + val NumberedList = R.drawable.ic_numbered_list + val Quote = R.drawable.ic_quote + val Strikethrough = R.drawable.ic_strikethrough + val Underline = R.drawable.ic_underline } diff --git a/libraries/designsystem/src/main/res/drawable/ic_bold.xml b/libraries/designsystem/src/main/res/drawable/ic_bold.xml new file mode 100644 index 0000000000..c361f85d3d --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_bold.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_bullet_list.xml b/libraries/designsystem/src/main/res/drawable/ic_bullet_list.xml new file mode 100644 index 0000000000..72d8324622 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_bullet_list.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_code_block.xml b/libraries/designsystem/src/main/res/drawable/ic_code_block.xml new file mode 100644 index 0000000000..6e622f5b27 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_code_block.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_indent_decrease.xml b/libraries/designsystem/src/main/res/drawable/ic_indent_decrease.xml new file mode 100644 index 0000000000..5a0b284223 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_indent_decrease.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_indent_increase.xml b/libraries/designsystem/src/main/res/drawable/ic_indent_increase.xml new file mode 100644 index 0000000000..367686ceac --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_indent_increase.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_inline_code.xml b/libraries/designsystem/src/main/res/drawable/ic_inline_code.xml new file mode 100644 index 0000000000..c0dc504ed9 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_inline_code.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_italic.xml b/libraries/designsystem/src/main/res/drawable/ic_italic.xml new file mode 100644 index 0000000000..f640c109f4 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_italic.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_link.xml b/libraries/designsystem/src/main/res/drawable/ic_link.xml new file mode 100644 index 0000000000..fd69ec4703 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_link.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_numbered_list.xml b/libraries/designsystem/src/main/res/drawable/ic_numbered_list.xml new file mode 100644 index 0000000000..f4f5862656 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_numbered_list.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_quote.xml b/libraries/designsystem/src/main/res/drawable/ic_quote.xml new file mode 100644 index 0000000000..e17565a6cc --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_quote.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_strikethrough.xml b/libraries/designsystem/src/main/res/drawable/ic_strikethrough.xml new file mode 100644 index 0000000000..d1994f8045 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_strikethrough.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_underline.xml b/libraries/designsystem/src/main/res/drawable/ic_underline.xml new file mode 100644 index 0000000000..09f92f2104 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_underline.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/textcomposer/impl/build.gradle.kts b/libraries/textcomposer/impl/build.gradle.kts index 3aaae7ca6e..633491d3b3 100644 --- a/libraries/textcomposer/impl/build.gradle.kts +++ b/libraries/textcomposer/impl/build.gradle.kts @@ -31,6 +31,8 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrixui) implementation(projects.libraries.designsystem) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.constraintlayout.compose) implementation(libs.matrix.richtexteditor) api(libs.matrix.richtexteditor.compose) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 04fa08c9ce..d137af18bb 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -18,29 +18,29 @@ package io.element.android.libraries.textcomposer import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.tween -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -51,21 +51,22 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension.Companion.fillToConstraints +import androidx.constraintlayout.compose.Visibility import io.element.android.libraries.designsystem.VectorIcons -import io.element.android.libraries.designsystem.modifiers.applyIf import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.text.applyScaleUp import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Surface +import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.TransactionId @@ -73,12 +74,17 @@ import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.ui.components.AttachmentThumbnail import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType +import io.element.android.libraries.textcomposer.components.FormattingOption +import io.element.android.libraries.textcomposer.components.FormattingOptionState import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.wysiwyg.compose.RichTextEditor import io.element.android.wysiwyg.compose.RichTextEditorDefaults import io.element.android.wysiwyg.compose.RichTextEditorState +import io.element.android.wysiwyg.view.models.InlineFormat import kotlinx.coroutines.android.awaitFrame +import uniffi.wysiwyg_composer.ActionState +import uniffi.wysiwyg_composer.ComposerAction @Composable fun TextComposer( @@ -86,112 +92,130 @@ fun TextComposer( composerMode: MessageComposerMode, canSendMessage: Boolean, modifier: Modifier = Modifier, + showTextFormatting: Boolean = false, onRequestFocus: () -> Unit = {}, onSendMessage: (Message) -> Unit = {}, onResetComposerMode: () -> Unit = {}, onAddAttachment: () -> Unit = {}, + onDismissTextFormatting: () -> Unit = {}, onError: (Throwable) -> Unit = {}, ) { - Row( - modifier.padding( - horizontal = 12.dp, - vertical = 8.dp - ), verticalAlignment = Alignment.Bottom - ) { - AttachmentButton(onClick = onAddAttachment, modifier = Modifier.padding(vertical = 6.dp)) - Spacer(modifier = Modifier.width(12.dp)) - val roundCornerSmall = 20.dp.applyScaleUp() - val roundCornerLarge = 28.dp.applyScaleUp() + val onSendClicked = { + onSendMessage(Message(html = state.messageHtml, markdown = state.messageMarkdown)) + } - val roundedCornerSize = remember(state.lineCount, composerMode) { - if (state.lineCount > 1 || composerMode is MessageComposerMode.Special) { - roundCornerSmall - } else { - roundCornerLarge - } - } - val roundedCornerSizeState = animateDpAsState( - targetValue = roundedCornerSize, - animationSpec = tween( - durationMillis = 100, + Column( + modifier = modifier + .padding( + start = 3.dp, + end = 6.dp, + top = 8.dp, + bottom = 5.dp, ) - ) - val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value) - val minHeight = 42.dp.applyScaleUp() - val colors = ElementTheme.colors - val bgColor = colors.bgSubtleSecondary - - val borderColor by remember(state.hasFocus, colors) { - derivedStateOf { - if (state.hasFocus) colors.borderDisabled else bgColor - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .clip(roundedCorners) - .background(color = bgColor) - .border(1.dp, borderColor, roundedCorners) + .fillMaxWidth(), + ) { + ConstraintLayout( + modifier = Modifier.fillMaxWidth(), ) { - if (composerMode is MessageComposerMode.Special) { - ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode) + val (composeOptions, textInput, sendButton) = createRefs() + val showComposerOptionsButton by remember(showTextFormatting) { + derivedStateOf { !showTextFormatting } } - val defaultTypography = ElementTheme.typography.fontBodyLgRegular - - Box { - Box( - modifier = Modifier - .heightIn(min = minHeight) - .background(color = bgColor, shape = roundedCorners) - .padding( - PaddingValues( - top = 4.dp.applyScaleUp(), - bottom = 4.dp.applyScaleUp(), - start = 12.dp.applyScaleUp(), - end = 42.dp.applyScaleUp() - ) - ), - contentAlignment = Alignment.CenterStart, - ) { - - // Placeholder - if (state.messageHtml.isEmpty()) { - Text( - stringResource(CommonStrings.common_message), - style = defaultTypography.copy( - color = ElementTheme.colors.textDisabled, - ), - ) - } - - RichTextEditor( - state = state, - modifier = Modifier - .fillMaxWidth(), - style = RichTextEditorDefaults.style( - text = RichTextEditorDefaults.textStyle( - color = if (state.hasFocus) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.secondary - } - ), - cursor = RichTextEditorDefaults.cursorStyle( - color = ElementTheme.colors.iconAccentTertiary, - ) - ), - onError = onError - ) - } - - SendButton( - canSendMessage = canSendMessage, - onClick = { onSendMessage(Message(html = state.messageHtml, markdown = state.messageMarkdown)) }, - composerMode = composerMode, - modifier = Modifier.padding(end = 6.dp.applyScaleUp(), bottom = 6.dp.applyScaleUp()) + IconButton( + modifier = Modifier + .size(48.dp) + .constrainAs(composeOptions) { + start.linkTo(parent.start) + bottom.linkTo(parent.bottom) + visibility = if (showComposerOptionsButton) Visibility.Visible else Visibility.Gone + }, + onClick = onAddAttachment + ) { + Icon( + modifier = Modifier.size(30.dp.applyScaleUp()), + resourceId = R.drawable.ic_plus, // TODO Replace with design system icon when available + contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), + tint = ElementTheme.colors.iconPrimary, ) } + val roundCornerSmall = 20.dp.applyScaleUp() + val roundCornerLarge = 28.dp.applyScaleUp() + + val roundedCornerSize = remember(state.lineCount, composerMode) { + if (state.lineCount > 1 || composerMode is MessageComposerMode.Special) { + roundCornerSmall + } else { + roundCornerLarge + } + } + val roundedCornerSizeState = animateDpAsState( + targetValue = roundedCornerSize, + animationSpec = tween( + durationMillis = 100, + ) + ) + val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value) + val colors = ElementTheme.colors + val bgColor = colors.bgSubtleSecondary + + val borderColor by remember(state.hasFocus, colors) { + derivedStateOf { + if (state.hasFocus) colors.borderDisabled else bgColor + } + } + + Column( + modifier = Modifier + .constrainAs(textInput) { + start.linkTo(composeOptions.end, margin = 3.dp, goneMargin = 9.dp) + end.linkTo(sendButton.start, margin = 6.dp, goneMargin = 6.dp) + bottom.linkTo(parent.bottom) + width = fillToConstraints + } + .padding(vertical = 3.dp) + .fillMaxWidth() + .clip(roundedCorners) + .background(color = bgColor) + .border(1.dp, borderColor, roundedCorners) + ) { + if (composerMode is MessageComposerMode.Special) { + ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode) + } + + TextInput( + state = state, + roundedCorners = roundedCorners, + bgColor = bgColor, + onError = onError, + ) + } + + SendButton( + canSendMessage = canSendMessage, + onClick = onSendClicked, + composerMode = composerMode, + modifier = Modifier + .constrainAs(sendButton) { + bottom.linkTo(parent.bottom) + end.linkTo(parent.end) + visibility = if (!showTextFormatting) Visibility.Visible else Visibility.Gone + } + ) + } + + if (showTextFormatting) { + TextFormatting( + state = state, + onDismiss = onDismissTextFormatting, + sendButton = { + SendButton( + canSendMessage = canSendMessage, + onClick = onSendClicked, + composerMode = composerMode, + modifier = it + ) + }, + ) } } @@ -208,6 +232,192 @@ fun TextComposer( } } +@Composable +private fun TextInput( + state: RichTextEditorState, + roundedCorners: RoundedCornerShape, + bgColor: Color, + modifier: Modifier = Modifier, + onError: (Throwable) -> Unit = {}, +) { + val minHeight = 42.dp.applyScaleUp() + val defaultTypography = ElementTheme.typography.fontBodyLgRegular + Box( + modifier = modifier + .heightIn(min = minHeight) + .background(color = bgColor, shape = roundedCorners) + .padding( + PaddingValues( + top = 4.dp.applyScaleUp(), + bottom = 4.dp.applyScaleUp(), + start = 12.dp.applyScaleUp(), + end = 42.dp.applyScaleUp() + ) + ), + contentAlignment = Alignment.CenterStart, + ) { + + // Placeholder + if (state.messageHtml.isEmpty()) { + Text( + stringResource(CommonStrings.common_message), + style = defaultTypography.copy( + color = ElementTheme.colors.textDisabled, + ), + ) + } + + RichTextEditor( + state = state, + modifier = Modifier + .fillMaxWidth(), + style = RichTextEditorDefaults.style( + text = RichTextEditorDefaults.textStyle( + color = if (state.hasFocus) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.secondary + } + ), + cursor = RichTextEditorDefaults.cursorStyle( + color = ElementTheme.colors.iconAccentTertiary, + ) + ), + onError = onError + ) + } +} + +@Composable +private fun TextFormatting( + state: RichTextEditorState, + onDismiss: () -> Unit, + modifier: Modifier = Modifier, + sendButton: @Composable (modifier: Modifier) -> Unit, +) { + ConstraintLayout( + modifier = modifier + .fillMaxWidth() + ) { + val (close, formatting, send) = createRefs() + + IconButton( + modifier = Modifier + .size(48.dp) + .constrainAs(close) { + start.linkTo(parent.start) + top.linkTo(parent.top) + bottom.linkTo(parent.bottom) + }, + onClick = onDismiss + ) { + Icon( + modifier = Modifier.size(30.dp.applyScaleUp()), + resourceId = R.drawable.ic_cancel, // TODO Replace with design system icon when available + contentDescription = stringResource(CommonStrings.action_close), + tint = ElementTheme.colors.iconPrimary, + ) + } + + val scrollState = rememberScrollState() + Row( + modifier = Modifier + .constrainAs(formatting) { + top.linkTo(parent.top) + bottom.linkTo(parent.bottom) + start.linkTo(close.end, margin = 3.dp) + end.linkTo(send.start, margin = 20.dp) + width = fillToConstraints + } + .horizontalScroll(scrollState), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + FormattingOption( + state = state.actions[ComposerAction.BOLD].toButtonState(), + onClick = { state.toggleInlineFormat(InlineFormat.Bold) }, + imageVector = ImageVector.vectorResource(VectorIcons.Bold), + contentDescription = stringResource(CommonStrings.rich_text_editor_format_bold) + ) + FormattingOption( + state = state.actions[ComposerAction.ITALIC].toButtonState(), + onClick = { state.toggleInlineFormat(InlineFormat.Italic) }, + imageVector = ImageVector.vectorResource(VectorIcons.Italic), + contentDescription = stringResource(CommonStrings.rich_text_editor_format_italic) + ) + FormattingOption( + state = state.actions[ComposerAction.UNDERLINE].toButtonState(), + onClick = { state.toggleInlineFormat(InlineFormat.Underline) }, + imageVector = ImageVector.vectorResource(VectorIcons.Underline), + contentDescription = stringResource(CommonStrings.rich_text_editor_format_underline) + ) + FormattingOption( + state = state.actions[ComposerAction.STRIKE_THROUGH].toButtonState(), + onClick = { state.toggleInlineFormat(InlineFormat.StrikeThrough) }, + imageVector = ImageVector.vectorResource(VectorIcons.Strikethrough), + contentDescription = stringResource(CommonStrings.rich_text_editor_format_strikethrough) + ) + FormattingOption( + state = state.actions[ComposerAction.UNORDERED_LIST].toButtonState(), + onClick = { state.toggleList(ordered = false) }, + imageVector = ImageVector.vectorResource(VectorIcons.BulletList), + contentDescription = stringResource(CommonStrings.rich_text_editor_bullet_list) + ) + FormattingOption( + state = state.actions[ComposerAction.ORDERED_LIST].toButtonState(), + onClick = { state.toggleList(ordered = true) }, + imageVector = ImageVector.vectorResource(VectorIcons.NumberedList), + contentDescription = stringResource(CommonStrings.rich_text_editor_numbered_list) + ) + FormattingOption( + state = state.actions[ComposerAction.INDENT].toButtonState(), + onClick = { state.indent() }, + imageVector = ImageVector.vectorResource(VectorIcons.IndentIncrease), + contentDescription = stringResource(CommonStrings.rich_text_editor_indent) + ) + FormattingOption( + state = state.actions[ComposerAction.UNINDENT].toButtonState(), + onClick = { state.unindent() }, + imageVector = ImageVector.vectorResource(VectorIcons.IndentDecrease), + contentDescription = stringResource(CommonStrings.rich_text_editor_unindent) + ) + FormattingOption( + state = state.actions[ComposerAction.INLINE_CODE].toButtonState(), + onClick = { state.toggleInlineFormat(InlineFormat.InlineCode) }, + imageVector = ImageVector.vectorResource(VectorIcons.InlineCode), + contentDescription = stringResource(CommonStrings.rich_text_editor_inline_code) + ) + FormattingOption( + state = state.actions[ComposerAction.CODE_BLOCK].toButtonState(), + onClick = { state.toggleCodeBlock() }, + imageVector = ImageVector.vectorResource(VectorIcons.CodeBlock), + contentDescription = stringResource(CommonStrings.rich_text_editor_code_block) + ) + FormattingOption( + state = state.actions[ComposerAction.QUOTE].toButtonState(), + onClick = { state.toggleQuote() }, + imageVector = ImageVector.vectorResource(VectorIcons.Quote), + contentDescription = stringResource(CommonStrings.rich_text_editor_quote) + ) + } + + sendButton( + Modifier.constrainAs(send) { + top.linkTo(parent.top) + bottom.linkTo(parent.bottom) + end.linkTo(parent.end) + }, + ) + } +} + +private fun ActionState?.toButtonState(): FormattingOptionState = + when (this) { + ActionState.ENABLED -> FormattingOptionState.Default + ActionState.REVERSED -> FormattingOptionState.Selected + ActionState.DISABLED, null -> FormattingOptionState.Disabled + } + @Composable private fun ComposerModeView( composerMode: MessageComposerMode, @@ -341,53 +551,17 @@ private fun ReplyToModeView( } @Composable -private fun AttachmentButton( - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - Surface( - modifier - .size(30.dp.applyScaleUp()) - .clickable(onClick = onClick), - shape = CircleShape, - color = ElementTheme.colors.iconPrimary - ) { - Image( - modifier = Modifier.size(12.5f.dp.applyScaleUp()), - painter = painterResource(R.drawable.ic_add_attachment), - contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), - contentScale = ContentScale.Inside, - colorFilter = ColorFilter.tint( - LocalContentColor.current - ) - ) - } -} - -@Composable -private fun BoxScope.SendButton( +private fun SendButton( canSendMessage: Boolean, onClick: () -> Unit, composerMode: MessageComposerMode, modifier: Modifier = Modifier, ) { - val interactionSource = remember { MutableInteractionSource() } - Box( + IconButton( modifier = modifier - .clip(CircleShape) - .background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent) - .size(30.dp.applyScaleUp()) - .align(Alignment.BottomEnd) - .applyIf(composerMode !is MessageComposerMode.Edit, ifTrue = { - padding(start = 1.dp.applyScaleUp()) // Center the arrow in the circle - }) - .clickable( - enabled = canSendMessage, - interactionSource = interactionSource, - indication = rememberRipple(bounded = false), - onClick = onClick, - ), - contentAlignment = Alignment.Center, + .size(48.dp.applyScaleUp()), + onClick = onClick, + enabled = canSendMessage, ) { val iconId = when (composerMode) { is MessageComposerMode.Edit -> R.drawable.ic_tick @@ -397,13 +571,22 @@ private fun BoxScope.SendButton( is MessageComposerMode.Edit -> stringResource(CommonStrings.action_edit) else -> stringResource(CommonStrings.action_send) } - Icon( - modifier = Modifier.size(16.dp.applyScaleUp()), - resourceId = iconId, - contentDescription = contentDescription, - // Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary - tint = if (canSendMessage) Color.White else ElementTheme.colors.iconDisabled - ) + Box( + modifier = Modifier + .clip(CircleShape) + .size(36.dp.applyScaleUp()) + .background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent) + ) { + Icon( + modifier = Modifier + .height(18.dp.applyScaleUp()) + .align(Alignment.Center), + resourceId = iconId, + contentDescription = contentDescription, + // Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary + tint = if (canSendMessage) Color.White else ElementTheme.colors.iconDisabled + ) + } } } @@ -447,6 +630,31 @@ internal fun TextComposerSimplePreview() = ElementPreview { } } +@DayNightPreviews +@Composable +internal fun TextComposerFormattingPreview() = ElementPreview { + Column { + TextComposer( + RichTextEditorState("", fake = true), + canSendMessage = false, + showTextFormatting = true, + composerMode = MessageComposerMode.Normal(""), + ) + TextComposer( + RichTextEditorState("A message", fake = true), + canSendMessage = true, + showTextFormatting = true, + composerMode = MessageComposerMode.Normal(""), + ) + TextComposer( + RichTextEditorState("A message\nWith several lines\nTo preview larger textfields and long lines with overflow", fake = true), + canSendMessage = true, + showTextFormatting = true, + composerMode = MessageComposerMode.Normal(""), + ) + } +} + @DayNightPreviews @Composable internal fun TextComposerEditPreview() = ElementPreview { diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt new file mode 100644 index 0000000000..7eb1d08293 --- /dev/null +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 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.libraries.textcomposer.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.text.applyScaleUp +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.theme.compound.generated.SemanticColors + +@Composable +internal fun FormattingOption( + state: FormattingOptionState, + onClick: () -> Unit, + imageVector: ImageVector, + contentDescription: String, + modifier: Modifier = Modifier, + colors: SemanticColors = ElementTheme.colors, +) { + val backgroundColor = when (state) { + FormattingOptionState.Selected -> colors.bgActionPrimaryRest + FormattingOptionState.Default, + FormattingOptionState.Disabled -> Color.Transparent + } + + val foregroundColor = when (state) { + FormattingOptionState.Selected -> colors.iconOnSolidPrimary + FormattingOptionState.Default -> colors.iconPrimary + FormattingOptionState.Disabled -> colors.iconDisabled + } + Box( + modifier = modifier + .clickable { onClick() } + .size(44.dp.applyScaleUp()) + .background(backgroundColor, shape = RoundedCornerShape(4.dp.applyScaleUp())) + ) { + Icon( + modifier = Modifier.align(Alignment.Center), + imageVector = imageVector, + contentDescription = contentDescription, + tint = foregroundColor, + ) + } +} + diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOptionState.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOptionState.kt new file mode 100644 index 0000000000..386fa5a668 --- /dev/null +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOptionState.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 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.libraries.textcomposer.components + +internal enum class FormattingOptionState { + Default, Selected, Disabled +} + diff --git a/libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml deleted file mode 100644 index ac9d53639b..0000000000 --- a/libraries/textcomposer/impl/src/main/res/drawable/ic_add_attachment.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/libraries/textcomposer/impl/src/main/res/drawable/ic_cancel.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_cancel.xml new file mode 100644 index 0000000000..5c27ba82d9 --- /dev/null +++ b/libraries/textcomposer/impl/src/main/res/drawable/ic_cancel.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/textcomposer/impl/src/main/res/drawable/ic_plus.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_plus.xml new file mode 100644 index 0000000000..ead38721dc --- /dev/null +++ b/libraries/textcomposer/impl/src/main/res/drawable/ic_plus.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml b/libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml index 64e0f120c4..bf346b3a01 100644 --- a/libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml +++ b/libraries/textcomposer/impl/src/main/res/drawable/ic_send.xml @@ -1,9 +1,9 @@ + android:width="21dp" + android:height="18dp" + android:viewportWidth="21" + android:viewportHeight="18"> + android:pathData="M20.252,10.085 L4.681,17.867c-1.049,0.525 -2.141,-0.601 -1.628,-1.627 0,0 1.93,-3.897 2.461,-4.918 0.531,-1.021 1.138,-1.197 6.781,-1.927 0.209,-0.027 0.38,-0.185 0.38,-0.395 0,-0.21 -0.171,-0.368 -0.38,-0.395C6.652,7.876 6.045,7.699 5.514,6.678 4.983,5.658 3.053,1.76 3.053,1.76 2.54,0.734 3.632,-0.391 4.681,0.133L20.252,7.915c0.894,0.446 0.894,1.723 0,2.17z" + android:fillColor="@android:color/white"/> diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-1_2_null,NEXUS_5,1.0,en].png index 58ebf07374..efcd596b40 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-1_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-1_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79aeef6875265e119c3b4b97cea4d36ba3354ae52c4b94b69bbc09461b7bc319 -size 22259 +oid sha256:e67b171ca09fd2efb25338a20fe7af7464e0e1ecb1b02afd679dbfc7cd3cd7df +size 25646 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-1_3_null,NEXUS_5,1.0,en].png index 6e91b56f10..a385dd8498 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-1_3_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-1_3_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dafa9a97ebc77f00fdb0432c7b94272f6ea1873c3475353be47ecde95e8b057 -size 20670 +oid sha256:e92e96cc117bf42ffb9fa282bcb9e40fd51c414e1d432862940c0f8fb6600fd0 +size 23453 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png index fa68f3bd24..ee0937d439 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4013454094701004f3c132df1ea1c3db2aa56a025b9edea80417fdd16fe55b19 -size 10422 +oid sha256:f3ea303577f655368800debe9c40e1292dc08a20da7f2ea6ddddb87f8407b112 +size 10431 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png index f6040d0e1a..e537e910e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db74b1655e377e4fd8c35aa18c22ef5f5641586b64d5e582ab2079afeac4b8c3 -size 10775 +oid sha256:b646c06e55b50b64eb7b566fbc0bcafa7f7e348398f87152d008a47e7448f4e0 +size 10736 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png index 2a10272dac..00cfa0d87e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfc6f54988e4fab08ff443f0c2ea285d47e3d030a8e6c92a1294ee0f85dc1269 -size 51967 +oid sha256:ba052f24e62aabc015da4b38bb893148c888a858a097669b2191e7880867e371 +size 52114 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png index 5cf07497cd..57d6580a12 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2ffd4fc93e7da38836fd860ce5e505c5f0c25fdd6558efef480aaeb05d00dd5 -size 53327 +oid sha256:4f8f7fd27e56aa2ca42053c249353836187467b99a9225c93c22f38365e63ccb +size 53285 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index 41f0170682..8a4f9bc201 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96864552336c65b464251c262f330856fc82c69a5f92f89b1357a185d654fccd -size 52252 +oid sha256:fbfc5593de6c7dda915b3a8bc881f0485b4b8400f52412547aa914862d1d8840 +size 52245 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index a022fb7675..6907cccce9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2411212e87f95415e0b4ed6732387922faed891cde5e78fa9f0691a185873129 -size 51026 +oid sha256:d56d5666d1d7749484f19c983e3cb2125110039c80e5898684e20b7e24a3e56b +size 51312 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png index 5fe74737cf..b2e621fc71 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:255560f478c093f4ca7d021646f4cf9064c16b420d5eeec7cbce97d26c751d92 -size 49540 +oid sha256:db0107e648e2acfc253d83f5e3b2f3e41de1abc9bdc4922dfd923ad4e50b8f5f +size 49700 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png index caf6d5a3da..1746cfeb84 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a384aa84ae514aa4989d4b4a5ef8048cb8810f1f37056137c77fd0ee798a0bab -size 53941 +oid sha256:398f4b1c7b21ab4c57802fb724d62b8c904f5a0c700eba507a811cb58881df49 +size 53896 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png index 93163a476e..69a8b67d95 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a48badf15c59ab5c42fc7cc200971f00cefa7838461ad0cb59537c2b4065bfff -size 55409 +oid sha256:2913fc7ee2c4b32e79e0d813ee8fa54e6d3f863466b798b8194462cbd9ef4fde +size 55137 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index 1ff65d3301..f8b59bb375 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88a498b9070653513b3e27aa2b597367ee85c8526c6e4c3712a4cb0c06e5313b -size 54353 +oid sha256:a20479945a552e2d3d3fb309c07ac7b9a66d4dfac0ad1ddf2c86c40fa0d34db9 +size 54175 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index be91f54717..367b0dc907 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf493a9cb7325b4f68924abd86864b37c72226afcf1c4179a06c17e923cfd0ae -size 55837 +oid sha256:1e7697c3f1eb995fc0bbf084853fce1cc10e841d0275d6ff4f2d857afd81b31d +size 56103 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png index 432e114fd5..cbdda6b794 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ac3dbf36380fa273d82ebe8836c525bbeee004d6348822d965b216f9bcdb920 -size 51335 +oid sha256:7e162503c27609f01e05bb2c634c2d3123abf6e786ecfe763c902d400ead050f +size 51283 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png deleted file mode 100644 index b1144213da..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-1_2_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce08e8c81d5494d2d803da43612a137df881e359646878b1d38cdfe77e0857ff -size 13829 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-2_3_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9d906ebe35 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-D-2_3_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46683edccf9c7686a07d7098c4387f296556ad2678381aad35efe2787cf6ad0a +size 14173 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 62264fcf27..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-1_3_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c2ba0ac13c81c707f0d00e3ff69737163dfc450a3d21aa468dd0b34deeeb7e1 -size 12916 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-2_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-2_4_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..4b9d77d2b1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerEdit-N-2_4_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6485de8235af05a9815a558b1af03b51e8c4b30ad0372aea0aa9fb2303525c9b +size 13286 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-D-1_2_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..760cf75800 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-D-1_2_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0e4c8da669ee5383a7d0f828a3300b923ec38ab5e04bc388da0e83f1cf1ccf3 +size 38291 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-N-1_3_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..0b9f9f3ab7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerFormatting-N-1_3_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f26aa7b13403cfaa864778a6ec5c26edde5932f3d887c7148d3a2b9f60f6e6a +size 36392 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 3e872eda82..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-2_3_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f15bc37e2a3d052e8d79e663f2c03223c27ddff3c02cd69f95a140c33fc6952c -size 79320 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..37e8a8561f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e65e15c721a939ed700719cacbdee57e1ccb89d984e88bdb5ed772c4b583472a +size 81494 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 8bd9e09c69..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-2_4_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6aa9b8849a2bbd7b487de6fee7fd355300091bc14d647973c4beea02e6009ac4 -size 76465 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..466f321959 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49f6d3b7f93008640abf30a5a65ddca6845e16343ef97c3450faf9dd6d9b9cec +size 78788 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png index 8afc6fc94a..d6beb7c22c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-D-0_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:501734b297cec566a008d3492690cf75b46ab68e662d2835a0b195fd0740c13f -size 42912 +oid sha256:2a998d3db9e4454fe74f31028b1dc61e4d6c07c824192f5e75563234dedf0b26 +size 44108 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png index de57e08951..863e8b8628 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerSimple-N-0_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff69ed7056380df3279a39b7544bc1887d2e455b43fb069b547e32cf5c92dc0f -size 40229 +oid sha256:97ab0a0b64ea7704a1557fc34b24d7caea34f9951948f5f5637f0bda596288dd +size 41455 From baebe419e745197daf81320eb221edcd4bcc1adb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 Sep 2023 13:12:46 +0000 Subject: [PATCH 090/127] Update dependency io.nlopez.compose.rules:detekt to v0.2.2 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index bd0f84177a..5c958fc397 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,7 +62,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.2.1") + detektPlugins("io.nlopez.compose.rules:detekt:0.2.2") } // KtLint From 33457e9c58f9c2309e0f5b69c3074cb17d81a2f9 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 11 Sep 2023 07:54:44 +0200 Subject: [PATCH 091/127] Make sure notification permission screen is dismissed (#1263) * Make sure notification permission screen is dismissed --- .../notifications/NotificationsOptInPresenter.kt | 16 ++++++++++++---- .../impl/notifications/NotificationsOptInView.kt | 7 ------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt index f7e4b6b26d..f3bffca590 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt @@ -20,6 +20,7 @@ import android.Manifest import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -56,15 +57,15 @@ class NotificationsOptInPresenter @AssistedInject constructor( @Composable override fun present(): NotificationsOptInState { - val notificationPremissionsState = postNotificationPermissionsPresenter.present() + val notificationsPermissionsState = postNotificationPermissionsPresenter.present() fun handleEvents(event: NotificationsOptInEvents) { when (event) { NotificationsOptInEvents.ContinueClicked -> { - if (notificationPremissionsState.permissionGranted) { + if (notificationsPermissionsState.permissionGranted) { callback.onNotificationsOptInFinished() } else { - notificationPremissionsState.eventSink(PermissionsEvents.OpenSystemDialog) + notificationsPermissionsState.eventSink(PermissionsEvents.OpenSystemDialog) } } NotificationsOptInEvents.NotNowClicked -> { @@ -76,8 +77,15 @@ class NotificationsOptInPresenter @AssistedInject constructor( } } + LaunchedEffect(notificationsPermissionsState) { + if (notificationsPermissionsState.permissionGranted + || notificationsPermissionsState.permissionAlreadyDenied) { + callback.onNotificationsOptInFinished() + } + } + return NotificationsOptInState( - notificationsPermissionState = notificationPremissionsState, + notificationsPermissionState = notificationsPermissionsState, eventSink = ::handleEvents ) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt index 73135cafdc..0b0676074b 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -32,7 +32,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Notifications import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -64,12 +63,6 @@ fun NotificationsOptInView( ) { BackHandler(onBack = onBack) - if (state.notificationsPermissionState.permissionAlreadyDenied) { - LaunchedEffect(Unit) { - state.eventSink(NotificationsOptInEvents.NotNowClicked) - } - } - HeaderFooterPage( modifier = modifier .systemBarsPadding() From 5059d67238f168a49ca2791e78425ebe2f431089 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Sep 2023 15:04:21 +0200 Subject: [PATCH 092/127] Iterate on tracing configuration - Add targets matrix_sdk, matrix_sdk::client and matrix_sdk::oidc - introduce default log level. --- .../tracing/TargetLogLevelMapBuilder.kt | 2 -- .../api/tracing/TracingFilterConfiguration.kt | 17 ++++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt index c70d573430..b851c15279 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt @@ -29,7 +29,6 @@ class TargetLogLevelMapBuilder @Inject constructor( fun getDefaultMap(): Map { return Target.entries.associateWith { target -> defaultConfig.getLogLevel(target) - ?: LogLevel.INFO } } @@ -37,7 +36,6 @@ class TargetLogLevelMapBuilder @Inject constructor( return Target.entries.associateWith { target -> tracingConfigurationStore.getLogLevel(target) ?: defaultConfig.getLogLevel(target) - ?: LogLevel.INFO } } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt index d34911644e..3062fa3aa3 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt @@ -19,27 +19,25 @@ package io.element.android.libraries.matrix.api.tracing data class TracingFilterConfiguration( val overrides: Map = emptyMap(), ) { + private val defaultLogLevel = LogLevel.INFO // Order should matters private val targetsToLogLevel: Map = mapOf( - Target.COMMON to LogLevel.INFO, Target.HYPER to LogLevel.WARN, Target.MATRIX_SDK_CRYPTO to LogLevel.DEBUG, Target.MATRIX_SDK_HTTP_CLIENT to LogLevel.DEBUG, Target.MATRIX_SDK_SLIDING_SYNC to LogLevel.TRACE, Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.TRACE, - Target.MATRIX_SDK_UI_TIMELINE to LogLevel.INFO, ) - fun getLogLevel(target: Target): LogLevel? { - return overrides[target] ?: targetsToLogLevel[target] + fun getLogLevel(target: Target): LogLevel { + return overrides[target] ?: targetsToLogLevel[target] ?: defaultLogLevel } val filter: String get() { - val fullMap = targetsToLogLevel.toMutableMap() - overrides.forEach { (target, logLevel) -> - fullMap[target] = logLevel + val fullMap = Target.values().associateWith { + overrides[it] ?: targetsToLogLevel[it] ?: defaultLogLevel } return fullMap.map { if (it.key.filter.isEmpty()) { @@ -58,7 +56,10 @@ enum class Target(open val filter: String) { MATRIX_SDK_FFI("matrix_sdk_ffi"), MATRIX_SDK_UNIFFI_API("matrix_sdk_ffi::uniffi_api"), MATRIX_SDK_CRYPTO("matrix_sdk_crypto"), + MATRIX_SDK("matrix_sdk"), MATRIX_SDK_HTTP_CLIENT("matrix_sdk::http_client"), + MATRIX_SDK_CLIENT("matrix_sdk::client"), + MATRIX_SDK_OIDC("matrix_sdk::oidc"), MATRIX_SDK_SLIDING_SYNC("matrix_sdk::sliding_sync"), MATRIX_SDK_BASE_SLIDING_SYNC("matrix_sdk_base::sliding_sync"), MATRIX_SDK_UI_TIMELINE("matrix_sdk_ui::timeline"), @@ -75,13 +76,11 @@ enum class LogLevel(open val filter: String) { object TracingFilterConfigurations { val release = TracingFilterConfiguration( overrides = mapOf( - Target.COMMON to LogLevel.INFO, Target.ELEMENT to LogLevel.DEBUG ), ) val debug = TracingFilterConfiguration( overrides = mapOf( - Target.COMMON to LogLevel.INFO, Target.ELEMENT to LogLevel.TRACE ) ) From 9f02de45b864a15d542deaa61cb1fb09674a0fba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 09:17:50 +0200 Subject: [PATCH 093/127] setenv "RUST_BACKTRACE" to "1" to get more info when a Rust stacktrace is printed out. --- .../io/element/android/x/initializer/TracingInitializer.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt index 7b93812d35..853412e403 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt @@ -17,6 +17,7 @@ package io.element.android.x.initializer import android.content.Context +import android.system.Os import androidx.preference.PreferenceManager import androidx.startup.Initializer import io.element.android.features.preferences.impl.developer.tracing.SharedPrefTracingConfigurationStore @@ -57,6 +58,8 @@ class TracingInitializer : Initializer { } bugReporter.cleanLogDirectoryIfNeeded() tracingService.setupTracing(tracingConfiguration) + // Also set env variable for rust back trace + Os.setenv("RUST_BACKTRACE", "1", true) } override fun dependencies(): List>> = mutableListOf() From a30af97ecd8dd9a6de160948f2bf79cd5838f83e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 09:57:45 +0200 Subject: [PATCH 094/127] Add ConfigureTracingEntryPoint to be able to access the screen from outside the Preference screen. --- .../api/ConfigureTracingEntryPoint.kt | 21 ++++++++++++ .../impl/DefaultConfigureTracingEntryPoint.kt | 33 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt diff --git a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt new file mode 100644 index 0000000000..803c0c9232 --- /dev/null +++ b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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.features.preferences.api + +import io.element.android.libraries.architecture.SimpleFeatureEntryPoint + +interface ConfigureTracingEntryPoint : SimpleFeatureEntryPoint diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt new file mode 100644 index 0000000000..372acbd1f4 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 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.features.preferences.impl + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.features.preferences.api.ConfigureTracingEntryPoint +import io.element.android.features.preferences.impl.developer.tracing.ConfigureTracingNode +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.AppScope +import javax.inject.Inject + +@ContributesBinding(AppScope::class) +class DefaultConfigureTracingEntryPoint @Inject constructor() : ConfigureTracingEntryPoint { + override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + return parentNode.createNode(buildContext) + } +} From 9c9a6ce7be5388c8299f2d5b1c3dd0995094d3cc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 09:58:40 +0200 Subject: [PATCH 095/127] Add a way to configure tracing when the session does not exist yet. --- .../android/appnav/NotLoggedInFlowNode.kt | 12 ++++++ .../onboarding/api/OnBoardingEntryPoint.kt | 1 + .../onboarding/impl/OnBoardingNode.kt | 6 +++ .../onboarding/impl/OnBoardingPresenter.kt | 4 ++ .../onboarding/impl/OnBoardingState.kt | 1 + .../impl/OnBoardingStateProvider.kt | 3 ++ .../onboarding/impl/OnBoardingView.kt | 41 ++++++++++++++++--- 7 files changed, 62 insertions(+), 6 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt index 17f3a44eb8..6c22644658 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt @@ -32,6 +32,7 @@ import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.onboarding.api.OnBoardingEntryPoint +import io.element.android.features.preferences.api.ConfigureTracingEntryPoint import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.di.AppScope @@ -43,6 +44,7 @@ class NotLoggedInFlowNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, private val onBoardingEntryPoint: OnBoardingEntryPoint, + private val configureTracingEntryPoint: ConfigureTracingEntryPoint, private val loginEntryPoint: LoginEntryPoint, private val notLoggedInImageLoaderFactory: NotLoggedInImageLoaderFactory, ) : BackstackNode( @@ -70,6 +72,9 @@ class NotLoggedInFlowNode @AssistedInject constructor( data class LoginFlow( val isAccountCreation: Boolean, ) : NavTarget + + @Parcelize + data object ConfigureTracing : NavTarget } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -83,6 +88,10 @@ class NotLoggedInFlowNode @AssistedInject constructor( override fun onSignIn() { backstack.push(NavTarget.LoginFlow(isAccountCreation = false)) } + + override fun onOpenDeveloperSettings() { + backstack.push(NavTarget.ConfigureTracing) + } } onBoardingEntryPoint .nodeBuilder(this, buildContext) @@ -94,6 +103,9 @@ class NotLoggedInFlowNode @AssistedInject constructor( .params(LoginEntryPoint.Params(isAccountCreation = navTarget.isAccountCreation)) .build() } + NavTarget.ConfigureTracing -> { + configureTracingEntryPoint.createNode(this, buildContext) + } } } diff --git a/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt b/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt index 7be45ce236..d183b05386 100644 --- a/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt +++ b/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt @@ -33,5 +33,6 @@ interface OnBoardingEntryPoint : FeatureEntryPoint { interface Callback : Plugin { fun onSignUp() fun onSignIn() + fun onOpenDeveloperSettings() } } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt index d86623cae2..21322657c1 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt @@ -46,6 +46,10 @@ class OnBoardingNode @AssistedInject constructor( plugins().forEach { it.onSignUp() } } + private fun onOpenDeveloperSettings() { + plugins().forEach { it.onOpenDeveloperSettings() } + } + @Composable override fun View(modifier: Modifier) { val state = presenter.present() @@ -54,6 +58,8 @@ class OnBoardingNode @AssistedInject constructor( modifier = modifier, onSignIn = ::onSignIn, onCreateAccount = ::onSignUp, + onSignInWithQrCode = { /* Not supported yet */ }, + onOpenDeveloperSettings = ::onOpenDeveloperSettings, ) } } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt index 48a360e6c9..b26752fdbe 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt @@ -18,6 +18,8 @@ package io.element.android.features.onboarding.impl import androidx.compose.runtime.Composable import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.core.meta.BuildType import javax.inject.Inject /** @@ -25,10 +27,12 @@ import javax.inject.Inject * When this presenter get more code in it, please remove the ignore rule in the kover configuration. */ class OnBoardingPresenter @Inject constructor( + private val buildMeta: BuildMeta, ) : Presenter { @Composable override fun present(): OnBoardingState { return OnBoardingState( + isDebugBuild = buildMeta.buildType != BuildType.RELEASE, canLoginWithQrCode = OnBoardingConfig.canLoginWithQrCode, canCreateAccount = OnBoardingConfig.canCreateAccount, ) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt index 88215c0c1e..5bd7718033 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt @@ -17,6 +17,7 @@ package io.element.android.features.onboarding.impl data class OnBoardingState( + val isDebugBuild: Boolean, val canLoginWithQrCode: Boolean, val canCreateAccount: Boolean, ) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt index 1c60a56018..926d2a2303 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt @@ -25,13 +25,16 @@ open class OnBoardingStateProvider : PreviewParameterProvider { anOnBoardingState(canLoginWithQrCode = true), anOnBoardingState(canCreateAccount = true), anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true), + anOnBoardingState(isDebugBuild = true), ) } fun anOnBoardingState( + isDebugBuild: Boolean = false, canLoginWithQrCode: Boolean = false, canCreateAccount: Boolean = false ) = OnBoardingState( + isDebugBuild = isDebugBuild, canLoginWithQrCode = canLoginWithQrCode, canCreateAccount = canCreateAccount ) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt index 1adfe6bd93..875b79d8f2 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt @@ -25,7 +25,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.QrCode +import androidx.compose.material.icons.filled.Settings import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.BiasAlignment import androidx.compose.ui.Modifier @@ -41,6 +43,8 @@ import io.element.android.libraries.designsystem.atomic.pages.OnBoardingPage import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.OutlinedButton import io.element.android.libraries.designsystem.theme.components.Text @@ -58,14 +62,18 @@ import io.element.android.libraries.ui.strings.CommonStrings fun OnBoardingView( state: OnBoardingState, modifier: Modifier = Modifier, - onSignInWithQrCode: () -> Unit = {}, - onSignIn: () -> Unit = {}, - onCreateAccount: () -> Unit = {}, + onSignInWithQrCode: () -> Unit, + onSignIn: () -> Unit, + onCreateAccount: () -> Unit, + onOpenDeveloperSettings: () -> Unit, ) { OnBoardingPage( modifier = modifier, content = { - OnBoardingContent() + OnBoardingContent( + state = state, + onOpenDeveloperSettings = onOpenDeveloperSettings + ) }, footer = { OnBoardingButtons( @@ -79,7 +87,11 @@ fun OnBoardingView( } @Composable -private fun OnBoardingContent(modifier: Modifier = Modifier) { +private fun OnBoardingContent( + state: OnBoardingState, + onOpenDeveloperSettings: () -> Unit, + modifier: Modifier = Modifier +) { Box( modifier = modifier.fillMaxSize(), ) { @@ -122,6 +134,17 @@ private fun OnBoardingContent(modifier: Modifier = Modifier) { ) } } + if (state.isDebugBuild) { + IconButton( + modifier = Modifier.align(Alignment.TopEnd), + onClick = onOpenDeveloperSettings, + ) { + Icon( + imageVector = Icons.Filled.Settings, + contentDescription = stringResource(CommonStrings.common_settings) + ) + } + } } } @@ -172,5 +195,11 @@ private fun OnBoardingButtons( internal fun OnBoardingScreenPreview( @PreviewParameter(OnBoardingStateProvider::class) state: OnBoardingState ) = ElementPreview { - OnBoardingView(state) + OnBoardingView( + state = state, + onSignInWithQrCode = {}, + onSignIn = {}, + onCreateAccount = {}, + onOpenDeveloperSettings = {} + ) } From eb4fc1d3000d120db1b0db5e031c778624e318a6 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 11 Sep 2023 08:08:27 +0000 Subject: [PATCH 096/127] Update screenshots --- ...impl_null_OnBoardingScreen-D-0_0_null_4,NEXUS_5,1.0,en].png | 3 +++ ...impl_null_OnBoardingScreen-N-0_1_null_4,NEXUS_5,1.0,en].png | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-D-0_0_null_4,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-N-0_1_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-D-0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-D-0_0_null_4,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..63eb2c9cdc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-D-0_0_null_4,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2c67243e8def6f8d188eb918b0dbd57dec3aae03fe8fca90ef5529658de537b +size 327304 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-N-0_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-N-0_1_null_4,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..cfc1433bcd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.onboarding.impl_null_OnBoardingScreen-N-0_1_null_4,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84e5641cce0113690d0d626bd3b17e8945728b3835a06b06a645418d12a05022 +size 421112 From ac5acd4949c2d970bd2f91ab77fec6030b9fbc25 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 10:40:49 +0200 Subject: [PATCH 097/127] Reorder params. --- .../element/android/features/onboarding/impl/OnBoardingView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt index 875b79d8f2..424c24839a 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt @@ -61,11 +61,11 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun OnBoardingView( state: OnBoardingState, - modifier: Modifier = Modifier, onSignInWithQrCode: () -> Unit, onSignIn: () -> Unit, onCreateAccount: () -> Unit, onOpenDeveloperSettings: () -> Unit, + modifier: Modifier = Modifier, ) { OnBoardingPage( modifier = modifier, From c73d41e7680b4f08cf7153ba260dca753b97c331 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 13:16:17 +0200 Subject: [PATCH 098/127] Add warning about issue on alpha07 --- gradle/libs.versions.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6d415faf59..c59d7359a6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -93,6 +93,8 @@ androidx_startup = { module = "androidx.startup:startup-runtime", version.ref = androidx_preference = "androidx.preference:preference:1.2.1" androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" } +# Warning: issue on alpha07, make sure this is working when upgrading +# Context in https://github.com/vector-im/element-x-android/pull/1239#issuecomment-1711500332 androidx_compose_material3 = "androidx.compose.material3:material3:1.2.0-alpha06" # Coroutines From 046453170c2cf3c0b9198033667f9164ee677f04 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Sep 2023 22:56:01 +0200 Subject: [PATCH 099/127] Add @OptIn(ExperimentalCoroutinesApi::class) Fix warning on runCurrent() --- .../ftue/impl/notifications/NotificationsOptInPresenterTests.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt index 0c55992367..74a867a0fc 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTests.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.permissions.impl.FakePermissionStateProvider import io.element.android.libraries.permissions.test.FakePermissionsPresenter import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider import io.element.android.tests.testutils.WarmUpRule +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.StandardTestDispatcher @@ -99,6 +100,7 @@ class NotificationsOptInPresenterTests { } } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun `set permission denied on not now clicked in API 33`() = runTest(StandardTestDispatcher()) { val permissionPresenter = FakePermissionsPresenter() From 3201358cb5fb35b44ce85af64c06a4c68beb35e0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 09:43:53 +0200 Subject: [PATCH 100/127] Fix preview 3 of AddPeopleView. --- .../impl/addpeople/AddPeopleUserListStateProvider.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt index 48ad56caf4..79969eeac7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt @@ -23,6 +23,7 @@ import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers import io.element.android.features.createroom.impl.userlist.aUserListState import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.libraries.usersearch.api.UserSearchResult import kotlinx.collections.immutable.toImmutableList open class AddPeopleUserListStateProvider : PreviewParameterProvider { @@ -36,7 +37,11 @@ open class AddPeopleUserListStateProvider : PreviewParameterProvider + UserSearchResult(matrixUser, index % 2 == 0) + } + .toImmutableList()), selectedUsers = aListOfSelectedUsers(), isSearchActive = true, selectionMode = SelectionMode.Multiple, From 5d89647a899dbb05f0dca7c6f79ef98b5537d966 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 13:35:46 +0200 Subject: [PATCH 101/127] Apply avatar colors to all the avatars across the app. --- .../designsystem/components/avatar/Avatar.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 958f4ca29e..ce39be4df7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -26,7 +26,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter @@ -34,6 +33,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.colors.avatarColors import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar @@ -53,9 +53,10 @@ fun Avatar( .size(avatarData.size.dp) .clip(CircleShape) if (avatarData.url.isNullOrBlank()) { + val avatarColors = initialAvatarColors ?: avatarColors(avatarData.id) InitialsAvatar( avatarData = avatarData, - avatarColors = initialAvatarColors, + avatarColors = avatarColors, modifier = commonModifier, ) } else { @@ -88,13 +89,11 @@ private fun ImageAvatar( @Composable private fun InitialsAvatar( avatarData: AvatarData, - avatarColors: AvatarColors?, + avatarColors: AvatarColors, modifier: Modifier = Modifier, ) { - // Use temporary color for default avatar background, if avatarColors is not provided - val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled Box( - modifier.background(color = avatarColors?.background ?: avatarColor) + modifier.background(color = avatarColors.background) ) { val fontSize = avatarData.size.dp.toSp() / 2 val originalFont = ElementTheme.typography.fontHeadingMdBold @@ -104,7 +103,7 @@ private fun InitialsAvatar( modifier = Modifier.align(Alignment.Center), text = avatarData.initial, style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), - color = avatarColors?.foreground ?: Color.White, + color = avatarColors.foreground, ) } } From f8b630ecb2ee426d46020e678d58466728cf111c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 13:51:46 +0200 Subject: [PATCH 102/127] Implement a in-memory cache for user avatar colors. --- .../notifications/NotificationsOptInView.kt | 8 ++-- .../components/TimelineItemEventRow.kt | 4 +- .../designsystem/colors/AvatarColors.kt | 44 +++++++++++++------ .../designsystem/components/avatar/Avatar.kt | 4 +- .../components/avatar/UserAvatarPreview.kt | 5 ++- 5 files changed, 42 insertions(+), 23 deletions(-) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt index 0b0676074b..cc467585cb 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -43,7 +43,7 @@ import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMo import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.colors.AvatarColors -import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -119,21 +119,21 @@ private fun NotificationsOptInContent( ) { NotificationRow( avatarLetter = "M", - avatarColors = avatarColors("5"), + avatarColors = AvatarColorsProvider.provide("5", ElementTheme.isLightTheme), firstRowPercent = 1f, secondRowPercent = 0.4f ) NotificationRow( avatarLetter = "A", - avatarColors = avatarColors("1"), + avatarColors = AvatarColorsProvider.provide("1", ElementTheme.isLightTheme), firstRowPercent = 1f, secondRowPercent = 1f ) NotificationRow( avatarLetter = "T", - avatarColors = avatarColors("4"), + avatarColors = AvatarColorsProvider.provide("4", ElementTheme.isLightTheme), firstRowPercent = 0.65f, secondRowPercent = 0f ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 30478c6ef0..d62513f95f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -75,7 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent -import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -328,7 +328,7 @@ private fun MessageSenderInformation( ) { val avatarStrokeColor = MaterialTheme.colorScheme.background val avatarSize = senderAvatar.size.dp - val avatarColors = avatarColors(senderAvatar.id) + val avatarColors = AvatarColorsProvider.provide(senderAvatar.id, ElementTheme.isLightTheme) Box( modifier = modifier ) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index fb379c751e..c12be3b37d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -16,9 +16,8 @@ package io.element.android.libraries.designsystem.colors -import androidx.compose.runtime.Composable +import androidx.collection.LruCache import androidx.compose.ui.graphics.Color -import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsDark import io.element.android.libraries.theme.colors.avatarColorsLight @@ -27,18 +26,37 @@ data class AvatarColors( val foreground: Color, ) -@Composable -fun avatarColors(userId: String): AvatarColors { - val hash = userId.toHash() - val colors = if (ElementTheme.isLightTheme) { - avatarColorsLight[hash] - } else { - avatarColorsDark[hash] +object AvatarColorsProvider { + private val cache = LruCache(200) + private var currentThemeIsLight = true + + fun provide(id: String, isLightTheme: Boolean): AvatarColors { + if (currentThemeIsLight != isLightTheme) { + currentThemeIsLight = isLightTheme + cache.evictAll() + } + val valueFromCache = cache.get(id) + return if (valueFromCache != null) { + valueFromCache + } else { + val colors = avatarColors(id, isLightTheme) + cache.put(id, colors) + colors + } + } + + private fun avatarColors(id: String, isLightTheme: Boolean): AvatarColors { + val hash = id.toHash() + val colors = if (isLightTheme) { + avatarColorsLight[hash] + } else { + avatarColorsDark[hash] + } + return AvatarColors( + background = colors.first, + foreground = colors.second, + ) } - return AvatarColors( - background = colors.first, - foreground = colors.second, - ) } internal fun String.toHash(): Int { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index ce39be4df7..a0349931fe 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -33,7 +33,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import io.element.android.libraries.designsystem.colors.AvatarColors -import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar @@ -53,7 +53,7 @@ fun Avatar( .size(avatarData.size.dp) .clip(CircleShape) if (avatarData.url.isNullOrBlank()) { - val avatarColors = initialAvatarColors ?: avatarColors(avatarData.id) + val avatarColors = initialAvatarColors ?: AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) InitialsAvatar( avatarData = avatarData, avatarColors = avatarColors, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt index 817650ffa7..2cfd820420 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -24,10 +24,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsLight @DayNightPreviews @@ -43,7 +44,7 @@ internal fun UserAvatarPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(), initialAvatarColors = avatarColors("$it")) + Avatar(anAvatarData(), initialAvatarColors = AvatarColorsProvider.provide("$it", ElementTheme.isLightTheme)) Text(text = "Color index $it") } } From 72497b584d989e6521eb45226f6c15b9b0f87f05 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 13:59:03 +0200 Subject: [PATCH 103/127] Now that we use a cache, there is no need to provide AvatarColors to the Avatar composable. --- .../notifications/NotificationsOptInView.kt | 18 ++++++++---------- .../components/TimelineItemEventRow.kt | 2 +- .../designsystem/components/avatar/Avatar.kt | 6 +----- .../components/avatar/UserAvatarPreview.kt | 4 +--- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt index cc467585cb..d22d6ab6ff 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -42,8 +42,6 @@ import io.element.android.features.ftue.impl.R import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage -import io.element.android.libraries.designsystem.colors.AvatarColors -import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -67,7 +65,7 @@ fun NotificationsOptInView( modifier = modifier .systemBarsPadding() .fillMaxSize(), - header = { NotificationsOptInHeader(modifier = Modifier.padding(top = 60.dp, bottom = 12.dp),) }, + header = { NotificationsOptInHeader(modifier = Modifier.padding(top = 60.dp, bottom = 12.dp)) }, footer = { NotificationsOptInFooter(state) }, ) { NotificationsOptInContent(modifier = Modifier.fillMaxWidth()) @@ -119,21 +117,21 @@ private fun NotificationsOptInContent( ) { NotificationRow( avatarLetter = "M", - avatarColors = AvatarColorsProvider.provide("5", ElementTheme.isLightTheme), + avatarColorsId = "5", firstRowPercent = 1f, secondRowPercent = 0.4f ) NotificationRow( avatarLetter = "A", - avatarColors = AvatarColorsProvider.provide("1", ElementTheme.isLightTheme), + avatarColorsId = "1", firstRowPercent = 1f, secondRowPercent = 1f ) NotificationRow( avatarLetter = "T", - avatarColors = AvatarColorsProvider.provide("4", ElementTheme.isLightTheme), + avatarColorsId = "4", firstRowPercent = 0.65f, secondRowPercent = 0f ) @@ -144,7 +142,7 @@ private fun NotificationsOptInContent( @Composable private fun NotificationRow( avatarLetter: String, - avatarColors: AvatarColors, + avatarColorsId: String, firstRowPercent: Float, secondRowPercent: Float, modifier: Modifier = Modifier @@ -161,8 +159,7 @@ private fun NotificationRow( verticalAlignment = Alignment.CenterVertically ) { Avatar( - avatarData = AvatarData(id = "", name = avatarLetter, size = AvatarSize.NotificationsOptIn), - initialAvatarColors = avatarColors, + avatarData = AvatarData(id = avatarColorsId, name = avatarLetter, size = AvatarSize.NotificationsOptIn), ) Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(12.dp)) { Box( @@ -174,7 +171,8 @@ private fun NotificationRow( ) if (secondRowPercent > 0f) { Box( - modifier = Modifier.clip(CircleShape) + modifier = Modifier + .clip(CircleShape) .fillMaxWidth(secondRowPercent) .height(10.dp) .background(ElementTheme.colors.borderInteractiveSecondary) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index d62513f95f..7e21ff649d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -346,7 +346,7 @@ private fun MessageSenderInformation( } // Content Row { - Avatar(senderAvatar, initialAvatarColors = avatarColors) + Avatar(senderAvatar) Spacer(modifier = Modifier.width(4.dp)) Text( text = sender, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index a0349931fe..4ce4aa8f14 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage -import io.element.android.libraries.designsystem.colors.AvatarColors import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup @@ -46,17 +45,14 @@ import timber.log.Timber fun Avatar( avatarData: AvatarData, modifier: Modifier = Modifier, - initialAvatarColors: AvatarColors? = null, contentDescription: String? = null, ) { val commonModifier = modifier .size(avatarData.size.dp) .clip(CircleShape) if (avatarData.url.isNullOrBlank()) { - val avatarColors = initialAvatarColors ?: AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) InitialsAvatar( avatarData = avatarData, - avatarColors = avatarColors, modifier = commonModifier, ) } else { @@ -89,9 +85,9 @@ private fun ImageAvatar( @Composable private fun InitialsAvatar( avatarData: AvatarData, - avatarColors: AvatarColors, modifier: Modifier = Modifier, ) { + val avatarColors = AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) Box( modifier.background(color = avatarColors.background) ) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt index 2cfd820420..ab1ec70db4 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsLight @DayNightPreviews @@ -44,7 +42,7 @@ internal fun UserAvatarPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(), initialAvatarColors = AvatarColorsProvider.provide("$it", ElementTheme.isLightTheme)) + Avatar(anAvatarData(id = "$it")) Text(text = "Color index $it") } } From 4e40d694e76bbbf906a5174932eee56da5f00445 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Sep 2023 14:53:46 +0200 Subject: [PATCH 104/127] Move class AvatarColorsProvider to its own file. --- .../designsystem/colors/AvatarColors.kt | 40 ------------- .../colors/AvatarColorsProvider.kt | 58 +++++++++++++++++++ 2 files changed, 58 insertions(+), 40 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsProvider.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index c12be3b37d..abac299ca6 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -16,50 +16,10 @@ package io.element.android.libraries.designsystem.colors -import androidx.collection.LruCache import androidx.compose.ui.graphics.Color -import io.element.android.libraries.theme.colors.avatarColorsDark -import io.element.android.libraries.theme.colors.avatarColorsLight data class AvatarColors( val background: Color, val foreground: Color, ) -object AvatarColorsProvider { - private val cache = LruCache(200) - private var currentThemeIsLight = true - - fun provide(id: String, isLightTheme: Boolean): AvatarColors { - if (currentThemeIsLight != isLightTheme) { - currentThemeIsLight = isLightTheme - cache.evictAll() - } - val valueFromCache = cache.get(id) - return if (valueFromCache != null) { - valueFromCache - } else { - val colors = avatarColors(id, isLightTheme) - cache.put(id, colors) - colors - } - } - - private fun avatarColors(id: String, isLightTheme: Boolean): AvatarColors { - val hash = id.toHash() - val colors = if (isLightTheme) { - avatarColorsLight[hash] - } else { - avatarColorsDark[hash] - } - return AvatarColors( - background = colors.first, - foreground = colors.second, - ) - } -} - -internal fun String.toHash(): Int { - return toList().sumOf { it.code } % avatarColorsLight.size -} - diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsProvider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsProvider.kt new file mode 100644 index 0000000000..bf195e8160 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsProvider.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 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.libraries.designsystem.colors + +import androidx.collection.LruCache +import io.element.android.libraries.theme.colors.avatarColorsDark +import io.element.android.libraries.theme.colors.avatarColorsLight + +object AvatarColorsProvider { + private val cache = LruCache(200) + private var currentThemeIsLight = true + + fun provide(id: String, isLightTheme: Boolean): AvatarColors { + if (currentThemeIsLight != isLightTheme) { + currentThemeIsLight = isLightTheme + cache.evictAll() + } + val valueFromCache = cache.get(id) + return if (valueFromCache != null) { + valueFromCache + } else { + val colors = avatarColors(id, isLightTheme) + cache.put(id, colors) + colors + } + } + + private fun avatarColors(id: String, isLightTheme: Boolean): AvatarColors { + val hash = id.toHash() + val colors = if (isLightTheme) { + avatarColorsLight[hash] + } else { + avatarColorsDark[hash] + } + return AvatarColors( + background = colors.first, + foreground = colors.second, + ) + } +} + +internal fun String.toHash(): Int { + return toList().sumOf { it.code } % avatarColorsLight.size +} From b2dcd4c4677d6ddaa2d124e76c99a5bb047ff7fd Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 11 Sep 2023 09:08:37 +0000 Subject: [PATCH 105/127] Update screenshots --- ...people_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...people_null_AddPeopleViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...eople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...eople_null_AddPeopleViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...l_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ponents_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...om_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...m_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...mmary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...mmary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...es.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...s.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ll_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ll_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...l_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...l_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ser_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ser_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...te_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...e_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...mbers_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...mbers_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...bers_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...bers_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png | 4 ++-- ....impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png | 4 ++-- ..._null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...list.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...oomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...st.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...t.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png | 4 ++-- ...s.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...ts.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png | 4 ++-- ...ll_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ll_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...l_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...l_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...onents_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...nents_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...omponents_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...omponents_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ents_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...nts_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mponents_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png | 4 ++-- 207 files changed, 414 insertions(+), 414 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png index 9031993cc7..f0232ef1fc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff5cb940c05656ed7debf230c7c2d780395e30f20c5d3da3abef136afb5359fe -size 28541 +oid sha256:2dc520372ac1b4ae340a1e75e0a1f4cc65f54c9e9ebf44c750309018613fa5d4 +size 28865 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_2,NEXUS_5,1.0,en].png index fae8a6fca3..dffeee671e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c89ac73df77c2bccb0c2aa80cee1420f78e7d07f0eda89a90bffef55e8cf753 -size 4464 +oid sha256:7bf3e51b483ca9600d9f589721bdfe93e0977ebcfe59ff66484fcbd7cfb12e20 +size 81101 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png index d65aa5499e..439ea49b7b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:edf63c7ae4b058c94cd611948f2bb3c3304c2646af0200e08f7b480f1ba965d8 -size 29245 +oid sha256:f8b78908805bb8745613be2f9fad2c1c4fd0d6087dce7f9b301b4fe3dc485d19 +size 30273 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_2,NEXUS_5,1.0,en].png index 665c8811ac..75c9154caf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.addpeople_null_AddPeopleViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb0d3bfcfd75cbd75fd9270ff1dc27090e5dbac79ca8db8a46d91a4c12bc966b -size 4457 +oid sha256:25b86e5211512c4a676cb142b847455ba34c13eb3712f75a22c8b313ca725eeb +size 83750 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png index b027f127c4..19e170130f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchMultipleUsersResultItem_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fe351b3d0b78473fdab1d4bc806468485939734e46cb3fa6d9f9058513d4dba -size 86421 +oid sha256:b051a4492303db0e5a1343269cb57301939105ab4c062db67326edb699a02d0f +size 86337 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png index 0f8dfab3d3..037a2c9e40 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_SearchSingleUserResultItem_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9dbfb671a112ae3bab099db959b30dcd4185d48bd365f63373da62971df51e00 -size 45246 +oid sha256:88608834541e31673c52014cc56072953f1ff1814bb3f89852822ebc6f762188 +size 45269 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png index 1b3c77ebaa..b87255406a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:137a71939d978e2f10d94d49faed208c54a5fa82b32d9ba2b47a3946641d361f -size 25688 +oid sha256:dda8e627414be70d99e5d7055fe32cb4d31014e5b55fb6fce326f90eb210a32f +size 26147 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png index ee833eae85..fd718e2025 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb84e5f7f23db39d8d2d162f0d55d8129ae88e984dcde816c86682981226bf4f -size 64074 +oid sha256:c67a25ba48fdd4edc640f848712427656299cfd397a24805e6ebb89da533e1d9 +size 63838 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png index 1a18f078da..3bb77b278a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eeeb724c3797679434f580261071602e2b8991b466e0e47806c7d7b0e4e4be2a -size 67838 +oid sha256:67861c2fc225ca366c3c2206fcee0d59f77b232eedd29b1bce9ed630af002ea0 +size 68143 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png index ed8846c5f4..85cb7efca2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2044763a0297a9d89c2a4ebb7fbd3ba967a5ac99a28375aeccf4766bc1a3be3 -size 25762 +oid sha256:7c01cba121aac57126e79becb6b5d2de7c3bee0f50418f9c17ab9228156c2030 +size 26274 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png index b014ceeaa4..09e93acea2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:675584b016f10890e13008152ade861de50b3463de9a253353f0d1af4f57c200 -size 65789 +oid sha256:663b97daf508ebb9e619c1a6a14c5ea005b93bf004ed6ef7c08a202284b87e33 +size 64676 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png index 3160672512..dc6259ef33 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_null_UserListViewLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:708d5201ded559e388a453d0df87d97aa7068f4892d6acb8a3bf50497a6754eb -size 69831 +oid sha256:e85d3ebafb87a593fa8977f9def17c8f45f9e067e02fe05c48b3f9650835a000 +size 69456 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png index aebe6c0c19..6e3c656d80 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7816a99e6460155c0d4c8f74fec6b2f09ec724f3442f5b1e77b45e98b5d43be1 -size 83585 +oid sha256:a88f6e1fdc1b3cd26f21a94866d0348e458509c5ce129c86c69b2673c7dc75f1 +size 84357 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png index 2b4f8e8e26..80d8dc14fd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.configureroom_null_ConfigureRoomViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec1b567e5175c9e83aee05623270f2f2d5497c901438042075a2b57a1284a368 -size 87153 +oid sha256:e116827aaa9d30b356088805bf6a820cce3ba42c49e6ffca2460aab1a4cdc8ba +size 87872 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png index 11393a5279..20ea3618e0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a59a7d481cdcc7b3fa216bc3ec4a20195730d27fe518a6610d9a61fb4a3b347f -size 20753 +oid sha256:8f04a88c84cb7e4e6d0f487b47aaf5e80c9ae1472ab25bf5412e084c356d4bbe +size 20765 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png index 786c163f1e..d8fa732c18 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22ac66742c1e14c8f9ddf8f56f86fd155f6f8d3adfc90483772f4f78c71fe81c -size 27063 +oid sha256:b85cf6982f409276e1bedc1a06322ecefef8ea86d4e5459a39d607fe10f5d08b +size 27093 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png index a4ed8eb2e3..3de381303a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd1cce3d0a456d3501f0f5c5160821210fd1060c24a66f1cacb65f9f95b44bb8 -size 23792 +oid sha256:d0be20df5f6bdf095fd9a93df3dc6ca81939365e4f27c8f605a1ab12b4959fc6 +size 23724 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png index 05509fabe3..49c0cecf77 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.root_null_CreateRoomRootViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f26d62e7ca9b98ca9314305b0659f7919b58f5d7805684832e91d5f3cb6ece4 -size 31162 +oid sha256:31bfc0054eff2bce1e43c49fa628968504e16853a198579710d08a2134d24efd +size 31099 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png index 16876034a0..dd4b64afcf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5740c7f4d76a786612c5a1cb9e58c29c87778f3e8d11878f310cfda3da1bed8a -size 28445 +oid sha256:245c5b206b5f560c9457069761694f0198a89ad700cfc39241b22441a7f2c31e +size 28345 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png index 9f6e875358..6c1fee3405 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbb6813f970b0fcfa9489d06b28b2e17d6d0fc97d2f0494553a629df930af48c -size 32919 +oid sha256:70b2df85168ea6d5d7f7cbae84a91f45a9ec7fe716d4d6c087d21f8b787a3fb6 +size 32648 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png index da5124b675..124e9ba417 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:633165e86d70889024469309db5a4f44eaa00456f0452e6c1447ed7e24b7bc4b -size 33059 +oid sha256:4e3ad562682d7e0df76faf0041947158c0e90b93a60d2aa4129ea1d222e439ce +size 32762 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png index e3e06b6a66..83bcdc038e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fb2d663532efdd393063f3a1a53ad0da2bad91033dec2d6bad971f681a56a45 -size 14016 +oid sha256:88b77b856b1a6582aad3fe26f08a48f405d2a0cbc1a495f691de7af569bc7370 +size 13744 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png index 986ba9ee23..14139948d0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e030b3d98c9d4e6a37a983b180e664b45697705a966bc9348ea432e123a3b6d -size 28604 +oid sha256:9e2d4495246144df6f91ed8ad6ef5f32b507f56c2f8ab9713230e7212078d7ea +size 28479 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png index 27daa2fd10..9af73d58bd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d75bae2ae2ee8a407d2b4652d699e664e619cffa5a7888cdf6169395abb97c6a -size 29142 +oid sha256:730f27b45cb2176ac6f8415780b74e2f117b9cc3f64d4602e6c42253f65b23e7 +size 29181 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png index c1dc2207c0..84b761658b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13fa1f840184a20cea94d1cd9d76480eda1c458225b4514e37213080c936d3fd -size 34888 +oid sha256:5bcafa377dfdd0a3e3db955c2d81791f1c36c95b22d978090b8d4e6b063c7d69 +size 34866 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png index c45e89835f..149ea8dca8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5abcb5badc21e715c6f7c4330e5721b0275fdcc678ca3920ce64ae5d34829250 -size 35005 +oid sha256:0b77b77a20d1c3d936dea733542f1b2bd8e575ccb6d3021ce1c2d84a701bea35 +size 34965 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png index 23a8c73c75..e9a0097fe1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:772d4d50bbed5bc5cebc8f636ce952fdc4951b714e4d621030a87db7a1df9c01 -size 14162 +oid sha256:d3092c176ec732f3e378430779a8645c02cd6c47756a6dafaf09a7fe28e79608 +size 14112 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png index 1ce40f977b..18eb4c8c8a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl.components_null_InviteSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3cd5c467381c74c579e62405bc6016da1b9b050365d04a335845a19d1ae2c41 -size 29448 +oid sha256:8b3cf23c4ef3ee18a3dd4a20a683266b2cdc6b6bca90b1006c109e23c82c6ebb +size 29445 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png index 3552000829..af4db9ed9a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2aad1e4a3ba3691a37c9a2df872609ce7b7cbfb326deca6e5a81e6a0a50fb19b -size 52305 +oid sha256:079fe39c7dced18433ef0c768b30ec0c66bda3d910b392bfc33319f6be7ce892 +size 51852 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png index fb13cb54ab..68751cdec3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb5f62cf093e48c40732d801cb27c51005c82f84aaf96ce86e5dc50c54ff27cb -size 49589 +oid sha256:e002caef4c4be424468938e2ca05a25c6f6502340f216eca908ba8784a4d98b2 +size 49289 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png index 42cdd40e09..4ba1ea763c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4954c0ae06d16a0058b88eb9b648911eb0c8b36eba19e40031bcf5ec6c262ff -size 50257 +oid sha256:d7bfc8f00d9286162292ed04e9a53f21f5f8f2f44bab88c00356d330b56fd426 +size 49965 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png index 568bdb2d89..c7a3568641 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0623f68ed17b1d7e39b2737255a2f3d5448a984bcef00ee58558a7581af84074 -size 40173 +oid sha256:6f23a5df96bb6faca94a8096cf4b884af1dc97a755f0664ca05c9d64657052f8 +size 39772 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png index 568bdb2d89..c7a3568641 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0623f68ed17b1d7e39b2737255a2f3d5448a984bcef00ee58558a7581af84074 -size 40173 +oid sha256:6f23a5df96bb6faca94a8096cf4b884af1dc97a755f0664ca05c9d64657052f8 +size 39772 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png index 44650d97d4..6b5fc9bfeb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9357fbad1987326b891699fb5e176e4458d1b7dbe660df95d20c079d8f38bc52 -size 55154 +oid sha256:9766ca3ad7562ead5bbc4b40eaf4712383a8c90876010fc0a23fc3ba4eb7eb42 +size 54662 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png index 0e6271869c..39c860e6f5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:840b7a0a23d458680f59f328d2a8b756e80ab76e368d749a511e7352d31d0f4f -size 54196 +oid sha256:b564f1c08b839c6758e3abba916a0b20f6cc0f590b27773de1d6a1e88a2cdc56 +size 53899 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png index 7c71ef8088..7e1c4760e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:062f857b2b2339f54543b70a864786b1463747cb7e45db54f76b1831938dd98f -size 54984 +oid sha256:6881032ea2d387c2bb8f8dd776fe6b581c100328d13b023e190c22dc0832e4a1 +size 54689 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png index 31b2eb0efb..cb2628494c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63070cf809fe17adedc37b9df0b9a421c453d09e8edd95869fb62f4b1b066a16 -size 44827 +oid sha256:9717ce6ae0559ae73cc9397976887b7acb1a534a957a3a29b0d0da2442e77130 +size 44397 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png index 31b2eb0efb..cb2628494c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.invitelist.impl_null_InviteListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63070cf809fe17adedc37b9df0b9a421c453d09e8edd95869fb62f4b1b066a16 -size 44827 +oid sha256:9717ce6ae0559ae73cc9397976887b7acb1a534a957a3a29b0d0da2442e77130 +size 44397 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png index 0ccf45d0dd..04e2ba64b3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b64a7ad8a711dcb67a5b130bac5f3083421ff79b4476060fa5f54f3b14dac173 -size 38511 +oid sha256:db2d848fded08ca0532f718f12ee9dab007d7bb129afcf949d26585e47efa054 +size 38389 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png index 3b48d22222..a008402361 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e335de03505f63e0b02ef98b916a1fd979b32a58f3c91bf0dc6194d6b66d671 -size 28302 +oid sha256:20847fc7ab9e27171ae0ae37a95e7524aac0bd2479ff5b8b1130a5bc26dbb3e6 +size 28232 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png index 1e64e85760..a5a732b30f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5366117e506df73eb6073bfcdc76738a89262c4ff83182a381c50b98230c71c2 -size 37051 +oid sha256:67060b3bd4d09915ec4eda311726a8657cf09e455b5e8ca42631fa3b448ad5b7 +size 37049 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png index 53b1988ad5..ceec7820f1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:286f4ed93711fe203aace6e629971b6681ed74cb2a9cd7cb8544125144d4fb17 -size 26867 +oid sha256:a62ebcf0024a1876984c936c29037cf04e2e02aefb3bea461030c092fbde2937 +size 26983 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index d41ab12fd3..80a6200a6c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98bfdfa99e207e5f50aa6a6aa08914b8f2be407d5547f39984a0a3e05d41bab7 -size 26932 +oid sha256:7afef32647fb7ca666ba516c3f348d1fb168be290279869b73c3b64522e20301 +size 27069 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png index a6fc15351a..28307e18cc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05e62d2584c3eda7e22068731de56223393e869c8e91ac547a148a7f84e870dc -size 26485 +oid sha256:e2d9ea4c550094975fbdaa0f42c85dd871e414b1553c96b1256c8534233d6050 +size 26618 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index e7d3a908ec..58213edfc0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f -size 26473 +oid sha256:2a216a2aefd132b3ffb64e89de3c8b2013595573783f7dcb9ad6e0f04e1cbf1c +size 26607 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png index e7d3a908ec..58213edfc0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f -size 26473 +oid sha256:2a216a2aefd132b3ffb64e89de3c8b2013595573783f7dcb9ad6e0f04e1cbf1c +size 26607 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png index e7d3a908ec..58213edfc0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewDark_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e72e276a8a0fefafe36314ec82f6ea1ca8f9bcb077afecc49f65ba977a59595f -size 26473 +oid sha256:2a216a2aefd132b3ffb64e89de3c8b2013595573783f7dcb9ad6e0f04e1cbf1c +size 26607 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index 6b74783202..3c82e866f9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:080d58220454a98725f418f931c6e18c4af11821076d8cd446525098a52db6d2 -size 28739 +oid sha256:2333902757fee47ccdcab42188b5f5379fe48e2419896a4d525855510b7925a1 +size 28241 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png index 2ce5fc6bc0..2281938ed5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7da900d8aab1134bbcc472104a876c390f156a9531f1f3f7d57e2e9211be5ba6 -size 28146 +oid sha256:7c4bcdf48d7ba2f11cb7e09ad56fb1facce1722fe71b2b10ac5c4a86ed201e37 +size 27646 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index 24919e87b8..605e036675 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 -size 28198 +oid sha256:fa25fe1ec3626e1726043987c5b727d5fd10660c4134d7b714616933a9e0d01c +size 27678 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png index 24919e87b8..605e036675 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 -size 28198 +oid sha256:fa25fe1ec3626e1726043987c5b727d5fd10660c4134d7b714616933a9e0d01c +size 27678 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png index 24919e87b8..605e036675 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.forward_null_ForwardMessagesViewLight_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f70d7796f416ec68599128d2da46304150b57d83262aa706e70fcf85d3b80a3 -size 28198 +oid sha256:fa25fe1ec3626e1726043987c5b727d5fd10660c4134d7b714616933a9e0d01c +size 27678 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png index 9572127bae..56702cb5b9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-14_15_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:094a0f5436527308d2a37b52f6e0c5f12e267f214b79fae980e409da116a07ec -size 25277 +oid sha256:fbe739da995dca5700bcbb6a944c611e7c0b427d39b5e085345d8a7e93759e7c +size 25201 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png index 73180b7d05..a61dfbb6e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-14_16_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0a29a48138febe8b13b1e1099fbeab2280f1b0567233614187d97117df05de0 -size 24943 +oid sha256:09864a80f5eaf0874dfdde8698b3fb6ef8ad95059f2d955e822f80009f49849f +size 24966 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png index 00cfa0d87e..a80b2ce36d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba052f24e62aabc015da4b38bb893148c888a858a097669b2191e7880867e371 -size 52114 +oid sha256:2b55dbcb731dfc40a1e100e8caf26802f759b4bcd186dbbc4432644db08f8316 +size 52141 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png index 57d6580a12..03f50fe82f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f8f7fd27e56aa2ca42053c249353836187467b99a9225c93c22f38365e63ccb -size 53285 +oid sha256:d5953ae4bb021c39157b4118ea628ca9bb2277f9672749cc6313f0b378d31cb8 +size 53312 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png index 8a4f9bc201..eb75a98270 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbfc5593de6c7dda915b3a8bc881f0485b4b8400f52412547aa914862d1d8840 -size 52245 +oid sha256:fd991a67e7d6c1169e08e62cb74ed6fa7d12ad7f91d69bbfa778e0053efebfec +size 52284 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png index 57b61342dc..3c98269fe1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7225f3510289f07d4c273e3bb179d05df0ac9f1a2ec868f061a2622c6f9d0b84 -size 54030 +oid sha256:1d6ba255d9b1aee8d560b51f2bf0c1d4433c63502c83f6cf18ef8eaa598f05c4 +size 54071 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png index 6907cccce9..35d5965ff3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d56d5666d1d7749484f19c983e3cb2125110039c80e5898684e20b7e24a3e56b -size 51312 +oid sha256:dc662d180d1766706f249f1585fb100f5933206b65d4644fae65abc6a121a633 +size 51331 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png index 1746cfeb84..65cdf717bb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:398f4b1c7b21ab4c57802fb724d62b8c904f5a0c700eba507a811cb58881df49 -size 53896 +oid sha256:3eb1479510a8cd04d133265e33ea15115158ac55c93387d1dafa93a3a3a858f0 +size 53620 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png index 69a8b67d95..a5959f6d60 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2913fc7ee2c4b32e79e0d813ee8fa54e6d3f863466b798b8194462cbd9ef4fde -size 55137 +oid sha256:c0d5272b14b347f18b2d67d5fae6eaf507b8d6f7c9d361317bb6b8a062e63ceb +size 54899 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png index f8b59bb375..9603a65588 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a20479945a552e2d3d3fb309c07ac7b9a66d4dfac0ad1ddf2c86c40fa0d34db9 -size 54175 +oid sha256:d421656ae8ad316e65f406c74dffa2ceb4e47b868b7f033f9cc4139e3e6be788 +size 53909 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png index cd18a11803..47d15c2bf6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9f686208853c864a9aada2c809a43e1de230e422e93af7c6330b8e78dffffec -size 55730 +oid sha256:fa96d668bd220fb1e47850c86c7ded9fe99b14b9704f1a5662cfde1e932c5299 +size 55443 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png index 367b0dc907..8212494315 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_null_MessagesViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e7697c3f1eb995fc0bbf084853fce1cc10e841d0275d6ff4f2d857afd81b31d -size 56103 +oid sha256:dff46ed537c81602be0dea8782e37bb78669ee798ec4d422c23ff29cbbdebc17 +size 55927 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png index 5fcb6cc260..21903d1663 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46bdcc0dcd5dd9ae0740eeb0af0b0587f1989689ec744c2f38cb4813c860bfab -size 39711 +oid sha256:239a01988afb77f399b9488e3c314846a59d368ba2a7fd8bec1514ff60dbd8ab +size 39772 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png index 3b7938f529..2fbb0cbc02 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae44b96af239aee5fc7839df08f9298490add53d76c51f4778d2af4d57aa746b -size 39043 +oid sha256:1b3670c1508e8548a32e51c8d1bd75d2dabce73a2bc710dc673a85f98901b5fb +size 39100 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png index f973a24462..b38a248d82 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66cf5b700fefe4839d6956e83d7590711bc38a659e41d0aff829cf877e7dc209 -size 42351 +oid sha256:ec1f4a968f58c9c7faf6d51ec5dc8e31f00d867eb506b35a466e6a2242945c74 +size 42131 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png index e400a8de25..fffb00c7f3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9372f8f7e0a173d680fd860fbbe7e4319409b82b02cad8b83eca2059fbf35bba -size 42486 +oid sha256:4b0006728215e73456e78192ce7d774d8bc792d04fef9fcfa3b76c081dfc8deb +size 41996 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png index f7d8135d0b..c53281b9c1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:964d97909629c1228e96d923ddb478735475839b8540c02142444f9ebd5bf400 -size 13100 +oid sha256:115262f8a16f26506139c7b8f630e85520639ae5dca424028bc9a721942aebc5 +size 13168 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png index bff7b81448..658eb46874 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd8ff4a09babf30be0eb3c336f3cbe6a1508a21696512d0dadbcc9d543e6e34f -size 12356 +oid sha256:5055b4cc1bdf5a4b00e901e5e40c0cdcc415d22d7154ef38888936928100928e +size 12365 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png index fe1fe39c26..85665e2302 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85530997942e39ce73512513ab0698494778168bc28cfab543b50b721c1807f5 -size 12855 +oid sha256:1c4ce3a10a671acfb2e619356cf792b5f11325a55edca30c57813aa7823e878d +size 12591 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png index 23211c9508..119c55ec0b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.user_null_UserPreferencesLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e0a638be5745c75c2663116877d380c83df093d226d2c969d4f6620e8cee109 -size 12965 +oid sha256:28f315ebf657e95e666b6599b096d1779b1c9f3cefea3e679a9054d80f89d53b +size 12412 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png index 3703690be4..e0211eacbe 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48311f503e47fc462a1f4d5afa2ea82c0e0eef99aaddea9cfabf5517af37bcd5 -size 29796 +oid sha256:19ac99f81f3e72f0492d33278a9e549763493ea7ff111412821c62d934a6b9f6 +size 29522 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png index d19b6c9ec9..e548c3c81f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1aaa12b291dc1e187835114eb8c5c49bb4eb5bf16d87b039272a6e32e16cc6e2 -size 23369 +oid sha256:d15154d8ad933acf9a52a73fb650d28489d780cae71b44c7edf10b682cec1ff9 +size 23143 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png index 46ed873359..487800c8dd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82e2cd2caae9b20cb2e3990216b0ecdf0bcfde4478911f00168e4f936c223889 -size 28736 +oid sha256:0958e2a99818be0125b700df470a944a3202e0336d440b073cc73ccc6305173f +size 28482 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png index ac9817e2c7..241c7e1400 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2cb829eadcf07760a073af775be6d15e91624a9366d7bde366d7c9cfabe2c9b -size 28456 +oid sha256:da07b8de2fd24e9e6bc7fea309e4d5fce68f2143316a5940a41f4270e9d48646 +size 28099 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png index ade52ae50b..1de6e8de96 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e142fdf51287c82112267ac8070ff4d6c2fc3f92c14c82c16127aa1822823312 -size 28839 +oid sha256:1a7e0644fff4f219712719b4837cf4e5db5c8cf4c9ec1e21fcd1362859a155f3 +size 28607 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png index abb2875d87..c078ce120e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:447fdfc57825e1da34d294b7e212984b088e283810fe961c5b21b66f3c770cbb -size 24971 +oid sha256:8444587bfa6ac65c6464b102bbac0bf679fecc0b193cc664540f39518b30c25d +size 24785 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png index 9fa729c209..dc1ba40727 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b27f3e2719d238b61a8f83264417c9c2d9e561bbaf12eea20f9169366c90489 -size 31076 +oid sha256:22b0a03bec31400bd88a51c160bf63132f0c8f7e1cf02041a901778c3f1e27ef +size 30856 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png index 1408e43788..cc49e4274d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5b4b04d5163e8acec4f156396fd239296b7fe3fc251fc5efa78200f4b6a0e83 -size 24352 +oid sha256:8308dc746a7a51a7bffa49cbf1436097565a175298073afe3d94558d77307510 +size 24145 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png index 1dddcbf124..ce4af21fcf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61b56cbc0193c9081ceb3c8662afc2da8686a7de4a3e8ed12af2f7dadfd0328a -size 30784 +oid sha256:32f3030c3bfb1bc9ed4c4378698df073cb29285477538c81592c38668953ffc8 +size 30562 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png index d108a47a92..090bda7bbf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7ff9340f9788a65fe6ec4707cba125196fed08bb57ead4dce8bce2efb70f1f6 -size 29714 +oid sha256:0587640a3ffb707c94d25da38d9f327500c3d3a96d0b57ba92a3c4201014fc11 +size 29448 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png index 68b91dcaaf..03d72aa037 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ab65feb9ba77f6a08e52fae42f32133845f169c651049e90c32c3abfbd8cea1 -size 30835 +oid sha256:1017fcd62a71f7a2a82dbee3ee2a5233747eb3c888c4b6302f65d9aa02c5492c +size 30673 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png index 29f2bfe96a..acd3d83443 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.edit_null_RoomDetailsEditViewLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf0735290b594857c52df56f2704b3e9ac7bae00a61a26b956febd5c6679357a -size 28228 +oid sha256:4e01d7e598c771260bf4ef91d0ae99081e80f318c1e0300cda3dc1ce780c80ee +size 28078 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png index 774ae616b9..56e17f1b80 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41c029826a7f0d722ff9493a287dc45ed01c4e0f02e1fbdb4f69abd0b762b5ac -size 28592 +oid sha256:44917f87510b19e963ab02f1324057b694815af1437300c8c4763ba617848dc5 +size 29113 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png index 4ace7951a5..cdc1d79045 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b4898e10aef39b1e7e9d16d9f214fab756dd203403de00e263a6049d4ff8b86 -size 26594 +oid sha256:c5fc0b0ad8f0b5524db430195f56526cf4c0d0ec48ac3bb90e7f339e4859507c +size 27041 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png index 1d6c880873..ce2912e13f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:473160d4ce97eecd9bc9ed67011c505e536272ce1acf838516c34f3b992f74a8 -size 45367 +oid sha256:6d289d744e4ab63c6f9fc679b3e431ca4a8a3e905b0a34f4dd4b6d8ec5f345b3 +size 45347 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png index 866984d7e3..ae4b8097c8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b20115a793c0b021d077d816061b5b221f8e40581a6cf715fb4701941a38c207 -size 38583 +oid sha256:c61dfd03185e0eff646f3e6d4c433881825299129d979369645d689305a6234c +size 38500 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png index 36b034bdb4..f4b3fc01a4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:695041dfecf9415914d4f642c81154c8f90c8460bbd5c2023c9cce91352d2245 -size 29528 +oid sha256:d1071bdafa2d9c1aa08e81ecc4b7017957725eb90d0fcb23f455b5f80f98691e +size 30568 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png index 9ac987f959..205a77a3e7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f8b8e95fc48731162ddf10a3b00bee300ba6fcaa02ea48455a68ce834915b8d -size 27532 +oid sha256:e391357db9d24d00fa2dcadb4cad590c7e71971b113ccccf7370edc396ae4da7 +size 28171 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png index a7e212f2f3..33303a2529 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:867deebdc8a7e1844718508501e05d1f2f811f9847c60815fea86113ccb82bbd -size 47057 +oid sha256:6fec1683e88a36fa4c95f9bd83b01030f9b375cfff2034f723c81c31c6615f5d +size 46229 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png index b204cae7f5..e50fd62303 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_null_RoomInviteMembersLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d99677b0930567cae7f6e356137ed98e701ff9ed2a6bd8aad66f9d12d8a1f27 -size 40726 +oid sha256:03881c5bc6ce8b1008679cdb0db2e86f713db25c9bea1eacecb713fc8274b91a +size 40281 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png index ba78172dd9..74a3f56bee 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 -size 19574 +oid sha256:33c80b7d24e8f0ea86d22ac1fa92c72926edc2d51ede177046787c2d43440790 +size 19399 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png index 3a070189ae..54685640c5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29fa748333d5bfaebc2877ba66677687a0ac40581c1a4c61bc7cfd67f627f85b -size 17375 +oid sha256:a89af486f34afce8a092954f6adbc4a4a38154a8219de751982cddaeec6029d5 +size 17181 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png index 2245a0502d..4d2060d15e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc56b1324ca0206fe25eb83b1bfc0ceb559ec86581227e3db766ed52c4b314e1 -size 19992 +oid sha256:235918bd815cadfd3f202ab259081ef48da0e2fd563547ce7173b098c585bca4 +size 19814 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png index ba78172dd9..74a3f56bee 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 -size 19574 +oid sha256:33c80b7d24e8f0ea86d22ac1fa92c72926edc2d51ede177046787c2d43440790 +size 19399 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png index ba78172dd9..74a3f56bee 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ceb363a42cce169fe6458d98f267feb22b87ced5f1bf6d73e5f41a6c2600199 -size 19574 +oid sha256:33c80b7d24e8f0ea86d22ac1fa92c72926edc2d51ede177046787c2d43440790 +size 19399 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png index e366ece74c..4a93a6cfa8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewDark--3_3_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84218b0e445d477223d7dc7aa87e043671b6c4a5ce24f431af4860ba04fc8f02 -size 20591 +oid sha256:cd3658bdce62cf7ca62c9138271df8b2d44ad5c0229b468fb40049a575036070 +size 20418 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png index 9aefe59c7c..c0ca95c0ed 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 -size 20054 +oid sha256:342a89e74b6067ff1fa1213edeb76dd05099d91083b6be92f48aff6ea6979393 +size 19817 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png index 23ead15fc3..42407d39fa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85bb085789a6c4fa5cfa4379ef19eea470b4e7f276823362cb06f49903c01788 -size 17754 +oid sha256:c276773e89fbaba8b81ca5ace972364f2c4de24f670ac8a39f3a66c243a56699 +size 17517 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png index 2d1bd42c0e..bb14682c7d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d21c65c4d5c0070c8a75156cadfa8b7a6f97a4ea8e2ab8b52339792a21638c63 -size 20512 +oid sha256:b6bdeb3f25b2f7a98ac55e3ba32858bc2fd2154f1f211e50a9bc36ac1be3090e +size 20270 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png index 9aefe59c7c..c0ca95c0ed 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 -size 20054 +oid sha256:342a89e74b6067ff1fa1213edeb76dd05099d91083b6be92f48aff6ea6979393 +size 19817 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png index 9aefe59c7c..c0ca95c0ed 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9830d6448948fad763093ccf0b8ca8df7cdc60e425d9fab1b1406f893329d620 -size 20054 +oid sha256:342a89e74b6067ff1fa1213edeb76dd05099d91083b6be92f48aff6ea6979393 +size 19817 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png index 121f05a71c..4f768927cb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members.details_null_RoomMemberDetailsViewLight--2_2_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be5e1b77f5a7d9673f4c498a99e40cb633d536de608408a54dcb78fae7434d45 -size 21068 +oid sha256:427da8bbf67861ee3214540b57e573ff8b2879aaf3639769d4b9fccd591676c5 +size 20881 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png index 592eb43fad..22ab8f88bb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c59cb5eb1538494a95a4dd531127afc8cae252b08c7812bee79db4b32cce500e -size 38214 +oid sha256:deecef6a5d8161828745db707304195d360e3454c1d092fe92c57cf87f55cb9c +size 38196 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png index 5e988eb0b1..de021bcb26 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3535a659e893592ba4010c91049f0595d900d9f0aeea7bc2cb8317484bda58d5 -size 24897 +oid sha256:ae2b5be95736d02b76b34d3156b61a626edb738f3dd64f75c1a6c36b9413df0b +size 24968 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png index 8ac709d1b5..5de307f4aa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da07b9156d4e27aaecf0d3860d927660a688f46caa305940f57ae2f783402c8e -size 39429 +oid sha256:c6312be03f23e39df742082f9886490107939fef35971c4476f3afe7285848fb +size 38836 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png index d8fd92355c..4f504958a5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_null_RoomMemberListLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3237f778a1be6d86fcc107942ed8d19d38f4c332c1c307391b70521f9b11c8c8 -size 25600 +oid sha256:c526ac195ee5c2d3f691a0fd13ea10a1efdd10b1c56bca579885d90d2f1658ac +size 25308 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png index 211bbf07bc..ae23a77cbc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49bd51a32dbd3615364a6039163a36c08d0096a8c511a7084e21b7c1780131db -size 52810 +oid sha256:470a655997e6cd489a74d31e6db8641b48fd7974db87547f2d2efc9a4c8901bf +size 52503 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png index 19f56b887f..1f23fa479a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c61e5d0eabb1f9cae83c3df0f73f14545e0c61bd7393d6e2862e0f48b9e3d7a -size 51272 +oid sha256:70b8a0df5f3184e54b372a07bba99381ddc107e6dea58eee96dcfd4f0d04c022 +size 50857 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png index ec15315140..00c3f8d140 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adf48ade91c22ce7f98bf2773ec4e14ce0c290f7ba25e8c76d9f722677c46277 -size 44388 +oid sha256:fc70f4008e918612b15ce7d55d26092c632a08f3179c98452bd3acc9111dbb9f +size 43979 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png index d72802868e..ab80b1cf18 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:262ba970549c3c137ab90ffc607279479dfc4fbf86468e18b08ea6c5ef5b0710 -size 53634 +oid sha256:dd9f45108f2ec9739cb414bd11751e9ed41044948d5ddd70e9afaf7d75b52b3a +size 53305 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png index 04edeb3284..40942f08a9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49d92579bffadd59f89e79217b5e6148bbfeda0c5750a06ad7aa36f8125d6d29 -size 50616 +oid sha256:c01f60be5fdd30d9f75de6dc8a272954123e14a05eca2dc3fe643fe8769ff218 +size 50239 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png index 2150b91f12..0efa94ce47 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b742f507ba11be8bdf733e5e751fc5d9fe1c0cc2eb070abf9abcffb605783ab3 -size 52151 +oid sha256:275e0112aeed3097ef7eb295ef6dc7aedf6bccb0add1167c823b78953c887e33 +size 51963 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png index 2150b91f12..0efa94ce47 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b742f507ba11be8bdf733e5e751fc5d9fe1c0cc2eb070abf9abcffb605783ab3 -size 52151 +oid sha256:275e0112aeed3097ef7eb295ef6dc7aedf6bccb0add1167c823b78953c887e33 +size 51963 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png index f94aa99b7b..1b87302d36 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:467ca1b17857b053881cb9999c3d6b099949c6b4279188da57383fdb9083041f -size 53946 +oid sha256:eb9e612cc985121de0a8a506066dfecad22eb283232a6815e7a50197c1af5a1c +size 53640 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png index dbddc54999..5914da7d56 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsDark--1_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8e1ede8c0ea34595e90b2031c9607b99e72c3d7d1e9a778bbfbece98eb23875 -size 53035 +oid sha256:2efcf4a4db75ffdf8f2a2bcc841eb8c27b5497f8724754360256dec83b494f5b +size 52747 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png index ca3e37d42a..cd275d2b96 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9f1d200ef2c93d557a67a29700918bd70439c7d7d8d247d60473b26f0c44eb3 -size 53851 +oid sha256:b845bb8d92a35424cd81a5355c0eb69cd069bdf327d28caf69326355e4c33e93 +size 53658 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png index c27ccdc333..4f5d817402 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b06e1652745ceff912734b9bf74543c95f4d420eaf3aec4b388dd101ea1428f8 -size 53838 +oid sha256:6825637037556cf9440d0cc2303f73e88e29385d1fce9e7670106c96ea3143f6 +size 53597 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png index 087bd78cc4..53423131be 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d4a381a3c99a7f04a11a2e93cd7c4145fa0bd33a1f7461038b3918c5cd94571 -size 46676 +oid sha256:6cca72e75685d2dbc6eb1b2025f8c487c443006d077cc560e6abafd16e06e6c9 +size 46510 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png index 0ebb4bdfc9..8425c5405e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61add95d28096c65f94764df109d253c7b589058cea324d908616312e7dffc3e -size 54723 +oid sha256:6a4c6e92b895251c2c075f3679f7d31480bf1eacfa3592ef17e7d11c79120397 +size 54529 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png index 8a3a6dddf4..7b04c98e13 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3197e871e4b4c39dc714610b54e351c4061149bfc0b5511f78a0c73e8ec2236b -size 51824 +oid sha256:2072ec79ee1aad73cd20eaf0d87106b8757223a2499fff67c5c806223a705c66 +size 51626 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png index 6547257b66..e54b8591f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0cf7d5d0c91aa7946586e5258077b07b329f387f46b0df0a29c49cc211ed584 -size 54021 +oid sha256:537e9ab994b8a6c6589b03e9c4231cd9b984cad4f233d106425d3d0e65af8864 +size 53852 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png index 6547257b66..e54b8591f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0cf7d5d0c91aa7946586e5258077b07b329f387f46b0df0a29c49cc211ed584 -size 54021 +oid sha256:537e9ab994b8a6c6589b03e9c4231cd9b984cad4f233d106425d3d0e65af8864 +size 53852 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png index 6879d4dfb5..dc6c756bd1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd4be4f49a78aba83c4b5f9c350f8b64cfe96d50890df16154cd7b0e20546d25 -size 55020 +oid sha256:183145910ec9cd8a5c19e30bcdf0995dcfc70c7a9a176fe28f6106b2dd5b21d3 +size 54827 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png index 92a37ad86d..185288adb1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl_null_RoomDetailsLight--0_0_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da79bef2bd54301f2724269719d93d1d9212fd17b9dc0d2a7ba935693c6170ac -size 54107 +oid sha256:3202fed8c4344f427442905d4088441ea97446b4ef9350e588df26d5497192e4 +size 53932 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png index 72105204f5..48f8da47ee 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efe240e29b1e9565edf56390c4ed5cb67a7e342cdfb96361782dd2d5dd28c939 -size 10554 +oid sha256:bbfb4b373449d3ce3ff06ad67e8c4ecfcbb0ec8d0bcb400d3c010952d11e8ad5 +size 10480 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png index afcb237bb8..82c658503e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62f986c59715c6f74b0c2bf98afe7ea9df4619b833919183863c2550419e8dc7 -size 10412 +oid sha256:1d0cc556a6c431fc0f10958a4760fe63d0dd3d7f976ce3507643308c50f37c2e +size 10381 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png index 96ad4b73cb..1af63ca5ba 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf5694071227c215dfeee78347b20575aab8456c97ba33129386fa7b156beee0 -size 12089 +oid sha256:701e8c9761795b0d7b31d2e08afe502a56882d7a6ec6b61db1b1c13c59471b9a +size 11864 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png index 4e2a983e69..5d349ba526 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a186c8be46410cd829bcbc46f2e2360816e6d50f6476d1bfa5dbd970d9fe609 -size 9367 +oid sha256:329326c10ecb636896916019d113e777cb606d1ee1ded5578b7dbfbc38e0189e +size 9143 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png index fcf7318f4f..5d673a1cff 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50826af8c22e844eca956ae277f09ff4c69a262507d32144313bb4638436a186 -size 12465 +oid sha256:e710857b4a1c3da12ceb51e7400229d0fd7f42d6d6158a07e2c2814c728abfdc +size 12229 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png index d4ff97ad67..d0ec7b4cb1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd7d6642bde8e6062a2a87829741b23a18c9a08ecca3f8f1b291ddee9cac8a29 -size 13363 +oid sha256:db014e76a88015053b1be458ac758dde99f8cf01a7a78850c0bf6ff4db27dcbc +size 13173 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png index 8a1c18bb99..606a183dce 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb25fca8bf0a2c4567e1687b37c4eba72cf8d7830cb74555f4bcf72941c66b2b -size 13694 +oid sha256:4d062feda6fc808aa87df5a5f4b3229153f7e50925e3c55a8c8a99a583212857 +size 13458 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png index 7d4841a54c..7078257343 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowDark_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b7fed22743d761141600d8c1f0df0ed9799acc3d2087d693da2fffe53605a30 -size 22092 +oid sha256:79b24ca5c6426aa966024d79bdbbc4a612169037cf6bda7496299ea298fa7517 +size 21951 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png index 0d10b79070..d80e1cc282 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0959e717c4964cd8c5acf05fcbbadb2e44bee3217ab451a7b2d77e534be08e3 -size 11868 +oid sha256:fde0cc6b7268856b611db66b66b22c51df155f605988fc54f5c7ba18e5f1f713 +size 11456 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png index d58e9f7aa0..73ca4a2eb7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:17dd1974f121b1bf0c769cb005f0b1cfb57b11e8cfe94f752b4e9d491e554af5 -size 9216 +oid sha256:ca1cb753204502aa929f52e8b222b86bd845086f841fb9ff2936886e1dcea526 +size 8778 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png index 7b034632db..e471eae254 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d90d24f83b8ef1d33ddeefe7942728d1b8de914de97b5724f1413fc88acac771 -size 12247 +oid sha256:9c9b33e480bfad9c55d55e25cef2a0ab1f25235382e1b53c93107a75e95fa90e +size 11840 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png index cf650bfb41..582d30fdfc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:193959145770210881785866b3951a5fc9c02f11604d96d2f4dcf9154b69328f -size 13211 +oid sha256:824e708f277ea66a161f17cb07a3070e03ddcfc326b9dd73d0ad6b7e62da32c1 +size 12807 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png index 07acdce0af..0de6b64bec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a439996ea530d83c8f40baf0c4320a8ac21966cff838922e8fab926f7d3af5a4 -size 13683 +oid sha256:39b7b8354b98bca791698ad65f4e21619136f446b2fd050c302bdd27ce138a4a +size 13263 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png index 5f190faa9e..fcf8b20fdc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_RoomSummaryRowLight_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ff4b3f9f077ba9a62878463e3153e89e033bc631c4b627d31324d4f9af511e4 -size 22486 +oid sha256:64e7ca21b0213413ed45d0640295ceb2764b01b2bce20a01518e55e620925086 +size 22193 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png index aebe17e861..976af63965 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_ContentTo_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 -size 30482 +oid sha256:0a7a00ebee01aea35dd50cfa5155f6ff58efb21fdf62efb934bf70411563d7cc +size 29908 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png index 26664565ca..5d23ac3205 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15198a0c45657bcfa1f945349b18106e3239def6e869aa000030e3354ddc03d6 -size 29732 +oid sha256:392c865a3d45c0ab5270241d31159075edfe020526b0fbe39593e46b29da958b +size 29819 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png index aebe17e861..976af63965 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_null_RoomListSearchResultContentLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 -size 30482 +oid sha256:0a7a00ebee01aea35dd50cfa5155f6ff58efb21fdf62efb934bf70411563d7cc +size 29908 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png index 50d588999b..c00ff9fa1a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4482b15d928567822dc984a1f19c698f6a9d981d907b70635b3054795292306a -size 36543 +oid sha256:66bf2e3b890ab75c77f1a9e4e80a374cbb5af35e72b8f53c86424c56f1a9f524 +size 36582 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png index 9ffc58dd11..d47352bb7c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b22df92cc4ec3e9622f23f6fb7e800e17afbe3a12f9f3d4121b1981ac0350f8 -size 59635 +oid sha256:1aff1b446de80f7535a71fbc77d7955a679ff2846bb240b70f2d410114f29b16 +size 59749 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png index 50d588999b..c00ff9fa1a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4482b15d928567822dc984a1f19c698f6a9d981d907b70635b3054795292306a -size 36543 +oid sha256:66bf2e3b890ab75c77f1a9e4e80a374cbb5af35e72b8f53c86424c56f1a9f524 +size 36582 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png index 58940cb17b..d054685464 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c78072a5ab2e95aaf7abb085db0d66761eb987b22c0e1dcd6da901f3fbe2a3d7 -size 38438 +oid sha256:0fd240006e3b08b081fccdcc29cb8911fbde7f923c4f8207de817ea6a42d3d6f +size 38475 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png index 98f9563247..144beef563 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cbf0a4e9ca5d3471d361890737d5aa9636abe3143f5de9218e0568951d59bf5 -size 37887 +oid sha256:77d78ad2cabaac211517c129a42d8164b02ba2cc5b75a13f27f2ae113b2b9f06 +size 37924 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png index 3db493ae46..7125e2cb27 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12cac3731fd61b4cbfec09b0f439b2744a5374b6d9ee2b79880507af2224b969 -size 38241 +oid sha256:9701408630ece8c6178e792920688eb41a8fe1a4621c45f8cf34338f134dded2 +size 38290 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png index 26664565ca..5d23ac3205 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15198a0c45657bcfa1f945349b18106e3239def6e869aa000030e3354ddc03d6 -size 29732 +oid sha256:392c865a3d45c0ab5270241d31159075edfe020526b0fbe39593e46b29da958b +size 29819 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png index 7b757a00fd..c12e094911 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b03c0240edcc58f64bd1dc7e9ef619081f4019c5825c6e4133f3aab4b7cf9b7a -size 39711 +oid sha256:56f0ecce5efe141fa2181e2c16dc654e79c4de43cb11b18004b03ce2ddad991d +size 38801 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png index b624add247..87770b930d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2ca4bee47e6beaf4b79c0417dbfe132f6e92974c33484bb0440929a35ada794 -size 63618 +oid sha256:f9d7be89279d30e82a689654eac67137678ca4eb079e80372011580bcf0e9e22 +size 62757 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png index 7b757a00fd..c12e094911 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b03c0240edcc58f64bd1dc7e9ef619081f4019c5825c6e4133f3aab4b7cf9b7a -size 39711 +oid sha256:56f0ecce5efe141fa2181e2c16dc654e79c4de43cb11b18004b03ce2ddad991d +size 38801 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png index d046533d4d..861787a0b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19e78d44954b0cde8ea83873f40e6b0a5cf53a02b4bd523e8b8710a483471e32 -size 41698 +oid sha256:db76df516d6c7a4bff5b830e423145c448b076846b8b7f75032be6f65585cd31 +size 40846 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png index 479929ff78..0968936113 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ff479b11d48f3bdf5adc02d466b6427cbf778b2d2184d6e88d7abe8c12043c5 -size 40960 +oid sha256:405842db16444b958899fe174ca1c0157c0c6384f8ae0be37be104de8613f140 +size 40126 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png index 7d8cdf7415..1033a71853 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f9e4cc9f63f4414fbe1f82e82b9eca7b5071e26aa057b1137daa75cecccf150 -size 41329 +oid sha256:658ee0f231146446810d7c0d09d280148d68475d2411c59cf0ac70caabf4e3ec +size 40496 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png index aebe17e861..976af63965 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d63e4326bdec31177615bc924c0fbde49842bb895601ae31036813dd7ba669 -size 30482 +oid sha256:0a7a00ebee01aea35dd50cfa5155f6ff58efb21fdf62efb934bf70411563d7cc +size 29908 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png index dd5e1401fb..9b60e19c06 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d5e1eec999486b11a48ae992708adb8634a46fc89114de463894fd5730330a8 -size 17895 +oid sha256:0a2a737eb81f74c50efb44c03ac9eb528c38ff393dc1a32efa0c148e27da4668 +size 17880 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png index 83cf5299d7..fbbc1e6a37 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a66c143d05cad7db2ca195bcd0d9a3007169c123c96f11fb66dfade6904db1e -size 17359 +oid sha256:ff929a3cfa47f93176817cc844b9ef2f5ff6146f016606515efe858fadd00247 +size 17199 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png index 8321f05002..56cb2f3f4d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8da740d8a43f978b1da59585326848fe18b71b7cbd4cbaecbf520a7219bf5df4 -size 19100 +oid sha256:385ccb31d2b5a286e2bc4db603d0332295fb6f31841e59440f042c99c5c3d5d5 +size 18837 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png index 7dc547ba61..86f5cac7e8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae676fe3063c21680f87ba11f7f68d11250c67365a4da0541397c4fb635f939f -size 20231 +oid sha256:ed8573768b874987b1a313482c9dd38695711ab8e67e81c2cc263da8236e9dc1 +size 19998 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png index c0d18e4417..3cbd9f9818 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_13,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2834d0f7335480a35ca041091c8d7062d64501d52855458864505a1eb12453c1 -size 19043 +oid sha256:7e8e8e31b6f3b43b53d43ec0e067e1f554d2b287909425af625f3c3a187d3b57 +size 18571 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png index 7c3c298a92..2c47cc04a5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_15,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71ea9ad8c4934ee391d94836e57e06f5332963c09ed4c689c125337bb4f66504 -size 22821 +oid sha256:fd6f03742a1840a794f6d506a70ab1dbbb5a1e745e054e47dd4d2292983cdaa1 +size 22491 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png index c6c2cca49b..3a9f7dafc8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_16,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02d3fc1981a83b1635b89cecbfe2ffac65b070060f28050fbafcbb35fa4222b1 -size 20911 +oid sha256:c9d94151ec126ccd1780326a56cce74bcd2a6bafb4a39ff06d6787c9be078d3a +size 20049 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png index 0f4969c23d..fdc359107b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_18,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34aab6f95f04977d64f97c5a9391806cae363408f011bd57a7a2954f6af6c5a2 -size 16654 +oid sha256:ce07aa02c49b32690e95f626edf7b9d6152eac078f4bd46a96ccb3c9c9c69859 +size 16531 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png index b66d0a9445..b1d7be7920 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_19,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5222d968327e6de88f6f1f2bc02e47da51b6bd2fb2dc109279e5b240762966df -size 15899 +oid sha256:a57d40118355c3b039b915462987b1bc960d9ca501d6c725937112fd8cb0b84b +size 15644 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png index 8a9e08a783..d10bba8289 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_21,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:677d553d6098e0534d81e7c4218698f8e0b9635225332d484108917332350494 -size 19540 +oid sha256:c0593fb2b66b37bfd2abc3b4c5cc44a9fd808bb192ab8c972998d424c30aca36 +size 19310 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png index 200d140d83..6868bc07ad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_22,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34e763d9617c7023f3f365ca00e75dcc0d4e80a7a9a2c74bede55456c73f3fea -size 18349 +oid sha256:c0bfae52f5a63263322d31c60a63f8715afd8b1846bc1cb264bcb1f5629927d2 +size 17871 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png index 12f34d2fe0..7d870f1ce4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_24,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7acf87fd6c7da93132c9c89974b6e82728b7aee91f078146ba9a002ed1ae261b -size 20457 +oid sha256:4f43a9df02fb5e54b9a0cba1e4975c5029dfa5e71ed14efb0e435dc8c27617b6 +size 20213 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png index d6b341d0f2..23724b3516 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_25,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6654898419c10c0fc2f96aa975295ac94a68bf1362c3ac955388e5f9bf8e67c -size 19301 +oid sha256:6747bc029d66697c13e7ec048020ad77391dfac6a60ca30d1e01fe3fd8a53beb +size 18784 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png index 300f3e1ba0..5f02a6a11d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_27,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cba6dc7fb2520afe1553ba63b92195708fd77f8ef852ecae0a1407e65970b31e -size 16263 +oid sha256:451a6870ceebaafc86252e72c71c96aebfa92a70dcc0516946c0879850f530da +size 16135 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png index a94d27f33c..cd8e301f95 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_28,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0271737aee4d0922d0613bce60098a921b1b9f717e9be68d5288f7bef07bd76d -size 15576 +oid sha256:7abb38bc4f7c9fca7875d9b5c8c7674c4c2b24c6cae6a122d833cd63ff16a0fe +size 15344 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png index ae8c04c855..4b307b5a87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ea7a72ca0a5e99b0c906342ed34830b7e9ac75cb1e370fc7c9eb33441492aff -size 23247 +oid sha256:c6c2991436f603bc75c9838008c30201ae3dade211852bfc713c8c2ab9d795d9 +size 22929 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png index 203e9e5ca2..2ca5005092 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_30,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1fbe133ecfff74a27273db57f40991cc3f4676f454a85a18162e0c9bc75b55d -size 17065 +oid sha256:c61707b4444693c7e4d58edeec7bb32de1bcaeb76e03a806a883eea7685a9bf0 +size 16962 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png index 6d763a36c3..a510b71d5c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_31,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9665e21d61256c77e239a587e45529edd30db85448bb768070d48ccf42a90c32 -size 16407 +oid sha256:8a637c8d265e3cd9c8ff0e8e804e46c415338bdbb4bc842c81bf5ef31146d53e +size 16177 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png index 95df6d421f..df93febb6f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_33,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46ffbd54e3171340f0b6b8d632964b3b91480cfd6d99871c0f1d6bb7b8cfecc6 -size 20738 +oid sha256:748a2562d8c3e9b5e4def3b8ea3c782868e56f449de1b1ddb4bc36cd84945318 +size 20642 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png index 59e8eac7f5..f97e401957 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_34,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10989322060483d1948f297cf66d7442444f613e9a883fa1377941d73b57be22 -size 20096 +oid sha256:9a6ce0c3b6fe3ac503ee7019dee234a9f96552e1106fe6858030a7c70c506d4f +size 19869 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png index d455ea4877..d21aa10955 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_36,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:736bd589ada20b9ac5d653fcc78acbedf08d406c0aab7a8159b0bd52db49d8be -size 18774 +oid sha256:0c49437c9f943cf044ec64a0ecab2b70d1fa811a34aff4baa8ed0ed846a4f5c5 +size 18595 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png index 3a075cd929..726d7087b0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_37,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a494c20b5047c925aa60b8253b4ea1bd90a95013df3d711bded444f1cbb0941 -size 17683 +oid sha256:063cdf0bbdfc846d3040af143f79a0b6eb325beab62cba5657236d028db6bc26 +size 17267 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png index 9b2e1e6381..38c479cfdc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_39,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fed24563d497b368859de9de4e4c9ae27cb645d89888f7fa7402df64d447471 -size 14589 +oid sha256:032ed67865d3ad800371e193ea922589f27cf03697e3c91c8d698957befa8d42 +size 14590 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png index c479e6007c..b109475f03 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc087aeecec205ff20e45fbe27003409591e9ecada4c2f2b4322537deac6b490 -size 21381 +oid sha256:c5b4dbf61e9b79fa1a884941cc5b92b71b13287109d28837a7fe76fd9c4286db +size 20533 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png index 46cc322fde..8152088666 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_40,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ff8361d32597bea90e830056f00846b9e2392685eb6ac000c8c930ba5c981cd -size 14296 +oid sha256:54b00e4382ea77eb90e6de983ec1b363b504456cebd1754946759fd2ee1e9b85 +size 14232 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png index 1483a5ea12..d69da80047 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_42,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c50d9aee05b3e8b8be0b403a0621bc949c08dbca46695f6c70666002d5101d2 -size 18355 +oid sha256:820b23e9b9175b48461a4e7e359c2440b8c45cb598f512ea360519b0815621fc +size 18259 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png index 868cdd8e71..4cf9f8f839 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_43,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d56abddf692484f8e2f3795c6cd3c62e8497a2d03042ef770fb75e8863921d40 -size 17689 +oid sha256:3ce4abbf622711cf6a106cb6c74ed729c6e609d329579b7b00ba8c1581b4b953 +size 17463 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png index 7165d890d3..6d21931fa0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e2070fbae74dff21576afcd623f73ceacd018b934d44247066f469c9690d2f1 -size 18679 +oid sha256:250b9abfa2b27ea622f43a7d553ee6323eb44afa2288ebc110c0ce2b192f40b0 +size 18504 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png index 92daab450b..217c6fc156 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86660baa06208b38f8201d9155a64fade6fb3ba49689982fa013488f8cbd6f83 -size 17595 +oid sha256:a87e06ec084f377cc608790d326adced33100f8821162ca28bab24856f7ee52d +size 17176 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png index 3c81ba86b6..b886f9140e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:febcacfbb96dcd0cf8815760409d105847b1fadc65e8254d386d774e41178a38 -size 19849 +oid sha256:73356882450cd90a01b8056379848967d3bea1e640ee4e901d9d21a1e823054d +size 19753 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png index f6663c9291..4dc5242c19 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:775f1249eded2e16bc7e03a827256020504379a6999b7ca3a1eeae2fdbf8415a -size 29227 +oid sha256:49f83ea2049468223d654efe71eb572af225fae3563f307ee45b95d220e8fa6e +size 29450 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png index f06a8e0ce6..03afa4ded3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12c84950e69b760e32bb59c9d90a01d4ec1e17a28ac3c6ba53bd16c8d561db05 -size 27552 +oid sha256:de59712837eaa588f9daaa55983f44bfa39fd9d0fa3b10678b4e04c7b5571f5e +size 27655 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png index 454bbe5c79..28c78fd115 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5882ca765a08118f6e23925d0621b882d41eb6ead7f8e62240c3473f3aa029d -size 29599 +oid sha256:2d91c6228c80d1d38217e557552e18e64494a94d284de8702d07cc3793150406 +size 29177 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png index 6533078c75..f1abda92fc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableMatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73fc004c07b36c64f08a65a8b9b62352e9a69f634629141dc1da3aa28397d6f1 -size 29347 +oid sha256:eeb5b50675e186318458d0900b2d3872ec52710df8e25ba7b633a4be7e13c8da +size 28196 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png index a645112020..a65a5470e1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_CheckableUnresolvedUserRow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84714adab3d3fc1a8f076589fd49bb35562913d99d353e9a9e318615568fe3a7 -size 116049 +oid sha256:fd6796e3461493cde5e861a05dfccd8bf40e1ceebb66273d1c5486a7a96684b1 +size 116160 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png index f7d8135d0b..c53281b9c1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:964d97909629c1228e96d923ddb478735475839b8540c02142444f9ebd5bf400 -size 13100 +oid sha256:115262f8a16f26506139c7b8f630e85520639ae5dca424028bc9a721942aebc5 +size 13168 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png index bff7b81448..658eb46874 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd8ff4a09babf30be0eb3c336f3cbe6a1508a21696512d0dadbcc9d543e6e34f -size 12356 +oid sha256:5055b4cc1bdf5a4b00e901e5e40c0cdcc415d22d7154ef38888936928100928e +size 12365 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png index fe1fe39c26..85665e2302 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85530997942e39ce73512513ab0698494778168bc28cfab543b50b721c1807f5 -size 12855 +oid sha256:1c4ce3a10a671acfb2e619356cf792b5f11325a55edca30c57813aa7823e878d +size 12591 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png index 23211c9508..119c55ec0b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserHeaderLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e0a638be5745c75c2663116877d380c83df093d226d2c969d4f6620e8cee109 -size 12965 +oid sha256:28f315ebf657e95e666b6599b096d1779b1c9f3cefea3e679a9054d80f89d53b +size 12412 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png index ad70967875..2e089c96eb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1acf91a8440717f3467e62a533a6172a7eba01c65b2d8d32b3b3b44d514f52b4 -size 11227 +oid sha256:3c174381b49b1d3d4043164db6621867193576e3b90cc7ff1c5eddf7244074f8 +size 11249 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png index 0563bc9ae3..8c97c7049c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01b6759a944884c2c6c7c0631984dc904da890c3a05ac65f4648729065c4f26c -size 10669 +oid sha256:8b7ad04703963062b5a6490434a572473582ec7f9fd5f96155f5723b0dfaae2c +size 10693 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png index 847d11231f..76b6e0d9ab 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c881c08f6501f8a7d2b865360510ec8b2cfc5819d398b477aa1ca970b20fac3 -size 10983 +oid sha256:7eb78dcf579ebd555e77fa74a40732458ae11bca79c8244f12e93eee605d9694 +size 10862 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png index f133082603..739a9ec9c9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_MatrixUserRowLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea7db4fd34a741fecff2a084941a55582e167d72a66a4e206102b5cf8d52c806 -size 11014 +oid sha256:20a51ed0238f83b99d849325c254919028c0011616698b042fc1f407841805b8 +size 10713 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png index 14155e5999..e008079f3b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64ca46029a544e74b05f4a1bc84f17082832b5fdaa9d76a1b5dd3aa755241951 -size 9297 +oid sha256:9a70b86bbd2db875ab61aabd34084aaebc9c12472e8548817be628bb1980547d +size 9311 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png index 0c18e4464d..0fa91f8ca3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedRoomLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78d437e9257a4e8e0f8478607cb852a18e188f65adc30c2297f1d18ef4fbccf1 -size 9108 +oid sha256:5d725ba73157dbb895b34594538ebc149765db558d87a463e7ec24b424bac4da +size 8791 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png index b640b61655..6cc609e8ec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4f6d3ffbe069775e1110e49d7e95d43cb81919642062953d6d8a7ab3b82987e -size 9464 +oid sha256:0046609fce701f35dd8a81cca93aba806782924a893919a6582bccc019899d3b +size 9467 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png index 6a1f4eaa15..e766c6c946 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUserLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c77400352729ec572955725cd8afd6149e7ae86aab18a82dcbd51f4c2cdc0e81 -size 9161 +oid sha256:2b00ab54a071453b87e3243bc8bc2f07520af89864c3776c112b23748e2e6e5e +size 8965 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png index 0d23f92aad..46ab9e4895 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d3677896ec686f3b9cff36bc947de97bfa3b9274dd19705d6fc79b26bcdcc82 -size 74472 +oid sha256:ebb4d2e8a884af7bbded12fcee2b6e74ebaa1c54223566d62cd5e9cdb8f78bed +size 75290 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png index bd01feb258..ac50871cb5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_SelectedUsersListLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3c61acf6eff591fb7765468aa981b8a87fb6da4054175ea60968f5d81370677 -size 73693 +oid sha256:0d3fa7cc10b81df36f01ef13c39f033d5cda8489bc2226f5358f21fb7ad9801f +size 74098 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png index c5a2a4a248..89a8e3dcfd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.matrix.ui.components_null_UnresolvedUserRow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9aa050bd40cae65f3a2fbcd396f525238d182d5e99656adc706692e8feeffd42 -size 32134 +oid sha256:7beca493206b2dd0c48792e391ae5b980ee6bd5e12ee435dadabaab647b816f6 +size 32239 From 3ff7b752a10bc2601674bb9563764f6502b748a7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 11:31:21 +0200 Subject: [PATCH 106/127] Ensure Posthog data are sent to "https://posthog.element.io" for release build. --- .../posthog/PostHogFactory.kt | 6 ++- .../posthog/PosthogAnalyticsProvider.kt | 4 +- ...thogConfig.kt => PosthogEndpointConfig.kt} | 9 ++--- .../posthog/PosthogEndpointConfigProvider.kt | 39 +++++++++++++++++++ 4 files changed, 49 insertions(+), 9 deletions(-) rename services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/{PosthogConfig.kt => PosthogEndpointConfig.kt} (77%) create mode 100644 services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt index b4fd6dcd18..ca6e5a18e1 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt @@ -22,13 +22,15 @@ import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.di.ApplicationContext import javax.inject.Inject -class PostHogFactory @Inject constructor( +internal class PostHogFactory @Inject constructor( @ApplicationContext private val context: Context, private val buildMeta: BuildMeta, + private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider, ) { fun createPosthog(): PostHog { - return PostHog.Builder(context, PosthogConfig.postHogApiKey, PosthogConfig.postHogHost) + val endpoint = posthogEndpointConfigProvider.provide() + return PostHog.Builder(context, endpoint.apiKey, endpoint.host) // Record certain application events automatically! (off/false by default) // .captureApplicationLifecycleEvents() // Record screen views automatically! (off/false by default) diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt index 1f21c0beb5..ca5ac527d9 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt @@ -32,10 +32,10 @@ import javax.inject.Inject // private val IGNORED_OPTIONS: Options? = null @ContributesMultibinding(AppScope::class) -class PosthogAnalyticsProvider @Inject constructor( +internal class PosthogAnalyticsProvider @Inject constructor( private val postHogFactory: PostHogFactory, ) : AnalyticsProvider { - override val name = PosthogConfig.name + override val name = "Posthog" private var posthog: PostHog? = null private var analyticsId: String? = null diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogConfig.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt similarity index 77% rename from services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogConfig.kt rename to services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt index 96d8659b11..06f10fc07b 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogConfig.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt @@ -16,8 +16,7 @@ package io.element.android.services.analyticsproviders.posthog -object PosthogConfig { - const val name = "Posthog" - const val postHogHost = "https://posthog.element.dev" - const val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN" -} +internal data class PosthogEndpointConfig( + val host: String, + val apiKey: String, +) diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt new file mode 100644 index 0000000000..841f41b807 --- /dev/null +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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.services.analyticsproviders.posthog + +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.core.meta.BuildType +import javax.inject.Inject + +internal class PosthogEndpointConfigProvider @Inject constructor( + private val buildMeta: BuildMeta, +) { + fun provide(): PosthogEndpointConfig { + return when (buildMeta.buildType) { + BuildType.RELEASE -> PosthogEndpointConfig( + host = "https://posthog.element.io", + apiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO", + ) + BuildType.NIGHTLY, + BuildType.DEBUG -> PosthogEndpointConfig( + host = "https://posthog.element.dev", + apiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN", + ) + } + } +} From 3b24990a9fb668fb2dd763f67de1722affc9814c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 11:37:56 +0200 Subject: [PATCH 107/127] changelog. --- changelog.d/1269.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1269.misc diff --git a/changelog.d/1269.misc b/changelog.d/1269.misc new file mode 100644 index 0000000000..1b3205917c --- /dev/null +++ b/changelog.d/1269.misc @@ -0,0 +1 @@ +Ensure Posthog data are sent to "https://posthog.element.io" From cbb27cb5e596b7088fbca4fe4f97bff31df205bc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 12:03:17 +0200 Subject: [PATCH 108/127] Class annotated with `@ContributesMultibinding` cannot be internal. --- .../services/analyticsproviders/posthog/PostHogFactory.kt | 2 +- .../analyticsproviders/posthog/PosthogAnalyticsProvider.kt | 2 +- .../analyticsproviders/posthog/PosthogEndpointConfig.kt | 2 +- .../analyticsproviders/posthog/PosthogEndpointConfigProvider.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt index ca6e5a18e1..40c72142c6 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt @@ -22,7 +22,7 @@ import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.di.ApplicationContext import javax.inject.Inject -internal class PostHogFactory @Inject constructor( +class PostHogFactory @Inject constructor( @ApplicationContext private val context: Context, private val buildMeta: BuildMeta, private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider, diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt index ca5ac527d9..e371c6fef4 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt @@ -32,7 +32,7 @@ import javax.inject.Inject // private val IGNORED_OPTIONS: Options? = null @ContributesMultibinding(AppScope::class) -internal class PosthogAnalyticsProvider @Inject constructor( +class PosthogAnalyticsProvider @Inject constructor( private val postHogFactory: PostHogFactory, ) : AnalyticsProvider { override val name = "Posthog" diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt index 06f10fc07b..a037c53797 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfig.kt @@ -16,7 +16,7 @@ package io.element.android.services.analyticsproviders.posthog -internal data class PosthogEndpointConfig( +data class PosthogEndpointConfig( val host: String, val apiKey: String, ) diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt index 841f41b807..53fdb0947f 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogEndpointConfigProvider.kt @@ -20,7 +20,7 @@ import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import javax.inject.Inject -internal class PosthogEndpointConfigProvider @Inject constructor( +class PosthogEndpointConfigProvider @Inject constructor( private val buildMeta: BuildMeta, ) { fun provide(): PosthogEndpointConfig { From d69728c0ffddf53a1e013c2dbc4a03fdea308fb0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 12:12:48 +0200 Subject: [PATCH 109/127] Fix and add test. --- .../onboarding/impl/OnBoardingPresenterTest.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt index c2db28631c..538fba98d5 100644 --- a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt +++ b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt @@ -20,6 +20,8 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.core.meta.BuildType +import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -33,13 +35,25 @@ class OnBoardingPresenterTest { @Test fun `present - initial state`() = runTest { - val presenter = OnBoardingPresenter() + val presenter = OnBoardingPresenter(aBuildMeta()) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitItem() + assertThat(initialState.isDebugBuild).isTrue() assertThat(initialState.canLoginWithQrCode).isFalse() assertThat(initialState.canCreateAccount).isFalse() } } + + @Test + fun `present - initial state release`() = runTest { + val presenter = OnBoardingPresenter(aBuildMeta(buildType = BuildType.RELEASE)) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.isDebugBuild).isFalse() + } + } } From 995d4e9f6de8c00772fcc7a9c58ff66973a5a628 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 14:51:12 +0200 Subject: [PATCH 110/127] Just try using `actions/checkout@v4` --- .github/workflows/build.yml | 2 +- .github/workflows/danger.yml | 2 +- .github/workflows/gradle-wrapper-update.yml | 2 +- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/maestro.yml | 2 +- .github/workflows/nightly.yml | 2 +- .github/workflows/nightlyReports.yml | 2 +- .github/workflows/quality.yml | 4 ++-- .github/workflows/release.yml | 2 +- .github/workflows/sonar.yml | 2 +- .github/workflows/sync-localazy.yml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 709d7ccd58..724060aa40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: group: ${{ github.ref == 'refs/heads/develop' && format('build-develop-{0}-{1}', matrix.variant, github.sha) || format('build-{0}-{1}', matrix.variant, github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index e2aa8e1266..f05db3c791 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest name: Danger main check steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - run: | npm install --save-dev @babel/plugin-transform-flow-strip-types - name: Danger diff --git a/.github/workflows/gradle-wrapper-update.yml b/.github/workflows/gradle-wrapper-update.yml index f9e998b1a0..351057fc89 100644 --- a/.github/workflows/gradle-wrapper-update.yml +++ b/.github/workflows/gradle-wrapper-update.yml @@ -8,7 +8,7 @@ jobs: update-gradle-wrapper: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Update Gradle Wrapper uses: gradle-update/update-gradle-wrapper-action@v1 # Skip in forks diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index bf1ca46700..4746aa3885 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -11,5 +11,5 @@ jobs: runs-on: ubuntu-latest # No concurrency required, this is a prerequisite to other actions and should run every time. steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - uses: gradle/wrapper-validation-action@v1 diff --git a/.github/workflows/maestro.yml b/.github/workflows/maestro.yml index 6f6edd9a31..8b78a3c447 100644 --- a/.github/workflows/maestro.yml +++ b/.github/workflows/maestro.yml @@ -24,7 +24,7 @@ jobs: group: ${{ format('maestro-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e2b027aebe..179b001131 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository == 'vector-im/element-x-android' }} steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index c1d73117b9..124afbc98f 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -55,7 +55,7 @@ jobs: name: Dependency analysis runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index fad3b13cb2..8fbcacba48 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -17,7 +17,7 @@ jobs: name: Search for forbidden patterns runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Run code quality check suite run: ./tools/check/check_code_quality.sh @@ -29,7 +29,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-develop-{0}', github.sha) || format('check-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b701b7d69e..cc8fc9055c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: group: ${{ github.ref == 'refs/head/main' && format('build-release-main-{0}', github.sha) }} cancel-in-progress: true steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Use JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 3a37e9ead1..f176984476 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -21,7 +21,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('sonar-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('sonar-develop-{0}', github.sha) || format('sonar-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index e4242aa634..f3acb4675b 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -11,7 +11,7 @@ jobs: # Skip in forks if: github.repository == 'vector-im/element-x-android' steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 + - uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: From e6ecedf7bb236dab3062573d65b1721ed34f5997 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 11 Sep 2023 15:24:56 +0200 Subject: [PATCH 111/127] Take screen density into account when requesting thumbnails (#1262) * Take screen density into account when requesting thumbnails Otherwise, we could be asking for images with N size while we needed images for N@2x or N@3x size i.e. --- .../libraries/matrix/ui/media/CoilMediaFetcher.kt | 11 +++++++++-- .../libraries/matrix/ui/media/ImageLoaderFactories.kt | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt index 8b421c6c28..8945c46817 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt @@ -16,6 +16,7 @@ package io.element.android.libraries.matrix.ui.media +import android.content.Context import coil.ImageLoader import coil.decode.DataSource import coil.decode.ImageSource @@ -32,8 +33,10 @@ import okio.Buffer import okio.Path.Companion.toOkioPath import timber.log.Timber import java.nio.ByteBuffer +import kotlin.math.roundToLong internal class CoilMediaFetcher( + private val scalingFunction: (Float) -> Float, private val mediaLoader: MatrixMediaLoader, private val mediaData: MediaRequestData?, private val options: Options @@ -80,8 +83,8 @@ internal class CoilMediaFetcher( private suspend fun fetchThumbnail(mediaSource: MediaSource, kind: MediaRequestData.Kind.Thumbnail, options: Options): FetchResult? { return mediaLoader.loadMediaThumbnail( source = mediaSource, - width = kind.width, - height = kind.height + width = scalingFunction(kind.width.toFloat()).roundToLong(), + height = scalingFunction(kind.height.toFloat()).roundToLong(), ).map { byteArray -> byteArray.asSourceResult(options) }.getOrNull() @@ -102,6 +105,7 @@ internal class CoilMediaFetcher( } class MediaRequestDataFactory( + private val context: Context, private val client: MatrixClient ) : Fetcher.Factory { @@ -111,6 +115,7 @@ internal class CoilMediaFetcher( imageLoader: ImageLoader ): Fetcher { return CoilMediaFetcher( + scalingFunction = { context.resources.displayMetrics.density * it }, mediaLoader = client.mediaLoader, mediaData = data, options = options @@ -119,6 +124,7 @@ internal class CoilMediaFetcher( } class AvatarFactory( + private val context: Context, private val client: MatrixClient ) : Fetcher.Factory { @@ -129,6 +135,7 @@ internal class CoilMediaFetcher( imageLoader: ImageLoader ): Fetcher { return CoilMediaFetcher( + scalingFunction = { context.resources.displayMetrics.density * it }, mediaLoader = client.mediaLoader, mediaData = data.toMediaRequestData(), options = options diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt index c5b7f1ed44..c495558fd9 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt @@ -46,8 +46,8 @@ class LoggedInImageLoaderFactory @Inject constructor( } add(AvatarDataKeyer()) add(MediaRequestDataKeyer()) - add(CoilMediaFetcher.AvatarFactory(matrixClient)) - add(CoilMediaFetcher.MediaRequestDataFactory(matrixClient)) + add(CoilMediaFetcher.AvatarFactory(context, matrixClient)) + add(CoilMediaFetcher.MediaRequestDataFactory(context, matrixClient)) } .build() } From 41061da76825bacd2bc2f5b82883f779af96e8e8 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 11 Sep 2023 15:43:23 +0200 Subject: [PATCH 112/127] [Compound] Bloom (#1253) * Add `bloom` and `avatarBloom` modifiers. * Add `ConnectivityIndicatorContainer` to control the padding needed at the top. --------- Co-authored-by: ElementBot --- changelog.d/1217.feature | 1 + .../api/ui/ConnectivityIndicatorView.kt | 57 +- .../features/roomlist/impl/RoomListView.kt | 13 +- .../impl/components/RoomListTopBar.kt | 235 +++++--- .../designsystem/components/Bloom.kt | 534 ++++++++++++++++++ .../components/avatar/AvatarSize.kt | 2 +- .../designsystem/preview/PreviewGroup.kt | 1 + .../src/main/res/drawable/ic_search.xml | 25 + ...etContent-D-0_1_null_3,NEXUS_5,1.0,en].png | 4 +- ...etContent-N-0_2_null_3,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...temEventRowDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...emEventRowLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...owWithReplyDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...wWithReplyLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...elineView-D-2_3_null_2,NEXUS_5,1.0,en].png | 4 +- ...elineView-D-2_3_null_3,NEXUS_5,1.0,en].png | 4 +- ...elineView-N-2_4_null_2,NEXUS_5,1.0,en].png | 4 +- ...elineView-N-2_4_null_3,NEXUS_5,1.0,en].png | 4 +- ...mListTopBarDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...ListTopBarLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...vatars_Avatar_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...vatars_Avatar_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...vatars_Avatar_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ts_null_Bloom-N_1_null,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_0,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_1,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_2,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_3,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_4,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_5,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_6,NEXUS_5,1.0,en].png | 3 + ...oomInitials-N_1_null_7,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_0,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_1,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_2,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_3,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_4,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_5,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_6,NEXUS_5,1.0,en].png | 3 + ...BloomInitials_0_null_7,NEXUS_5,1.0,en].png | 3 + ...ull_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png | 3 + ...mposerReply-D-3_4_null,NEXUS_5,1.0,en].png | 4 +- ...mposerReply-N-3_5_null,NEXUS_5,1.0,en].png | 4 +- 67 files changed, 913 insertions(+), 173 deletions(-) create mode 100644 changelog.d/1217.feature create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt create mode 100644 libraries/designsystem/src/main/res/drawable/ic_search.xml create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png diff --git a/changelog.d/1217.feature b/changelog.d/1217.feature new file mode 100644 index 0000000000..24941e4ed3 --- /dev/null +++ b/changelog.d/1217.feature @@ -0,0 +1 @@ +Implement Bloom effect modifier. diff --git a/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt b/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt index 855bf067dd..7c03be6a41 100644 --- a/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt +++ b/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt @@ -18,6 +18,9 @@ package io.element.android.features.networkmonitor.api.ui import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.spring import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut @@ -27,34 +30,44 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width -import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WifiOff import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.text.toDp +import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings +/** + * A view that displays a connectivity indicator when the device is offline, adding a default + * padding to make sure the status bar is not overlapped. + */ @Composable fun ConnectivityIndicatorView( isOnline: Boolean, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { val isIndicatorVisible = remember { MutableTransitionState(!isOnline) }.apply { targetState = !isOnline } val isStatusBarPaddingVisible = remember { MutableTransitionState(isOnline) }.apply { targetState = isOnline } @@ -78,6 +91,46 @@ fun ConnectivityIndicatorView( } } +/** + * A view that displays a connectivity indicator when the device is offline, passing the padding + * needed to make sure the status bar is not overlapped to its content views. + */ +@Composable +fun ConnectivityIndicatorContainer( + isOnline: Boolean, + modifier: Modifier = Modifier, + content: @Composable (topPadding: Dp) -> Unit, +) { + val isIndicatorVisible = remember { MutableTransitionState(!isOnline) }.apply { targetState = !isOnline } + + val statusBarTopPadding = if (LocalInspectionMode.current) { + // Needed to get valid UI previews + 24.dp + } else { + WindowInsets.statusBars.asPaddingValues().calculateTopPadding() + 6.dp + } + val target = remember(isOnline) { if (isOnline) 0.dp else statusBarTopPadding } + val animationStateOffset by animateDpAsState( + targetValue = target, + animationSpec = spring( + stiffness = Spring.StiffnessMediumLow, + visibilityThreshold = 1.dp, + ), + label = "insets-animation", + ) + + content(animationStateOffset) + + // Display the network indicator with an animation + AnimatedVisibility( + visibleState = isIndicatorVisible, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically(), + ) { + Indicator(modifier) + } +} + @Composable private fun Indicator(modifier: Modifier = Modifier) { Row( diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index f7f712fbc3..80d183a91b 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -18,13 +18,13 @@ package io.element.android.features.roomlist.impl import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState @@ -45,7 +45,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Velocity import androidx.compose.ui.unit.dp import io.element.android.features.leaveroom.api.LeaveRoomView -import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView +import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer import io.element.android.features.roomlist.impl.components.RequestVerificationHeader import io.element.android.features.roomlist.impl.components.RoomListMenuAction import io.element.android.features.roomlist.impl.components.RoomListTopBar @@ -76,8 +76,10 @@ fun RoomListView( onMenuActionClicked: (RoomListMenuAction) -> Unit, modifier: Modifier = Modifier, ) { - Column(modifier = modifier) { - ConnectivityIndicatorView(isOnline = state.hasNetworkConnection) + ConnectivityIndicatorContainer( + modifier = modifier, + isOnline = state.hasNetworkConnection, + ) { topPadding -> Box { fun onRoomLongClicked( roomListRoomSummary: RoomListRoomSummary @@ -96,6 +98,7 @@ fun RoomListView( LeaveRoomView(state = state.leaveRoomState) RoomListContent( + modifier = Modifier.padding(top = topPadding), state = state, onVerifyClicked = onVerifyClicked, onRoomClicked = onRoomClicked, @@ -111,6 +114,8 @@ fun RoomListView( onRoomClicked = onRoomClicked, onRoomLongClicked = { onRoomLongClicked(it) }, modifier = Modifier + .statusBarsPadding() + .padding(top = topPadding) .fillMaxSize() .background(MaterialTheme.colorScheme.background) ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 001c048e4e..a5113d33ce 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -17,10 +17,13 @@ package io.element.android.features.roomlist.impl.components import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.statusBars +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.outlined.BugReport import androidx.compose.material.icons.outlined.Share import androidx.compose.material3.ExperimentalMaterial3Api @@ -30,24 +33,37 @@ import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import io.element.android.features.roomlist.impl.R import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatarBloom import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.text.applyScaleDown +import io.element.android.libraries.designsystem.text.roundToPx +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.designsystem.text.toSp import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.DropdownMenu import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem +import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar @@ -60,6 +76,9 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.libraries.designsystem.R as CommonR + +private val avatarBloomSize = 430.dp @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -89,6 +108,7 @@ fun RoomListTopBar( DefaultRoomListTopBar( matrixUser = matrixUser, + areSearchResultsDisplayed = areSearchResultsDisplayed, onOpenSettings = onOpenSettings, onSearchClicked = onToggleSearch, onMenuActionClicked = onMenuActionClicked, @@ -101,6 +121,7 @@ fun RoomListTopBar( @Composable private fun DefaultRoomListTopBar( matrixUser: MatrixUser?, + areSearchResultsDisplayed: Boolean, scrollBehavior: TopAppBarScrollBehavior, onOpenSettings: () -> Unit, onSearchClicked: () -> Unit, @@ -108,94 +129,139 @@ private fun DefaultRoomListTopBar( modifier: Modifier = Modifier, ) { var showMenu by remember { mutableStateOf(false) } - MediumTopAppBar( - modifier = modifier - .nestedScroll(scrollBehavior.nestedScrollConnection), - title = { - val fontStyle = if (scrollBehavior.state.collapsedFraction > 0.5) - ElementTheme.typography.aliasScreenTitle - else - ElementTheme.typography.fontHeadingLgBold.copy( - // Due to a limitation of MediumTopAppBar, and to avoid the text to be truncated, - // ensure that the font size will never be bigger than 28.dp. - fontSize = 28.dp.applyScaleDown().toSp() - ) - Text( - style = fontStyle, - text = stringResource(id = R.string.screen_roomlist_main_space_title) - ) - }, - navigationIcon = { - if (matrixUser != null) { - IconButton( - modifier = Modifier.testTag(TestTags.homeScreenSettings), - onClick = onOpenSettings - ) { - val avatarData by remember { - derivedStateOf { - matrixUser.getAvatarData(size = AvatarSize.CurrentUserTopBar) - } - } - Avatar(avatarData, contentDescription = stringResource(CommonStrings.common_settings)) + + // We need this to manually clip the top app bar in preview mode + val previewAppBarHeight = if (LocalInspectionMode.current) { + 112.dp.roundToPx() + } else { + null + } + val collapsedFraction = scrollBehavior.state.collapsedFraction + var appBarHeight by remember { + mutableIntStateOf(previewAppBarHeight ?: 0) + } + + val avatarData by remember(matrixUser) { + derivedStateOf { + matrixUser?.getAvatarData(size = AvatarSize.CurrentUserTopBar) + } + } + + val statusBarPadding = with (LocalDensity.current) { WindowInsets.statusBars.getTop(this).toDp() } + + Box(modifier = modifier) { + MediumTopAppBar( + modifier = Modifier + .onSizeChanged { + appBarHeight = it.height } - } - }, - actions = { - IconButton( - onClick = onSearchClicked, - ) { - Icon( - imageVector = Icons.Default.Search, - tint = ElementTheme.materialColors.secondary, - contentDescription = stringResource(CommonStrings.action_search), + .nestedScroll(scrollBehavior.nestedScrollConnection) + .avatarBloom( + avatarData = avatarData, + background = ElementTheme.materialColors.background, + blurSize = DpSize(avatarBloomSize, avatarBloomSize), + offset = DpOffset(24.dp, 24.dp + statusBarPadding), + clipToSize = if (appBarHeight > 0) DpSize( + avatarBloomSize, + appBarHeight.toDp() + ) else DpSize.Unspecified, + bottomSoftEdgeAlpha = 1f - collapsedFraction, + alpha = if (areSearchResultsDisplayed) 0f else 1f, ) - } - IconButton( - onClick = { showMenu = !showMenu } - ) { - Icon( - imageVector = Icons.Default.MoreVert, - tint = ElementTheme.materialColors.secondary, - contentDescription = null, + .statusBarsPadding(), + colors = TopAppBarDefaults.mediumTopAppBarColors( + containerColor = Color.Transparent, + scrolledContainerColor = Color.Transparent, + ), + title = { + val fontStyle = if (scrollBehavior.state.collapsedFraction > 0.5) + ElementTheme.typography.aliasScreenTitle + else + ElementTheme.typography.fontHeadingLgBold.copy( + // Due to a limitation of MediumTopAppBar, and to avoid the text to be truncated, + // ensure that the font size will never be bigger than 28.dp. + fontSize = 28.dp.applyScaleDown().toSp() + ) + Text( + style = fontStyle, + text = stringResource(id = R.string.screen_roomlist_main_space_title) ) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClicked(RoomListMenuAction.InviteFriends) - }, - text = { Text(stringResource(id = CommonStrings.action_invite)) }, - leadingIcon = { - Icon( - Icons.Outlined.Share, - tint = ElementTheme.materialColors.secondary, - contentDescription = null, + }, + navigationIcon = { + avatarData?.let { + IconButton( + modifier = Modifier.testTag(TestTags.homeScreenSettings), + onClick = onOpenSettings + ) { + Avatar( + avatarData = it, + contentDescription = stringResource(CommonStrings.common_settings), ) } - ) - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClicked(RoomListMenuAction.ReportBug) - }, - text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) }, - leadingIcon = { - Icon( - Icons.Outlined.BugReport, - tint = ElementTheme.materialColors.secondary, - contentDescription = null, - ) - } - ) - } - }, - scrollBehavior = scrollBehavior, - windowInsets = WindowInsets(0.dp), - ) + } + }, + actions = { + IconButton( + onClick = onSearchClicked, + ) { + Icon( + resourceId = CommonR.drawable.ic_search, + contentDescription = stringResource(CommonStrings.action_search), + ) + } + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = null, + ) + } + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.InviteFriends) + }, + text = { Text(stringResource(id = CommonStrings.action_invite)) }, + leadingIcon = { + Icon( + Icons.Outlined.Share, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + ) + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.ReportBug) + }, + text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) }, + leadingIcon = { + Icon( + Icons.Outlined.BugReport, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + ) + } + }, + scrollBehavior = scrollBehavior, + windowInsets = WindowInsets(0.dp), + ) + + HorizontalDivider(modifier = + Modifier.fillMaxWidth() + .alpha(collapsedFraction) + .align(Alignment.BottomCenter), + color = ElementTheme.materialColors.outlineVariant, + ) + } } @Preview @@ -211,6 +277,7 @@ internal fun DefaultRoomListTopBarDarkPreview() = ElementPreviewDark { DefaultRo private fun DefaultRoomListTopBarPreview() { DefaultRoomListTopBar( matrixUser = MatrixUser(UserId("@id:domain"), "Alice"), + areSearchResultsDisplayed = false, scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), onOpenSettings = {}, onSearchClicked = {}, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt new file mode 100644 index 0000000000..5e1d7116ba --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2023 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.libraries.designsystem.components + +import android.graphics.Bitmap +import android.graphics.Typeface +import android.graphics.drawable.BitmapDrawable +import android.os.Build +import android.text.TextPaint +import androidx.annotation.FloatRange +import androidx.compose.foundation.Image +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Share +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.IconButton +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.rememberTopAppBarState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.geometry.center +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.ClipOp +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.LinearGradientShader +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.RadialGradientShader +import androidx.compose.ui.graphics.ShaderBrush +import androidx.compose.ui.graphics.asAndroidBitmap +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.clipPath +import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalFontFamilyResolver +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.isSpecified +import androidx.compose.ui.unit.toOffset +import androidx.compose.ui.unit.toSize +import coil.compose.rememberAsyncImagePainter +import coil.request.ImageRequest +import com.airbnb.android.showkase.annotation.ShowkaseComposable +import com.vanniktech.blurhash.BlurHash +import io.element.android.libraries.designsystem.R +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.designsystem.text.toDp +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar +import io.element.android.libraries.designsystem.theme.components.Scaffold +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.ElementTheme +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlin.math.max +import kotlin.math.roundToInt + +/** + * Default bloom configuration values. + */ +object BloomDefaults { + /** + * Number of components to use with BlurHash to generate the blur effect. + * Larger values mean more detailed blurs. + */ + const val HASH_COMPONENTS = 8 + + /** Default bloom layers. */ + @Composable + fun defaultLayers() = persistentListOf( + // Bottom layer + if (isSystemInDarkTheme()) { + BloomLayer(0.5f, BlendMode.Exclusion) + } else { + BloomLayer(0.2f, BlendMode.Hardlight) + }, + // Top layer + BloomLayer(if (isSystemInDarkTheme()) 0.2f else 0.8f, BlendMode.Color), + ) +} + +/** + * Bloom layer configuration. + * @param alpha The alpha value to apply to the layer. + * @param blendMode The blend mode to apply to the layer. + */ +data class BloomLayer( + val alpha: Float, + val blendMode: BlendMode, +) + +/** + * Bloom effect modifier. Applies a bloom effect to the component. + * @param hash The BlurHash to use as the bloom source. + * @param background The background color to use for the bloom effect. Since we use blend modes it must be non-transparent. + * @param blurSize The size of the bloom effect. If not specified the bloom effect will be the size of the component. + * @param offset The offset to use for the bloom effect. If not specified the bloom effect will be centered on the component. + * @param clipToSize The size to use for clipping the bloom effect. If not specified the bloom effect will not be clipped. + * @param layerConfiguration The configuration for the bloom layers. If not specified the default layers configuration will be used. + * @param bottomSoftEdgeHeight The height of the bottom soft edge. If not specified the bottom soft edge will not be drawn. + * @param bottomSoftEdgeAlpha The alpha value to apply to the bottom soft edge. + * @param alpha The alpha value to apply to the bloom effect. + */ +fun Modifier.bloom( + hash: String?, + background: Color, + blurSize: DpSize = DpSize.Unspecified, + offset: DpOffset = DpOffset.Unspecified, + clipToSize: DpSize = DpSize.Unspecified, + layerConfiguration: ImmutableList? = null, + bottomSoftEdgeHeight: Dp = 40.dp, + @FloatRange(from = 0.0, to = 1.0) + bottomSoftEdgeAlpha: Float = 1.0f, + @FloatRange(from = 0.0, to = 1.0) + alpha: Float = 1f, +) = composed { + val defaultLayers = BloomDefaults.defaultLayers() + val layers = layerConfiguration ?: defaultLayers + // Bloom only works on API 29+ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return@composed this + if (hash == null) return@composed this + + val hashedBitmap = remember(hash) { + BlurHash.decode(hash, BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS)?.asImageBitmap() + } ?: return@composed this + val density = LocalDensity.current + val pixelSize = remember(blurSize, density) { blurSize.toIntSize(density) } + val clipToPixelSize = remember(clipToSize, density) { clipToSize.toIntSize(density) } + val bottomSoftEdgeHeightPixels = remember(bottomSoftEdgeHeight, density) { with(density) { bottomSoftEdgeHeight.roundToPx() } } + val isRTL = LocalLayoutDirection.current == LayoutDirection.Rtl + drawWithCache { + val dstSize = if (pixelSize != IntSize.Zero) { + pixelSize + } else { + IntSize(size.width.toInt(), size.height.toInt()) + } + // Calculate where to place the center of the bloom effect + val centerOffset = if (offset.isSpecified) { + if (isRTL) { + IntOffset( + size.width.roundToInt() - offset.x.roundToPx(), + size.height.roundToInt() - offset.y.roundToPx(), + ) + } else { + IntOffset( + offset.x.roundToPx(), + offset.y.roundToPx(), + ) + } + } else { + IntOffset( + size.center.x.toInt(), + size.center.y.toInt(), + ) + } + // Calculate the offset to draw the different layers and apply clipping + // This offset is applied to place the top left corner of the bloom effect + val layersOffset = if (offset.isSpecified) { + // Offsets the layers so the center of the bloom effect is at the provided offset value + IntOffset( + centerOffset.x - dstSize.width / 2, + centerOffset.y - dstSize.height / 2, + ) + } else { + // Places the layers at the center of the component + IntOffset.Zero + } + val radius = max(dstSize.width, dstSize.height).toFloat() / 2 + val circularGradientShader = RadialGradientShader( + centerOffset.toOffset(), + radius, + listOf(Color.Red, Color.Transparent), + listOf(0f, 1f) + ) + val circularGradientBrush = ShaderBrush(circularGradientShader) + val bottomEdgeGradient = LinearGradientShader( + from = IntOffset(0, clipToPixelSize.height - bottomSoftEdgeHeightPixels).toOffset(), + to = IntOffset(0, clipToPixelSize.height).toOffset(), + listOf(Color.Transparent, background), + listOf(0f, 1f) + ) + val bottomEdgeGradientBrush = ShaderBrush(bottomEdgeGradient) + onDrawBehind { + if (dstSize != IntSize.Zero) { + val circleClipPath = Path().apply { + addOval(Rect(centerOffset.toOffset(), radius - 1)) + } + // Clip the external radius of bloom gradient too, otherwise we have a 1px border + clipPath(circleClipPath, clipOp = ClipOp.Intersect) { + // Draw the bloom layers + drawWithLayer { + // Clip rect to the provided size if needed + if (clipToPixelSize != IntSize.Zero) { + drawContext.canvas.clipRect(Rect(Offset.Zero, clipToPixelSize.toSize()), ClipOp.Intersect) + } + // Draw background color for blending + drawRect(background, size = pixelSize.toSize()) + // Draw layers + for (layer in layers) { + drawImage( + hashedBitmap, + srcSize = IntSize(BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS), + dstSize = dstSize, + dstOffset = layersOffset, + alpha = layer.alpha * alpha, + blendMode = layer.blendMode, + ) + } + // Mask the layers erasing the outer radius using the gradient brush + drawCircle( + circularGradientBrush, + radius, + centerOffset.toOffset(), + blendMode = BlendMode.DstIn + ) + } + } + // Draw the bottom soft edge + drawRect( + bottomEdgeGradientBrush, + topLeft = IntOffset(0, clipToPixelSize.height - bottomSoftEdgeHeight.roundToPx()).toOffset(), + size = IntSize(pixelSize.width, bottomSoftEdgeHeight.roundToPx()).toSize(), + alpha = bottomSoftEdgeAlpha + ) + } + } + } +} + +/** + * Bloom effect modifier for avatars. Applies a bloom effect to the component. + * @param avatarData The avatar data to use as the bloom source. + * If the avatar data has a URL it will be used as the bloom source, otherwise the initials will be used. If `null` is passed, no bloom effect will be applied. + * @param background The background color to use for the bloom effect. Since we use blend modes it must be non-transparent. + * @param blurSize The size of the bloom effect. If not specified the bloom effect will be the size of the component. + * @param offset The offset to use for the bloom effect. If not specified the bloom effect will be centered on the component. + * @param clipToSize The size to use for clipping the bloom effect. If not specified the bloom effect will not be clipped. + * @param bottomSoftEdgeHeight The height of the bottom soft edge. If not specified the bottom soft edge will not be drawn. + * @param bottomSoftEdgeAlpha The alpha value to apply to the bottom soft edge. + * @param alpha The alpha value to apply to the bloom effect. + */ +fun Modifier.avatarBloom( + avatarData: AvatarData?, + background: Color, + blurSize: DpSize = DpSize.Unspecified, + offset: DpOffset = DpOffset.Unspecified, + clipToSize: DpSize = DpSize.Unspecified, + bottomSoftEdgeHeight: Dp = 40.dp, + @FloatRange(from = 0.0, to = 1.0) + bottomSoftEdgeAlpha: Float = 1.0f, + @FloatRange(from = 0.0, to = 1.0) + alpha: Float = 1f, +) = composed { + // Bloom only works on API 29+ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return@composed this + avatarData ?: return@composed this + + if (avatarData.url != null) { + // Request the avatar contents to use as the bloom source + val painter = rememberAsyncImagePainter( + ImageRequest.Builder(LocalContext.current) + .data(avatarData) + // Needed to be able to read pixels from the Bitmap for the hash + .allowHardware(false) + .build() + ) + var blurHash by remember { mutableStateOf(null) } + + LaunchedEffect(avatarData) { + val drawable = painter.imageLoader.execute(painter.request).drawable ?: return@LaunchedEffect + val bitmap = (drawable as? BitmapDrawable)?.bitmap ?: return@LaunchedEffect + blurHash = BlurHash.encode(bitmap, BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS) + } + + bloom( + hash = blurHash, + background = background, + blurSize = blurSize, + offset = offset, + clipToSize = clipToSize, + bottomSoftEdgeHeight = bottomSoftEdgeHeight, + bottomSoftEdgeAlpha = bottomSoftEdgeAlpha, + alpha = alpha, + ) + } else { + // There is no URL so we'll generate an avatar with the initials and use that as the bloom source + val avatarColors = AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) + val initialsBitmap = initialsBitmap( + width = avatarData.size.dp, + height = avatarData.size.dp, + text = avatarData.initial, + textColor = avatarColors.foreground, + backgroundColor = avatarColors.background, + ) + val hash = remember(avatarData, avatarColors) { + BlurHash.encode(initialsBitmap.asAndroidBitmap(), BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS) + } + bloom( + hash = hash, + background = background, + blurSize = blurSize, + offset = offset, + clipToSize = clipToSize, + bottomSoftEdgeHeight = bottomSoftEdgeHeight, + bottomSoftEdgeAlpha = bottomSoftEdgeAlpha, + alpha = alpha, + ) + } +} + +// Used to create a Bitmap version of the initials avatar +@Composable +private fun initialsBitmap( + text: String, + backgroundColor: Color, + textColor: Color, + width: Dp = 32.dp, + height: Dp = 32.dp, +): ImageBitmap = with(LocalDensity.current) { + val backgroundPaint = remember(backgroundColor) { + Paint().also { it.color = backgroundColor } + } + val resolver: FontFamily.Resolver = LocalFontFamilyResolver.current + val fontSize = remember { height.toSp() / 2 } + val typeface: Typeface = remember(resolver) { + resolver.resolve( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontStyle = FontStyle.Normal, + ) + }.value as Typeface + val textPaint = remember(textColor, typeface) { + TextPaint().apply { + color = textColor.toArgb() + textSize = fontSize.toPx() + this.typeface = typeface + } + } + val textMeasurer = rememberTextMeasurer() + val result = remember(text) { textMeasurer.measure(text, TextStyle.Default.copy(fontSize = fontSize)) } + val centerPx = remember(width, height) { IntOffset(width.roundToPx() / 2, height.roundToPx() / 2) } + remember(text, width, height, backgroundColor, textColor) { + val bitmap = Bitmap.createBitmap(width.roundToPx(), height.roundToPx(), Bitmap.Config.ARGB_8888).asImageBitmap() + androidx.compose.ui.graphics.Canvas(bitmap).also { canvas -> + canvas.drawCircle(centerPx.toOffset(), width.toPx() / 2, backgroundPaint) + canvas.nativeCanvas.drawText(text, centerPx.x.toFloat() - result.size.width/2, centerPx.y * 2f - result.size.height/2 - 4, textPaint) + } + bitmap + } +} + +// Translates DP sizes into pixel sizes, taking into account unspecified values +private fun DpSize.toIntSize(density: Density) = with(density) { + if (isSpecified) { + IntSize(width.roundToPx(), height.roundToPx()) + } else { + IntSize.Zero + } +} + +/** + * Helper to draw to a canvas using layers. This allows us to apply clipping to those layers only. + */ +fun DrawScope.drawWithLayer(block: DrawScope.() -> Unit) { + with(drawContext.canvas.nativeCanvas) { + val checkPoint = saveLayer(null, null) + block() + restoreToCount(checkPoint) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@DayNightPreviews +@ShowkaseComposable(group = PreviewGroup.Bloom) +@Composable +internal fun BloomPreview() { + val blurhash = "eePn{tI?xExEja}ooKWWodjtNJoKR,j@a|sBWpS3WDbGazoKWWWWj@" + var topAppBarHeight by remember { mutableIntStateOf(-1) } + val topAppBarState = rememberTopAppBarState() + val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(topAppBarState) + ElementPreview { + Scaffold( + modifier = Modifier.fillMaxSize().nestedScroll(scrollBehavior.nestedScrollConnection), + topBar = { + Box { + MediumTopAppBar( + modifier = Modifier + .onSizeChanged { size -> + topAppBarHeight = size.height + } + .bloom( + hash = blurhash, + background = ElementTheme.materialColors.background, + blurSize = DpSize(430.dp, 430.dp), + offset = DpOffset(24.dp, 24.dp), + clipToSize = if (topAppBarHeight > 0) DpSize(430.dp, topAppBarHeight.toDp()) else DpSize.Zero, + ), + colors = TopAppBarDefaults.largeTopAppBarColors( + containerColor = Color.Transparent, + scrolledContainerColor = Color.Black.copy(alpha = 0.05f), + ), + navigationIcon = { + Image( + modifier = Modifier + .padding(start = 8.dp) + .size(32.dp) + .clip(CircleShape), + painter = painterResource(id = R.drawable.sample_avatar), + contentScale = ContentScale.Crop, + contentDescription = null + ) + }, + actions = { + IconButton(onClick = {}) { + Icon(imageVector = Icons.Default.Share, contentDescription = null) + } + }, + title = { + Text("Title") + }, + scrollBehavior = scrollBehavior, + ) + } + }, + ) { paddingValues -> + Column( + modifier = Modifier + .padding(paddingValues) + .consumeWindowInsets(paddingValues) + .fillMaxSize() + .verticalScroll(rememberScrollState()), + ) { + repeat(20) { + Text("Content", modifier = Modifier.padding(vertical = 20.dp)) + } + } + } + } +} + +class InitialsColorStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf(0, 1, 2, 3, 4, 5, 6, 7) +} + +@DayNightPreviews +@Composable +@ShowkaseComposable(group = PreviewGroup.Bloom) +internal fun BloomInitialsPreview(@PreviewParameter(InitialsColorStateProvider::class) color: Int) { + ElementPreview { + val avatarColors = AvatarColorsProvider.provide("$color", ElementTheme.isLightTheme) + val bitmap = initialsBitmap(text = "F", backgroundColor = avatarColors.background, textColor = avatarColors.foreground) + val hash = BlurHash.encode(bitmap.asAndroidBitmap(), BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS) + Box( + modifier = Modifier.size(256.dp) + .bloom( + hash = hash, + background = ElementTheme.materialColors.background, + blurSize = DpSize(256.dp, 256.dp), + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .size(32.dp) + .clip(CircleShape), + painter = BitmapPainter(bitmap), + contentDescription = null + ) + } + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 372aecea32..38b1df6dce 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp enum class AvatarSize(val dp: Dp) { - CurrentUserTopBar(28.dp), + CurrentUserTopBar(32.dp), RoomHeader(96.dp), RoomListItem(52.dp), diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt index 8bfd198f1c..a1f458ee08 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt @@ -19,6 +19,7 @@ package io.element.android.libraries.designsystem.preview object PreviewGroup { const val AppBars = "App Bars" const val Avatars = "Avatars" + const val Bloom = "Bloom" const val BottomSheets = "Bottom Sheets" const val Buttons = "Buttons" const val DateTimePickers = "DateTime pickers" diff --git a/libraries/designsystem/src/main/res/drawable/ic_search.xml b/libraries/designsystem/src/main/res/drawable/ic_search.xml new file mode 100644 index 0000000000..440aef72f6 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_search.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png index 1f851222f4..540f71b5a7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8421be9fe6518a4a610e561692352c28c63b1e588fae4f7617f6be94439852f2 -size 45078 +oid sha256:ee62a7f77e591d238878e72e3f2fbe489e8c4e8c6a5c121b16e120ad5c43836d +size 44185 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png index 8fae4446ea..cf7a8a2c81 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c30a6c0c7169044216a02dde5605d59fba9307499855ffc1fa0d3fcd1650f5e -size 43291 +oid sha256:d4bdf3944d30980e9bfd7cfffbabe2dac9861748cc3006e751bfd5cbf59c86db +size 42475 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png index affcb49660..7ff6d4dec6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c40273c36eb1479f284e75fa91d4a75b1ae97edd0242dda37a2d4a8f10394928 -size 138700 +oid sha256:6c0485788c8776536a01613058ab001bad02a67519cf0cb4892505c7c3715fea +size 144681 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png index cb4b57910b..7dae7dddb0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7c47c713c74766c39d3b349d9e421ea588261e043105a5475cd8e68af782806 -size 185325 +oid sha256:b4a259f036e555fdc52ecc8f0c9578dae70ed677235fbfd344bc31cbabc76be5 +size 181478 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png index db705106e0..00c4b05824 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d5479f3a6ea138b00c8f6a376cc4a67984385a087fb32bcdb764b2996e89402 -size 137137 +oid sha256:d5966cae164fed6a3a12c1e1dd940ae7b0601e4ba69d11f49d18740bdab8c520 +size 130130 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png index affcb49660..7ff6d4dec6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c40273c36eb1479f284e75fa91d4a75b1ae97edd0242dda37a2d4a8f10394928 -size 138700 +oid sha256:6c0485788c8776536a01613058ab001bad02a67519cf0cb4892505c7c3715fea +size 144681 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png index cb4b57910b..7dae7dddb0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7c47c713c74766c39d3b349d9e421ea588261e043105a5475cd8e68af782806 -size 185325 +oid sha256:b4a259f036e555fdc52ecc8f0c9578dae70ed677235fbfd344bc31cbabc76be5 +size 181478 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png index db705106e0..a603a6cc61 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d5479f3a6ea138b00c8f6a376cc4a67984385a087fb32bcdb764b2996e89402 -size 137137 +oid sha256:b8cb21e08faf31779111d78c2be1e4e68e6f3bc994b16c108bd654f13d39fa02 +size 130130 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png index 5361cd1a24..0e6ff544a1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06617cda0f93ce0ea26b2a77a243371cdaf4f9a2956d8159ecb7196f7f6fe082 -size 139282 +oid sha256:f2782edd31f68b7aa27e0c35b29d7c84574326cb56c65394738357479d408f5f +size 144667 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png index 0e14867b04..b8b527778b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55d2d11ba729a68b1b62e9a69c3308594839fdb3612ff3db59850f0b346c28da -size 186118 +oid sha256:cd352f748e3fd08225aa714181fdc18d53e91a8c62f8e5e860b67ff5aaeb7b8e +size 181969 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png index da8a3d6499..6ee90c4b3a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62c57a45c2cb1aac23fa0c3af44f90a5d7b9a1e1626ec49eb94a2c126f53f96d -size 137535 +oid sha256:43da903ec671dd1cb591396306ce8c057432ffa8c1bfce7a509f28576e82b530 +size 130337 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png index 5361cd1a24..0e6ff544a1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06617cda0f93ce0ea26b2a77a243371cdaf4f9a2956d8159ecb7196f7f6fe082 -size 139282 +oid sha256:f2782edd31f68b7aa27e0c35b29d7c84574326cb56c65394738357479d408f5f +size 144667 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png index 0e14867b04..b8b527778b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55d2d11ba729a68b1b62e9a69c3308594839fdb3612ff3db59850f0b346c28da -size 186118 +oid sha256:cd352f748e3fd08225aa714181fdc18d53e91a8c62f8e5e860b67ff5aaeb7b8e +size 181969 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png index da8a3d6499..c4150178a1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62c57a45c2cb1aac23fa0c3af44f90a5d7b9a1e1626ec49eb94a2c126f53f96d -size 137535 +oid sha256:8141eaa257454258d2926df5ee970daf5ee165b774e4b948256b90e22a388d4c +size 130337 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png index 722bd8c6a5..5fd48ba7e6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0ad6895582183b697732ef032f89a6a0cad32106c9bbf30925c390dcab65ee6 -size 151752 +oid sha256:f95fbf1b51966c1c6b7b149c771f33400455d3c999b505e1aa65f0e3eb41c0ef +size 140928 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png index fb9457779e..3798fc1bc8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:676b62ab782652c45a7267aac5df12943fd181bea48964d28dce664884ae4182 -size 156619 +oid sha256:e8d522eb99079792d010e053d488f78a95e91f5a1b614b9d512bd005f0df81cf +size 146976 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png index c39b41db87..5bc3b72bec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b991a34a137d82ff4dedf48316a05ebbc008233984b11af70e64889a5fb5eda8 -size 127438 +oid sha256:eebf95f938f483da9b087eda86ae4a1baac594bc4b6f1f893d869b759679526c +size 123267 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png index a6500ca748..6e52c4b6d3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43b6514716d18382c8962520928d9d2ff6d0f665b2471e8a24e5d2e44a25c88c -size 132295 +oid sha256:4875df98092a8ef8bd1c2fda8c4a038ae2830b9ffa57e4ab71859523f97c26c9 +size 128062 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png index 307e6a7acf..18e6545be9 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d7bc773e70c57226840b30675f14a7fd99026100d61f48eeab64fb55d43f7c6 -size 230426 +oid sha256:30119e8fcb65e8cbf058191268f0d70633a62b160b9f49f71879272d0d076537 +size 241818 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png index 4d97155b83..cc3ad6b40e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87f93b06f658352e7d97617c28dc0a4bd7454263fd402abfc2676f548c41d6b2 -size 231314 +oid sha256:73ca2b85c0f1f8f13cd3a0aae9d394116a460aa2c511ca1f2672a356eee496d2 +size 241553 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png index 946096b37e..7fa7a38d87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f13fbb9bc776fa230b69c41e3faab659c52083d4e4f737f84b472c966f42c8dd -size 229746 +oid sha256:ff7953fabf75b346e61bd4335f3753331b498dbe5f17f9af3aad8a6a1ce051cd +size 239490 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png index 419a96a180..45eafc5baa 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d312c80758e940b368e0b9eb2d41efb55c158691164bfde3456d7540080e46a9 -size 230651 +oid sha256:e262b1128df681c9a98bbefe426a891d02e0500646319f2e1756c1b5c93f2d23 +size 239303 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png index 48f8da47ee..434058e988 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbfb4b373449d3ce3ff06ad67e8c4ecfcbb0ec8d0bcb400d3c010952d11e8ad5 -size 10480 +oid sha256:51931b01aa27677c8d29a79bf92f4e8b48fc2be05e80fdabedfb9026dcbd8899 +size 31634 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png index 82c658503e..70b7534b8c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d0cc556a6c431fc0f10958a4760fe63d0dd3d7f976ce3507643308c50f37c2e -size 10381 +oid sha256:5441c89fc077720b52479d4daf1ebd5fe5b98b63f35141a550dac228fe1c649f +size 10617 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png index c00ff9fa1a..c6ce4ced6b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66bf2e3b890ab75c77f1a9e4e80a374cbb5af35e72b8f53c86424c56f1a9f524 -size 36582 +oid sha256:9156202a9f621b75cff3ca45aac33d72a938620049948828fc34aab3b9e0980d +size 55382 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png index d47352bb7c..21a3ec4a13 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1aff1b446de80f7535a71fbc77d7955a679ff2846bb240b70f2d410114f29b16 -size 59749 +oid sha256:0c7ee3acbf4653e49633e68f896fe0f5f73591c2cbc889204cc244b319996e0d +size 78348 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png index c00ff9fa1a..c6ce4ced6b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66bf2e3b890ab75c77f1a9e4e80a374cbb5af35e72b8f53c86424c56f1a9f524 -size 36582 +oid sha256:9156202a9f621b75cff3ca45aac33d72a938620049948828fc34aab3b9e0980d +size 55382 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png index d054685464..3cc44b882b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fd240006e3b08b081fccdcc29cb8911fbde7f923c4f8207de817ea6a42d3d6f -size 38475 +oid sha256:55800431dfe4453fa3c11f97bfae53ceaf95f1c18b72bcc8620b8c3295b26b27 +size 56388 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png index 144beef563..0f8a496726 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77d78ad2cabaac211517c129a42d8164b02ba2cc5b75a13f27f2ae113b2b9f06 -size 37924 +oid sha256:b2d288f46eb76b8a71a8c1a2ec60ba7c3b8b1bf2a92be9d8daf33c06b3a0f126 +size 56593 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png index 7125e2cb27..0306387553 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9701408630ece8c6178e792920688eb41a8fe1a4621c45f8cf34338f134dded2 -size 38290 +oid sha256:c0e5bc6abe96bff50960c5ace2c4eccd5aabdd9f3ccd015fae867b4c3bc2b423 +size 56902 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png index c12e094911..6b5e25ce2f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56f0ecce5efe141fa2181e2c16dc654e79c4de43cb11b18004b03ce2ddad991d -size 38801 +oid sha256:1f385e70f3a8bda7c0c2f7c090ba665575239299472c0fbd62f2821783ceb065 +size 39016 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png index 87770b930d..c0b73d2764 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9d7be89279d30e82a689654eac67137678ca4eb079e80372011580bcf0e9e22 -size 62757 +oid sha256:4bdb22d629e4bc3273aac4944802d1c91b43065858f4f4cc90052bd78ae6dd89 +size 62998 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png index c12e094911..6b5e25ce2f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56f0ecce5efe141fa2181e2c16dc654e79c4de43cb11b18004b03ce2ddad991d -size 38801 +oid sha256:1f385e70f3a8bda7c0c2f7c090ba665575239299472c0fbd62f2821783ceb065 +size 39016 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png index 861787a0b8..8fe1fefb5d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db76df516d6c7a4bff5b830e423145c448b076846b8b7f75032be6f65585cd31 -size 40846 +oid sha256:8ec1d951c96737ff8c5b401ef7c3af944f76be69348559401e40a12f60d5d459 +size 40807 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png index 0968936113..c0550bff56 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:405842db16444b958899fe174ca1c0157c0c6384f8ae0be37be104de8613f140 -size 40126 +oid sha256:ef7d9c31a72334294e93c67af1ca068ddff0062ae909ee8b682f0117c5c0ab6c +size 40331 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png index 1033a71853..340f3d07c3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:658ee0f231146446810d7c0d09d280148d68475d2411c59cf0ac70caabf4e3ec -size 40496 +oid sha256:54ebfc606c04f37ed72edf5e9168a55628b59e69ea8a03cc3925cf25ca807195 +size 40695 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png index 9b60e19c06..b0851b0bde 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a2a737eb81f74c50efb44c03ac9eb528c38ff393dc1a32efa0c148e27da4668 -size 17880 +oid sha256:877bec872499d1a1f15b50c95c507be6233a2ea121cf3429e255b3bde66c1d7b +size 18331 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png index fbbc1e6a37..3cf0d12761 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff929a3cfa47f93176817cc844b9ef2f5ff6146f016606515efe858fadd00247 -size 17199 +oid sha256:84da3f320738e96b2c90724b278b0b2538e55f4089753f10e4913f7f759fd1c3 +size 17533 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_2,NEXUS_5,1.0,en].png index d05e5b744b..2b087814f2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.avatar_null_Avatars_Avatar_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9b589643f99328d44a38a263b50c4447df7104a6fc0494dd80bbb2920752cb1 -size 19519 +oid sha256:ce86a5fe5ee55b411bd1f76b59e12baafb0cbc963251c9e58d047b1a2a200331 +size 20274 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..42af4e3ccb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bd86a694456603dce070a7bef0646e553cefdb365f81c9d835b28d6b2521950 +size 71026 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..622b4080c5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67be26f120cbce266651737206a5f444b9a0605a4528cea30971f4629b340501 +size 85653 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2006811bc7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7142834262eb7db1909a5a48621979cb1a2ee00bc3b70de08e90523f53083e2d +size 85294 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..637c2b6594 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3424334cf7831701633ebe3b865a5696d6843c41acc372a6dcddadaaa371160f +size 83088 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..474bb5ca7a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e5583fd71bfe7ae518b4b90c3d3b00f1a65829dc015c6384ddd1a560ca77bdb +size 88567 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..a69eca99b4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88902f2d5512e22e1f5cd50d0628c7f968a0ee9e88b16a9d0d55fd2e11aefcba +size 85255 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..07783dd2d7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a55cef72cf73e76104b74d55fe0abe92efa60e094116d871686fc4f525ca3649 +size 84298 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..97b62022c8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70919d061d76126b09642e2d0f1b41b3d0b6a4cff68f68c6bd2e43d141732dd3 +size 87805 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8c93c67eb8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b62cd8043e21bed0a323d657f79605aa9a0ad3fae632387d175fdd764baf8ce +size 81507 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..5df89eca37 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aafacbe3b1d14fdb11144d65148a24400fe964c4cd880796f8cc829abf37ae05 +size 5294 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..c40dfa4088 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30bb9d0a709868ff29803e45265069aad6e75ea2e65cdd8524b83a490a666831 +size 5272 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..553e8c904c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c56746d71fa25bf610f041b6c72e4559282407808bedbcdcc3c71a4497b3244 +size 5417 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..29ceb833be --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8be31e6a338f76e28550062911766dab5e4744e3e514f1348636100885ac1fe7 +size 5310 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9cb6b0bb87 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:813856d48fdb7b168b5cd662113a54dad9286b5f4191379471866ef6eda55e84 +size 5336 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7faff66c03 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83adb2ece84370f3f7249765b391ca30dcb5ba9a2ceb04872bbb7f66101890a7 +size 5340 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..888d88b06c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a71d6d556b72e3be69f0a9902771066259123f002f7fd35652a64aa8c26c9eea +size 5256 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3d3e4db08f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:667ecdc1069d2111044ca8f55f2fe12ff7aff84529b65c89e1c0223d841fb455 +size 5465 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..24f73f516c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c452593117cb003aca6d7d3c547b96a879c1bb10a169926c507c57a2abdc9b1 +size 77557 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png index 37e8a8561f..6d92ba07bc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e65e15c721a939ed700719cacbdee57e1ccb89d984e88bdb5ed772c4b583472a -size 81494 +oid sha256:700c12595cb3df0b342b36816dd336424ae1a94245874cb1e989528e89964336 +size 79384 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png index 466f321959..d51e1ad32f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49f6d3b7f93008640abf30a5a65ddca6845e16343ef97c3450faf9dd6d9b9cec -size 78788 +oid sha256:9f562083dcd0746eab20db445fce2836628faf5b57077dbb63ddbc32a479a9a0 +size 76138 From 962acc08f6f21cfab4f29b96f89f89559c073745 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 16:02:26 +0200 Subject: [PATCH 113/127] Hide Reply action if user cannot post to the room. --- .../features/messages/impl/MessagesView.kt | 12 +++- .../impl/actionlist/ActionListEvents.kt | 6 +- .../impl/actionlist/ActionListPresenter.kt | 6 +- .../actionlist/ActionListPresenterTest.kt | 59 ++++++++++++++----- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 9810845228..ab11ca05d7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -123,7 +123,13 @@ fun MessagesView( fun onMessageLongClicked(event: TimelineItem.Event) { Timber.v("OnMessageLongClicked= ${event.id}") localView.hideKeyboard() - state.actionListState.eventSink(ActionListEvents.ComputeForMessage(event, state.userHasPermissionToRedact)) + state.actionListState.eventSink( + ActionListEvents.ComputeForMessage( + event = event, + canRedact = state.userHasPermissionToRedact, + canSendMessage = state.userHasPermissionToSendMessage, + ) + ) } fun onActionSelected(action: TimelineItemAction, event: TimelineItem.Event) { @@ -203,8 +209,8 @@ fun MessagesView( CustomReactionBottomSheet( state = state.customReactionState, onEmojiSelected = { eventId, emoji -> - state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId)) - state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) + state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId)) + state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) } ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt index c5e6618736..7c8fad6c7c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt @@ -20,5 +20,9 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem sealed interface ActionListEvents { data object Clear : ActionListEvents - data class ComputeForMessage(val event: TimelineItem.Event, val canRedact: Boolean) : ActionListEvents + data class ComputeForMessage( + val event: TimelineItem.Event, + val canRedact: Boolean, + val canSendMessage: Boolean, + ) : ActionListEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index d0fa46175a..510c375bc5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -62,6 +62,7 @@ class ActionListPresenter @Inject constructor( is ActionListEvents.ComputeForMessage -> localCoroutineScope.computeForMessage( timelineItem = event.event, userCanRedact = event.canRedact, + userCanSendMessage = event.canSendMessage, target = target, ) } @@ -77,6 +78,7 @@ class ActionListPresenter @Inject constructor( private fun CoroutineScope.computeForMessage( timelineItem: TimelineItem.Event, userCanRedact: Boolean, + userCanSendMessage: Boolean, target: MutableState ) = launch { target.value = ActionListState.Target.Loading(timelineItem) @@ -126,7 +128,9 @@ class ActionListPresenter @Inject constructor( else -> buildList { if (timelineItem.isRemote) { // Can only reply or forward messages already uploaded to the server - add(TimelineItemAction.Reply) + if (userCanSendMessage) { + add(TimelineItemAction.Reply) + } add(TimelineItemAction.Forward) } if (timelineItem.isMine && timelineItem.isTextMessage) { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt index 3f3114dff3..5e68906216 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt @@ -64,7 +64,7 @@ class ActionListPresenterTest { }.test { val initialState = awaitItem() val messageEvent = aMessageEvent(isMine = true, content = TimelineItemRedactedContent) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -89,7 +89,7 @@ class ActionListPresenterTest { }.test { val initialState = awaitItem() val messageEvent = aMessageEvent(isMine = false, content = TimelineItemRedactedContent) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -117,7 +117,7 @@ class ActionListPresenterTest { isMine = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -138,6 +138,37 @@ class ActionListPresenterTest { } } + @Test + fun `present - compute for others message cannot sent message`() = runTest { + val presenter = anActionListPresenter(isBuildDebuggable = true) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = false, + content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) + ) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = false)) + // val loadingState = awaitItem() + // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + messageEvent, + persistentListOf( + TimelineItemAction.Forward, + TimelineItemAction.Copy, + TimelineItemAction.Developer, + TimelineItemAction.ReportContent, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + @Test fun `present - compute for others message and can redact`() = runTest { val presenter = anActionListPresenter(isBuildDebuggable = true) @@ -149,7 +180,7 @@ class ActionListPresenterTest { isMine = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, true)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = true, canSendMessage = true)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -180,7 +211,7 @@ class ActionListPresenterTest { isMine = true, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -213,7 +244,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemImageContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -244,7 +275,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemStateEventContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -273,7 +304,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemStateEventContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -301,7 +332,7 @@ class ActionListPresenterTest { isMine = true, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -338,10 +369,10 @@ class ActionListPresenterTest { content = TimelineItemRedactedContent, ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) assertThat(awaitItem().target).isInstanceOf(ActionListState.Target.Success::class.java) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, canRedact = false, canSendMessage = true)) awaitItem().run { assertThat(target).isEqualTo(ActionListState.Target.None) assertThat(displayEmojiReactions).isFalse() @@ -362,7 +393,7 @@ class ActionListPresenterTest { content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -389,7 +420,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemPollContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -415,7 +446,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemPollContent(isEnded = true), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( From 23358b9edbb5c8e857cbe2ea62ca51c2ea681c43 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 16:23:29 +0200 Subject: [PATCH 114/127] Disable swipe to reply action for unsupported events. --- .../messages/impl/actionlist/ActionListPresenter.kt | 3 ++- .../messages/impl/timeline/TimelinePresenter.kt | 2 +- .../features/messages/impl/timeline/TimelineState.kt | 2 +- .../messages/impl/timeline/TimelineStateProvider.kt | 2 +- .../features/messages/impl/timeline/TimelineView.kt | 9 +++++---- .../timeline/model/event/TimelineItemEventContent.kt | 12 ++++++++++++ 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 510c375bc5..b179261c72 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -103,7 +103,8 @@ class ActionListPresenter @Inject constructor( buildList { val isMineOrCanRedact = timelineItem.isMine || userCanRedact - // TODO Poll: Reply to poll + // TODO Poll: Reply to poll. Ensure to update `fun TimelineItemEventContent.canBeReplied()` + // when touching this // if (timelineItem.isRemote) { // // Can only reply or forward messages already uploaded to the server // add(TimelineItemAction.Reply) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index f5e6b45fe6..bf0f61e258 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -116,7 +116,7 @@ class TimelinePresenter @Inject constructor( return TimelineState( highlightedEventId = highlightedEventId.value, - canReply = userHasPermissionToSendMessage, + userHasPermissionToSendMessage = userHasPermissionToSendMessage, paginationState = paginationState, timelineItems = timelineItems, hasNewItems = hasNewItems.value, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt index ab5874d39c..1c7ff1b87c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt @@ -26,7 +26,7 @@ import kotlinx.collections.immutable.ImmutableList data class TimelineState( val timelineItems: ImmutableList, val highlightedEventId: EventId?, - val canReply: Boolean, + val userHasPermissionToSendMessage: Boolean, val paginationState: MatrixTimeline.PaginationState, val hasNewItems: Boolean, val eventSink: (TimelineEvents) -> Unit diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt index 6172da0469..8a4d45e40c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt @@ -44,7 +44,7 @@ fun aTimelineState(timelineItems: ImmutableList = persistentListOf timelineItems = timelineItems, paginationState = MatrixTimeline.PaginationState(isBackPaginating = false, hasMoreToLoadBackwards = true), highlightedEventId = null, - canReply = true, + userHasPermissionToSendMessage = true, hasNewItems = false, eventSink = {}, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index ff90e8d29a..b5187b4b30 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -63,6 +63,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentProvider import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent +import io.element.android.features.messages.impl.timeline.model.event.canBeReplied import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.FloatingActionButton @@ -119,7 +120,7 @@ fun TimelineView( TimelineItemRow( timelineItem = timelineItem, highlightedItem = state.highlightedEventId?.value, - canReply = state.canReply, + userHasPermissionToSendMessage = state.userHasPermissionToSendMessage, onClick = onMessageClicked, onLongClick = onMessageLongClicked, onUserDataClick = onUserDataClicked, @@ -156,7 +157,7 @@ fun TimelineView( fun TimelineItemRow( timelineItem: TimelineItem, highlightedItem: String?, - canReply: Boolean, + userHasPermissionToSendMessage: Boolean, onUserDataClick: (UserId) -> Unit, onClick: (TimelineItem.Event) -> Unit, onLongClick: (TimelineItem.Event) -> Unit, @@ -189,7 +190,7 @@ fun TimelineItemRow( TimelineItemEventRow( event = timelineItem, isHighlighted = highlightedItem == timelineItem.identifier(), - canReply = canReply, + canReply = userHasPermissionToSendMessage && timelineItem.content.canBeReplied(), onClick = { onClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) }, onUserDataClick = onUserDataClick, @@ -228,7 +229,7 @@ fun TimelineItemRow( TimelineItemRow( timelineItem = subGroupEvent, highlightedItem = highlightedItem, - canReply = false, + userHasPermissionToSendMessage = false, onClick = onClick, onLongClick = onLongClick, inReplyToClick = inReplyToClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index 02837bd6b4..4501e98e79 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -34,6 +34,18 @@ fun TimelineItemEventContent.canBeCopied(): Boolean = else -> false } +/** + * Determine if the event content can be replied to. + * Note: it should match the logic in [io.element.android.features.messages.impl.actionlist.ActionListPresenter]. + */ +fun TimelineItemEventContent.canBeReplied(): Boolean = + when (this) { + is TimelineItemRedactedContent, + is TimelineItemStateContent, + is TimelineItemPollContent -> false + else -> true + } + /** * Return true if user can react (i.e. send a reaction) on the event content. */ From e3d2fe9ec91dcfa7a5e258937701df53a838e23a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 Sep 2023 16:39:01 +0200 Subject: [PATCH 115/127] Changelog --- changelog.d/1173.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1173.bugfix diff --git a/changelog.d/1173.bugfix b/changelog.d/1173.bugfix new file mode 100644 index 0000000000..354aaaa3c4 --- /dev/null +++ b/changelog.d/1173.bugfix @@ -0,0 +1 @@ +Reply action: harmonize conditions in bottom sheet and swipe to reply. From 4b6a44db0010f5919d7e104cdcbb6b5142b8b0b7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 11 Sep 2023 17:47:58 +0200 Subject: [PATCH 116/127] TimelineEvent : fix memory leak --- .../item/event/TimelineEventContentMapper.kt | 147 +++++++++--------- 1 file changed, 77 insertions(+), 70 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index 22f8a062f0..3d02346bb3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -34,85 +34,92 @@ import io.element.android.libraries.matrix.impl.media.map import io.element.android.libraries.matrix.impl.poll.map import org.matrix.rustcomponents.sdk.TimelineItemContent import org.matrix.rustcomponents.sdk.TimelineItemContentKind +import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.EncryptedMessage as RustEncryptedMessage import org.matrix.rustcomponents.sdk.MembershipChange as RustMembershipChange import org.matrix.rustcomponents.sdk.OtherState as RustOtherState class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) { - fun map(content: TimelineItemContent): EventContent = content.use { - when (val kind = it.kind()) { - is TimelineItemContentKind.FailedToParseMessageLike -> { - FailedToParseMessageLikeContent( - eventType = kind.eventType, - error = kind.error - ) + fun map(content: TimelineItemContent): EventContent { + return content.use { _ -> + content.kind().use { kind -> + map(content, kind) } - is TimelineItemContentKind.FailedToParseState -> { - FailedToParseStateContent( - eventType = kind.eventType, - stateKey = kind.stateKey, - error = kind.error - ) - } - TimelineItemContentKind.Message -> { - val message = it.asMessage() - if (message == null) { - UnknownContent - } else { - eventMessageMapper.map(message) - } - } - is TimelineItemContentKind.ProfileChange -> { - ProfileChangeContent( - displayName = kind.displayName, - prevDisplayName = kind.prevDisplayName, - avatarUrl = kind.avatarUrl, - prevAvatarUrl = kind.prevAvatarUrl - ) - } - TimelineItemContentKind.RedactedMessage -> { - RedactedContent - } - is TimelineItemContentKind.RoomMembership -> { - RoomMembershipContent( - UserId(kind.userId), - kind.change?.map() - ) - } - is TimelineItemContentKind.State -> { - StateContent( - stateKey = kind.stateKey, - content = kind.content.map() - ) - } - is TimelineItemContentKind.Sticker -> { - StickerContent( - body = kind.body, - info = kind.info.map(), - url = kind.url, - ) - } - is TimelineItemContentKind.Poll -> { - PollContent( - question = kind.question, - kind = kind.kind.map(), - maxSelections = kind.maxSelections, - answers = kind.answers.map { answer -> answer.map() }, - votes = kind.votes.mapValues { vote -> - vote.value.map { userId -> UserId(userId) } - }, - endTime = kind.endTime, - ) - } - is TimelineItemContentKind.UnableToDecrypt -> { - UnableToDecryptContent( - data = kind.msg.map() - ) - } - else -> UnknownContent } } + + private fun map(content: TimelineItemContent, kind: TimelineItemContentKind) = when (kind) { + is TimelineItemContentKind.FailedToParseMessageLike -> { + FailedToParseMessageLikeContent( + eventType = kind.eventType, + error = kind.error + ) + } + is TimelineItemContentKind.FailedToParseState -> { + FailedToParseStateContent( + eventType = kind.eventType, + stateKey = kind.stateKey, + error = kind.error + ) + } + TimelineItemContentKind.Message -> { + val message = content.asMessage() + if (message == null) { + UnknownContent + } else { + eventMessageMapper.map(message) + } + } + is TimelineItemContentKind.ProfileChange -> { + ProfileChangeContent( + displayName = kind.displayName, + prevDisplayName = kind.prevDisplayName, + avatarUrl = kind.avatarUrl, + prevAvatarUrl = kind.prevAvatarUrl + ) + } + TimelineItemContentKind.RedactedMessage -> { + RedactedContent + } + is TimelineItemContentKind.RoomMembership -> { + RoomMembershipContent( + UserId(kind.userId), + kind.change?.map() + ) + } + is TimelineItemContentKind.State -> { + StateContent( + stateKey = kind.stateKey, + content = kind.content.map() + ) + } + is TimelineItemContentKind.Sticker -> { + StickerContent( + body = kind.body, + info = kind.info.map(), + url = kind.url, + ) + } + is TimelineItemContentKind.Poll -> { + PollContent( + question = kind.question, + kind = kind.kind.map(), + maxSelections = kind.maxSelections, + answers = kind.answers.map { answer -> answer.map() }, + votes = kind.votes.mapValues { vote -> + vote.value.map { userId -> UserId(userId) } + }, + endTime = kind.endTime, + ) + } + is TimelineItemContentKind.UnableToDecrypt -> { + UnableToDecryptContent( + data = kind.msg.map() + ) + } + else -> UnknownContent + } } private fun RustMembershipChange.map(): MembershipChange { From 557099995112b1a37dc5e7a5b2b4bc2246b71f8f Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Sep 2023 09:46:12 +0200 Subject: [PATCH 117/127] PR review Co-authored-by: Benoit Marty --- .../impl/timeline/item/event/TimelineEventContentMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index 3d02346bb3..01dd32c048 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -42,7 +42,7 @@ import org.matrix.rustcomponents.sdk.OtherState as RustOtherState class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) { fun map(content: TimelineItemContent): EventContent { - return content.use { _ -> + return content.use { content.kind().use { kind -> map(content, kind) } From 04c82aa1a551e44be6473d829c6b1a1cdab1a84a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:00:29 +0200 Subject: [PATCH 118/127] Update core to v1.12.0 (#1242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update core to v1.12.0 * Fixed now nullable `PendingIntent` creation --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- gradle/libs.versions.toml | 2 +- .../push/impl/notifications/factories/PendingIntentFactory.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c59d7359a6..b281ec73df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ molecule = "1.2.0" # AndroidX material = "1.9.0" -core = "1.10.1" +core = "1.12.0" datastore = "1.0.0" constraintlayout = "2.1.4" constraintlayout_compose = "1.0.1" diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt index 2fe02a8958..9752c621d5 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt @@ -131,6 +131,6 @@ class PendingIntentFactory @Inject constructor( fun createInviteListPendingIntent(sessionId: SessionId): PendingIntent { val intent = intentProvider.getInviteListIntent(sessionId) - return PendingIntentCompat.getActivity(context, 0, intent, 0, false) + return PendingIntentCompat.getActivity(context, 0, intent, 0, false)!! } } From be5bece629cc4f48e3327fe4b42f86311c7dd162 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Sep 2023 13:20:29 +0200 Subject: [PATCH 119/127] Attempt to add extra spacing for Document (#1228) --- .../timeline/components/event/ExtraPadding.kt | 11 ++++++++ .../components/event/TimelineItemTextView.kt | 24 ++++++---------- .../timeline/components/html/HtmlDocument.kt | 28 ++++++++++++++----- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/ExtraPadding.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/ExtraPadding.kt index 65101183d9..e5851c993b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/ExtraPadding.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/ExtraPadding.kt @@ -18,10 +18,14 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.times import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent import io.element.android.libraries.core.bool.orFalse +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings @@ -69,3 +73,10 @@ fun ExtraPadding.getStr(fontSize: TextUnit): String { // A space and some unbreakable spaces return " " + "\u00A0".repeat(nbOfSpaces) } + +@Composable +fun ExtraPadding.getDpSize(): Dp { + if (nbChars == 0) return 0.dp + val timestampFontSize = ElementTheme.typography.fontBodyXsRegular.fontSize // 11.sp + return nbChars * timestampFontSize.toDp() / 3 +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemTextView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemTextView.kt index c6b0218bba..b2dcc477a0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemTextView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemTextView.kt @@ -18,9 +18,6 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height import androidx.compose.material3.LocalContentColor import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -28,7 +25,6 @@ import androidx.compose.runtime.remember 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 androidx.compose.ui.unit.sp import io.element.android.features.messages.impl.timeline.components.html.HtmlDocument import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent @@ -51,18 +47,14 @@ fun TimelineItemTextView( CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.textPrimary) { val htmlDocument = content.htmlDocument if (htmlDocument != null) { - // For now we ignore the extra padding for html content, so add some spacing - // below the content (as previous behavior) - Column(modifier = modifier) { - HtmlDocument( - document = htmlDocument, - modifier = Modifier, - onTextClicked = onTextClicked, - onTextLongClicked = onTextLongClicked, - interactionSource = interactionSource - ) - Spacer(Modifier.height(16.dp)) - } + HtmlDocument( + document = htmlDocument, + extraPadding = extraPadding, + modifier = modifier, + onTextClicked = onTextClicked, + onTextLongClicked = onTextLongClicked, + interactionSource = interactionSource + ) } else { Box(modifier) { val textWithPadding = remember(content.body) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt index 9c2798a638..11eb1f421f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt @@ -25,8 +25,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent @@ -53,6 +55,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import io.element.android.features.messages.impl.timeline.components.event.ExtraPadding +import io.element.android.features.messages.impl.timeline.components.event.getDpSize +import io.element.android.features.messages.impl.timeline.components.event.noExtraPadding import io.element.android.libraries.designsystem.components.ClickableLinkText import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight @@ -72,18 +77,23 @@ private const val CHIP_ID = "chip" @Composable fun HtmlDocument( document: Document, + extraPadding: ExtraPadding, interactionSource: MutableInteractionSource, modifier: Modifier = Modifier, onTextClicked: () -> Unit = {}, onTextLongClicked: () -> Unit = {}, ) { - HtmlBody( - body = document.body(), - interactionSource = interactionSource, + FlowRow( modifier = modifier, - onTextClicked = onTextClicked, - onTextLongClicked = onTextLongClicked, - ) + ) { + HtmlBody( + body = document.body(), + interactionSource = interactionSource, + onTextClicked = onTextClicked, + onTextLongClicked = onTextLongClicked, + ) + Spacer(modifier = Modifier.width(extraPadding.getDpSize())) + } } @Composable @@ -603,5 +613,9 @@ internal fun HtmlDocumentDarkPreview(@PreviewParameter(DocumentProvider::class) @Composable private fun ContentToPreview(document: Document) { - HtmlDocument(document, remember { MutableInteractionSource() }) + HtmlDocument( + document = document, + extraPadding = noExtraPadding, + interactionSource = remember { MutableInteractionSource() } + ) } From da0b691fecbc3ca855a0c6e9d702b0eda8e45d0e Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 12 Sep 2023 11:28:15 +0000 Subject: [PATCH 120/127] Update screenshots --- ...null_TimelineItemTextViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...null_TimelineItemTextViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...null_TimelineItemTextViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_1,NEXUS_5,1.0,en].png index a9f640a918..73cb512e55 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:367f76f13127a604d1fec6e86d56611b01765dc90462dd329cd567e55a52fdca -size 7827 +oid sha256:eb78a3bc85d7f9ead19ba7d2723b997af1a399167ce28004be8ccbf0dd8ce5fd +size 7736 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_3,NEXUS_5,1.0,en].png index a40d484b80..30d4d8b3f7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a14f96fc1119481ca8e7336ac0a65cb831a2bfff3e8e43270b0da8844f419f0e -size 7982 +oid sha256:499df8785b50d0bd1d5466b8a5b65ab1a8eb358f0c1341ad5956f5d1931859ed +size 7987 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_5,NEXUS_5,1.0,en].png index 4f4adf041d..95464be951 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9caf6d9b49cf7eeaa41025617a7cc5b1d89bbd7468f7ecbfc0cac73ca4a04cc -size 7452 +oid sha256:021d867d665e0fa77aa10a85e734e4a9416b96d627b21ce462f0e327c5e58333 +size 7392 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png index 923bbeea49..5ff17ba18a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c196f9cb2da2366e4e67d59012f61c5f50a5775475230c3a0cbc8d823ba53dcd -size 63317 +oid sha256:5d1a1361432b343ef1bacc7e95bf1c4b50f9eab2e1bd3ab80024db4994f62508 +size 63028 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png index b59ac27461..b7c334bef0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59773d8a5435a37b3d47bf0c41412299b0b277af4be7a1a25ccb33b4b60a32db -size 65397 +oid sha256:d573380414ffbabcb509bc9ae8e34f155daae61edf5c3c406d20eec929cc91a9 +size 65158 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png index c586722f7b..d07e5c3c1f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee692fa3f3dbe4500cff084526a4537fef6444440c78f63a03d990a6a027f794 -size 69844 +oid sha256:be16428b678680bf888d33beb07377faba36515c2d9aa0632c089f32330185ce +size 69640 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png index b518541c41..784f05fd57 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b8155faa2599615048193667f540664c7185ac7b6a9159afdc14dfb6286d62e -size 71826 +oid sha256:d220bc3af69c6e576b639bb98c9696cee71232caae5e164cc2b306821a2cd4c1 +size 71603 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png index 7cc47ddfae..372883de77 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:771343ea6a9d83160284b3a9248f744c68ab25c2ad64817269c3628a5ca67972 -size 62319 +oid sha256:c6dd7c3eff7191c6ca0232fa467ac2ac723c81d7c8fdc60653ec49e2427990e3 +size 62067 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png index 903f4965cc..6bc82b809c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4663107c550f193aa9bb23b6bccf9229aed5ad30c380ce6b9a326e6a3fe5def7 -size 64854 +oid sha256:6dc81ed6a87958bd35754941d3a767b40f331822402db88fc21058bafae23628 +size 64681 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png index 60029246ea..b280c416b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca51c27cb553709458343bf16d8402a55eb1b7187b4b85191c3318f5b88c29db -size 69312 +oid sha256:c3169984328bc0ff82f602b6b136bbafbe8361df269bbb6169ffffd803086d8e +size 69016 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png index 08348ad401..4415a6052e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0a825d8090414c617780bf2d7332b8e80e5e4de066cd117c53f5e90cae8d4f6 -size 72112 +oid sha256:3e5905aabbe47b08864e6f6f3992b9e3a42d5b36bc101b53835ad91e7d7fd5f5 +size 71691 From a4c9c55a8b2ef0bdddce08cdff8fa3ba43b0bd35 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Tue, 12 Sep 2023 13:35:26 +0200 Subject: [PATCH 121/127] New icons for Poll and Poll end (#1280) Now both icons come from our designs and have a consistent size and padding (previously the poll one was coming from the material icons). --- .../actionlist/model/TimelineItemAction.kt | 2 +- .../features/poll/api/PollContentView.kt | 6 ++--- .../libraries/designsystem/VectorIcons.kt | 3 ++- .../src/main/res/drawable/ic_poll.xml | 9 +++++++ .../src/main/res/drawable/ic_poll_end.xml | 27 ++++++++++++------- ...etContent-D-0_1_null_8,NEXUS_5,1.0,en].png | 4 +-- ...etContent-N-0_2_null_8,NEXUS_5,1.0,en].png | 4 +-- ...ollView-D-13_14_null_0,NEXUS_5,1.0,en].png | 4 +-- ...ollView-D-13_14_null_1,NEXUS_5,1.0,en].png | 4 +-- ...ollView-N-13_15_null_0,NEXUS_5,1.0,en].png | 4 +-- ...ollView-N-13_15_null_1,NEXUS_5,1.0,en].png | 4 +-- ...tTimestampBelow_0_null,NEXUS_5,1.0,en].png | 4 +-- ...ntDisclosed-D-1_1_null,NEXUS_5,1.0,en].png | 4 +-- ...ntDisclosed-N-1_2_null,NEXUS_5,1.0,en].png | 4 +-- ...ontentEnded-D-2_2_null,NEXUS_5,1.0,en].png | 4 +-- ...ontentEnded-N-2_3_null,NEXUS_5,1.0,en].png | 4 +-- ...Undisclosed-D-0_0_null,NEXUS_5,1.0,en].png | 4 +-- ...Undisclosed-N-0_1_null,NEXUS_5,1.0,en].png | 4 +-- 18 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 libraries/designsystem/src/main/res/drawable/ic_poll.xml diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt index 8dc48f892e..7a8a1fa1db 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt @@ -35,5 +35,5 @@ sealed class TimelineItemAction( data object Edit : TimelineItemAction(CommonStrings.action_edit, VectorIcons.Edit) data object Developer : TimelineItemAction(CommonStrings.action_view_source, VectorIcons.DeveloperMode) data object ReportContent : TimelineItemAction(CommonStrings.action_report_content, VectorIcons.ReportContent, destructive = true) - data object EndPoll : TimelineItemAction(CommonStrings.action_end_poll, VectorIcons.EndPoll) + data object EndPoll : TimelineItemAction(CommonStrings.action_end_poll, VectorIcons.PollEnd) } diff --git a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt index 9301630b73..7e03d7a46e 100644 --- a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt +++ b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/PollContentView.kt @@ -24,8 +24,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Poll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -86,13 +84,13 @@ internal fun PollTitle( ) { if (isPollEnded) { Icon( - resourceId = VectorIcons.EndPoll, + resourceId = VectorIcons.PollEnd, contentDescription = null, modifier = Modifier.size(22.dp) ) } else { Icon( - imageVector = Icons.Outlined.Poll, + resourceId = VectorIcons.Poll, contentDescription = null, modifier = Modifier.size(22.dp) ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt index cd1b408a99..20ebb85615 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/VectorIcons.kt @@ -27,7 +27,8 @@ object VectorIcons { val ReportContent = R.drawable.ic_report_content val Groups = R.drawable.ic_groups val Share = R.drawable.ic_share - val EndPoll = R.drawable.ic_poll_end + val Poll = R.drawable.ic_poll + val PollEnd = R.drawable.ic_poll_end val Bold = R.drawable.ic_bold val BulletList = R.drawable.ic_bullet_list val CodeBlock = R.drawable.ic_code_block diff --git a/libraries/designsystem/src/main/res/drawable/ic_poll.xml b/libraries/designsystem/src/main/res/drawable/ic_poll.xml new file mode 100644 index 0000000000..6167653c82 --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_poll.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml b/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml index 21d895e613..86c169cf41 100644 --- a/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml +++ b/libraries/designsystem/src/main/res/drawable/ic_poll_end.xml @@ -1,14 +1,21 @@ + android:width="22dp" + android:height="22dp" + android:viewportWidth="22" + android:viewportHeight="22"> + android:pathData="M17.148,7.065L20.815,3.399C21.173,3.041 21.173,2.46 20.815,2.102C20.457,1.744 19.876,1.744 19.518,2.102L16.5,5.121L15.315,3.936C14.957,3.578 14.377,3.578 14.019,3.936C13.66,4.294 13.66,4.874 14.019,5.232L15.852,7.065C16.21,7.423 16.79,7.423 17.148,7.065Z" + android:fillColor="#1B1D22"/> + android:pathData="M19.25,17.417V9.771C18.677,9.974 18.059,10.084 17.417,10.084V17.417H4.583V4.584L11.917,4.584C11.917,3.941 12.027,3.324 12.23,2.751H4.583C4.079,2.751 3.648,2.93 3.289,3.289C2.93,3.648 2.75,4.08 2.75,4.584V17.417C2.75,17.921 2.93,18.353 3.289,18.712C3.648,19.071 4.079,19.251 4.583,19.251H17.417C17.921,19.251 18.352,19.071 18.712,18.712C19.07,18.353 19.25,17.921 19.25,17.417Z" + android:fillColor="#1B1D22"/> + + + diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png index a008402361..c94ec815dd 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20847fc7ab9e27171ae0ae37a95e7524aac0bd2479ff5b8b1130a5bc26dbb3e6 -size 28232 +oid sha256:d6a15254ca331bc6d8ec6a6408b0a5a3d4fd26961e7c6025805ec7841a22e017 +size 28313 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png index ceec7820f1..3152bb0b19 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a62ebcf0024a1876984c936c29037cf04e2e02aefb3bea461030c092fbde2937 -size 26983 +oid sha256:e0355effa8376bc88f9474f4d0e7f595708702f4fda5e39becf811fef10b0d16 +size 27081 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_0,NEXUS_5,1.0,en].png index 9bd8087f0c..84f2abf39d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15d14bf99af3cd0433870ebd6032d9bf4a45196e2ef1df7184cc55859a704dee -size 49008 +oid sha256:339e5f22a47e29b6f681ac169be3b65568b7fa5d1197b0e81fb68bef639ae5c2 +size 49033 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_1,NEXUS_5,1.0,en].png index 170f3d997a..0fbe7c6581 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-13_14_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e47fc219bbd63b76d01a5e50c3e4c6b1b0a8b4ec40b08b13271d0b2673d8d5e -size 50932 +oid sha256:c439f506df4eaed4ad35148d1734630a89b0de3ccb097864b7ff853c679772c1 +size 50964 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_0,NEXUS_5,1.0,en].png index cb9d6334b0..dacffc90ea 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cacb91ffca97f21bbc19b29525813f58fc8017a858aa28ccd4e620b70a8cd9ca -size 46119 +oid sha256:f85799360092c7e2d02f64f32668279c4e0c39bca3d45c9db13d503ddb7bf753 +size 46162 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_1,NEXUS_5,1.0,en].png index ec2787d842..40e0174919 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-13_15_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f1c14a23ee598ece6843a68d3ca0b1d1f725f53174bd493e27c6137de70c508 -size 48296 +oid sha256:b05475d6509b15fcffeae54bdebf434a529a99af5173c48992677a88b654f3eb +size 48336 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png index 6f6070772e..4ba636ed5c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventTimestampBelow_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe0a95b6c94668709c75052feec2953d310b8bcfda42758b2898e28b384ce193 -size 56189 +oid sha256:bdcc950b0ce924a73ae742f0bb3fc7279de46f36ba01d377822a2a14b6f90343 +size 56239 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-D-1_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-D-1_1_null,NEXUS_5,1.0,en].png index 9bd8087f0c..84f2abf39d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-D-1_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-D-1_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15d14bf99af3cd0433870ebd6032d9bf4a45196e2ef1df7184cc55859a704dee -size 49008 +oid sha256:339e5f22a47e29b6f681ac169be3b65568b7fa5d1197b0e81fb68bef639ae5c2 +size 49033 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-N-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-N-1_2_null,NEXUS_5,1.0,en].png index cb9d6334b0..dacffc90ea 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-N-1_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentDisclosed-N-1_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cacb91ffca97f21bbc19b29525813f58fc8017a858aa28ccd4e620b70a8cd9ca -size 46119 +oid sha256:f85799360092c7e2d02f64f32668279c4e0c39bca3d45c9db13d503ddb7bf753 +size 46162 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png index 140c07a3ca..e700e58b7e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-D-2_2_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:434c4f6dc4ee4c66291eca2ff1a8ab2471aaf521dbbf0d32f53f277ea6519c07 -size 49107 +oid sha256:85fbaa916a38c9b75a527dc3fddded9e9d06a98ab20f9f3eb74596c24ba4b5b7 +size 49105 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png index 0b32e49a00..26b2576508 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentEnded-N-2_3_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63685437c43543115e8f509919ef179d70a620c012c8a46ebf6682dcfe9820c6 -size 45890 +oid sha256:cee9e96cfefa6f84fb924857a92fd4ba04bbd196d94a6345bb821ff769fbd56d +size 45889 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-D-0_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-D-0_0_null,NEXUS_5,1.0,en].png index 7319bf6694..41f7fba3e5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-D-0_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-D-0_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2264139761f7fe3977ece3c9a7d949ac51223dd209497b7b311987cba3e5a069 -size 47154 +oid sha256:53cffdc5ea12b16db3f87ab12c28fede82ce5a744c222c9f19e5c35ef751c583 +size 47179 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-N-0_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-N-0_1_null,NEXUS_5,1.0,en].png index 3a129abb0b..cb51eea54a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-N-0_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.api_null_PollContentUndisclosed-N-0_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3ff35998ce8558b5a7af84e378bee039e36099084b357fffccf329a4983b035 -size 43551 +oid sha256:96d696014b24a2a222ba331d754d6048063a9ec573158edc41ded92ed588b60d +size 43593 From 00d21e24e548f2e11a957754de1df712f494c4f7 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Tue, 12 Sep 2023 14:01:33 +0200 Subject: [PATCH 122/127] Update analytics sdk to v0.8.0 (#1284) Integrates a few breaking changes introducing a `messageType` Composer prop: - Sends `messageType` = Text by default in composer. - Refactors existing location analytics to send the appropriate `messageType`. --- .../features/location/impl/send/SendLocationPresenter.kt | 8 +++----- .../location/impl/send/SendLocationPresenterTest.kt | 9 +++------ .../impl/messagecomposer/MessageComposerPresenter.kt | 2 +- gradle/libs.versions.toml | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt index 2ea7dc20e1..94af55c01c 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt @@ -26,10 +26,10 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import im.vector.app.features.analytics.plan.Composer import io.element.android.features.location.impl.common.MapDefaults +import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState -import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.messages.api.MessageComposerContext import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta @@ -119,9 +119,8 @@ class SendLocationPresenter @Inject constructor( Composer( inThread = messageComposerContext.composerMode.inThread, isEditing = messageComposerContext.composerMode.isEditing, - isLocation = true, isReply = messageComposerContext.composerMode.isReply, - locationType = Composer.LocationType.PinDrop, + messageType = Composer.MessageType.LocationPin, ) ) } @@ -138,9 +137,8 @@ class SendLocationPresenter @Inject constructor( Composer( inThread = messageComposerContext.composerMode.inThread, isEditing = messageComposerContext.composerMode.isEditing, - isLocation = true, isReply = messageComposerContext.composerMode.isReply, - locationType = Composer.LocationType.MyLocation, + messageType = Composer.MessageType.LocationUser, ) ) } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt index 15afa48b26..af31f1bfeb 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt @@ -308,9 +308,8 @@ class SendLocationPresenterTest { Composer( inThread = false, isEditing = false, - isLocation = true, isReply = false, - locationType = Composer.LocationType.MyLocation, + messageType = Composer.MessageType.LocationUser, ) ) } @@ -365,9 +364,8 @@ class SendLocationPresenterTest { Composer( inThread = false, isEditing = false, - isLocation = true, isReply = false, - locationType = Composer.LocationType.PinDrop, + messageType = Composer.MessageType.LocationPin, ) ) } @@ -412,9 +410,8 @@ class SendLocationPresenterTest { Composer( inThread = false, isEditing = true, - isLocation = true, isReply = false, - locationType = Composer.LocationType.PinDrop, + messageType = Composer.MessageType.LocationPin, ) ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 3c3ebc2db9..215826dade 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -153,7 +153,7 @@ class MessageComposerPresenter @Inject constructor( inThread = messageComposerContext.composerMode.inThread, isEditing = messageComposerContext.composerMode.isEditing, isReply = messageComposerContext.composerMode.isReply, - isLocation = false, + messageType = Composer.MessageType.Text, ) ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b281ec73df..d172bc120d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -169,7 +169,7 @@ maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:2.0.1" # Analytics posthog = "com.posthog.android:posthog:2.0.3" sentry = "io.sentry:sentry-android:6.29.0" -matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:42b2faa417c1e95f430bf8f6e379adba25ad5ef8" +matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:e9cd9adaf18cec52ed851395eb84358b4f9b8d7f" # Emojibase matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.1.3" From fb9d08bab090973f74c765838c1b240039bfad58 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 12 Sep 2023 14:02:59 +0200 Subject: [PATCH 123/127] [Compound] Improve Bloom (#1272) * Improve Bloom: - Simplify bloom blurred image. - Display very subtle bloom for avatars with soft colors. * Improve caching and performance --------- Co-authored-by: ElementBot --- .../impl/components/RoomListTopBar.kt | 8 ++- .../designsystem/components/Bloom.kt | 54 ++++++++++++++----- ...etContent-D-0_1_null_3,NEXUS_5,1.0,en].png | 4 +- ...etContent-N-0_2_null_3,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ImageViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...mageViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...VideoViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ideoViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...temEventRowDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...emEventRowLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...owWithReplyDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...wWithReplyLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...elineView-D-2_3_null_2,NEXUS_5,1.0,en].png | 4 +- ...elineView-D-2_3_null_3,NEXUS_5,1.0,en].png | 4 +- ...elineView-N-2_4_null_2,NEXUS_5,1.0,en].png | 4 +- ...elineView-N-2_4_null_3,NEXUS_5,1.0,en].png | 4 +- ...mListTopBarDark_0_null,NEXUS_5,1.0,en].png | 4 +- ...ListTopBarLight_0_null,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...mListViewDark_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...ListViewLight_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...ts_null_Bloom-N_1_null,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_0,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_1,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_2,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_3,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_4,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_5,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_6,NEXUS_5,1.0,en].png | 4 +- ...oomInitials-N_1_null_7,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_6,NEXUS_5,1.0,en].png | 4 +- ...BloomInitials_0_null_7,NEXUS_5,1.0,en].png | 4 +- ...ull_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png | 2 +- ...mposerReply-D-3_4_null,NEXUS_5,1.0,en].png | 4 +- ...mposerReply-N-3_5_null,NEXUS_5,1.0,en].png | 4 +- 58 files changed, 160 insertions(+), 124 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index a5113d33ce..508385dd84 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -158,13 +158,19 @@ private fun DefaultRoomListTopBar( .nestedScroll(scrollBehavior.nestedScrollConnection) .avatarBloom( avatarData = avatarData, - background = ElementTheme.materialColors.background, + background = if (ElementTheme.isLightTheme) { + // Workaround to display a very subtle bloom for avatars with very soft colors + Color(0xFFF9F9F9) + } else { + ElementTheme.materialColors.background + }, blurSize = DpSize(avatarBloomSize, avatarBloomSize), offset = DpOffset(24.dp, 24.dp + statusBarPadding), clipToSize = if (appBarHeight > 0) DpSize( avatarBloomSize, appBarHeight.toDp() ) else DpSize.Unspecified, + bottomSoftEdgeColor = ElementTheme.materialColors.background, bottomSoftEdgeAlpha = 1f - collapsedFraction, alpha = if (areSearchResultsDisplayed) 0f else 1f, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt index 5e1d7116ba..2a178af000 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt @@ -45,6 +45,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -96,8 +97,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.isSpecified import androidx.compose.ui.unit.toOffset import androidx.compose.ui.unit.toSize -import coil.compose.rememberAsyncImagePainter +import coil.imageLoader +import coil.request.DefaultRequestOptions import coil.request.ImageRequest +import coil.size.Size import com.airbnb.android.showkase.annotation.ShowkaseComposable import com.vanniktech.blurhash.BlurHash import io.element.android.libraries.designsystem.R @@ -114,6 +117,8 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import kotlin.math.max import kotlin.math.roundToInt @@ -125,7 +130,7 @@ object BloomDefaults { * Number of components to use with BlurHash to generate the blur effect. * Larger values mean more detailed blurs. */ - const val HASH_COMPONENTS = 8 + const val HASH_COMPONENTS = 5 /** Default bloom layers. */ @Composable @@ -159,6 +164,7 @@ data class BloomLayer( * @param offset The offset to use for the bloom effect. If not specified the bloom effect will be centered on the component. * @param clipToSize The size to use for clipping the bloom effect. If not specified the bloom effect will not be clipped. * @param layerConfiguration The configuration for the bloom layers. If not specified the default layers configuration will be used. + * @param bottomSoftEdgeColor The color to use for the bottom soft edge. If not specified the [background] color will be used. * @param bottomSoftEdgeHeight The height of the bottom soft edge. If not specified the bottom soft edge will not be drawn. * @param bottomSoftEdgeAlpha The alpha value to apply to the bottom soft edge. * @param alpha The alpha value to apply to the bloom effect. @@ -170,6 +176,7 @@ fun Modifier.bloom( offset: DpOffset = DpOffset.Unspecified, clipToSize: DpSize = DpSize.Unspecified, layerConfiguration: ImmutableList? = null, + bottomSoftEdgeColor: Color = background, bottomSoftEdgeHeight: Dp = 40.dp, @FloatRange(from = 0.0, to = 1.0) bottomSoftEdgeAlpha: Float = 1.0f, @@ -238,7 +245,7 @@ fun Modifier.bloom( val bottomEdgeGradient = LinearGradientShader( from = IntOffset(0, clipToPixelSize.height - bottomSoftEdgeHeightPixels).toOffset(), to = IntOffset(0, clipToPixelSize.height).toOffset(), - listOf(Color.Transparent, background), + listOf(Color.Transparent, bottomSoftEdgeColor), listOf(0f, 1f) ) val bottomEdgeGradientBrush = ShaderBrush(bottomEdgeGradient) @@ -297,6 +304,7 @@ fun Modifier.bloom( * @param blurSize The size of the bloom effect. If not specified the bloom effect will be the size of the component. * @param offset The offset to use for the bloom effect. If not specified the bloom effect will be centered on the component. * @param clipToSize The size to use for clipping the bloom effect. If not specified the bloom effect will not be clipped. + * @param bottomSoftEdgeColor The color to use for the bottom soft edge. If not specified the [background] color will be used. * @param bottomSoftEdgeHeight The height of the bottom soft edge. If not specified the bottom soft edge will not be drawn. * @param bottomSoftEdgeAlpha The alpha value to apply to the bottom soft edge. * @param alpha The alpha value to apply to the bloom effect. @@ -307,6 +315,7 @@ fun Modifier.avatarBloom( blurSize: DpSize = DpSize.Unspecified, offset: DpOffset = DpOffset.Unspecified, clipToSize: DpSize = DpSize.Unspecified, + bottomSoftEdgeColor: Color = background, bottomSoftEdgeHeight: Dp = 40.dp, @FloatRange(from = 0.0, to = 1.0) bottomSoftEdgeAlpha: Float = 1.0f, @@ -317,21 +326,35 @@ fun Modifier.avatarBloom( if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return@composed this avatarData ?: return@composed this + // Request the avatar contents to use as the bloom source + val context = LocalContext.current + val density = LocalDensity.current if (avatarData.url != null) { - // Request the avatar contents to use as the bloom source - val painter = rememberAsyncImagePainter( - ImageRequest.Builder(LocalContext.current) + val painterRequest = remember(avatarData) { + ImageRequest.Builder(context) .data(avatarData) + // Allow cache and default dispatchers + .defaults(DefaultRequestOptions()) // Needed to be able to read pixels from the Bitmap for the hash .allowHardware(false) + // Reduce size so it loads faster for large avatars + .size(with(density) { Size(64.dp.roundToPx(), 64.dp.roundToPx()) }) .build() - ) - var blurHash by remember { mutableStateOf(null) } + } + // By making it saveable, we'll 'cache' the previous bloom effect until a new one is loaded + var blurHash by rememberSaveable(avatarData) { mutableStateOf(null) } LaunchedEffect(avatarData) { - val drawable = painter.imageLoader.execute(painter.request).drawable ?: return@LaunchedEffect - val bitmap = (drawable as? BitmapDrawable)?.bitmap ?: return@LaunchedEffect - blurHash = BlurHash.encode(bitmap, BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS) + withContext(Dispatchers.IO) { + val drawable = + context.imageLoader.execute(painterRequest).drawable ?: return@withContext + val bitmap = (drawable as? BitmapDrawable)?.bitmap ?: return@withContext + blurHash = BlurHash.encode( + bitmap, + BloomDefaults.HASH_COMPONENTS, + BloomDefaults.HASH_COMPONENTS + ) + } } bloom( @@ -363,6 +386,7 @@ fun Modifier.avatarBloom( blurSize = blurSize, offset = offset, clipToSize = clipToSize, + bottomSoftEdgeColor = bottomSoftEdgeColor, bottomSoftEdgeHeight = bottomSoftEdgeHeight, bottomSoftEdgeAlpha = bottomSoftEdgeAlpha, alpha = alpha, @@ -517,7 +541,13 @@ internal fun BloomInitialsPreview(@PreviewParameter(InitialsColorStateProvider:: modifier = Modifier.size(256.dp) .bloom( hash = hash, - background = ElementTheme.materialColors.background, + background = if (ElementTheme.isLightTheme) { + // Workaround to display a very subtle bloom for avatars with very soft colors + Color(0xFFF9F9F9) + } else { + ElementTheme.materialColors.background + }, + bottomSoftEdgeColor = ElementTheme.materialColors.background, blurSize = DpSize(256.dp, 256.dp), ), contentAlignment = Alignment.Center diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png index 540f71b5a7..1f851222f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-0_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee62a7f77e591d238878e72e3f2fbe489e8c4e8c6a5c121b16e120ad5c43836d -size 44185 +oid sha256:8421be9fe6518a4a610e561692352c28c63b1e588fae4f7617f6be94439852f2 +size 45078 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png index cf7a8a2c81..8fae4446ea 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-0_2_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4bdf3944d30980e9bfd7cfffbabe2dac9861748cc3006e751bfd5cbf59c86db -size 42475 +oid sha256:4c30a6c0c7169044216a02dde5605d59fba9307499855ffc1fa0d3fcd1650f5e +size 43291 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png index 7ff6d4dec6..affcb49660 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c0485788c8776536a01613058ab001bad02a67519cf0cb4892505c7c3715fea -size 144681 +oid sha256:c40273c36eb1479f284e75fa91d4a75b1ae97edd0242dda37a2d4a8f10394928 +size 138700 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png index 7dae7dddb0..cb4b57910b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4a259f036e555fdc52ecc8f0c9578dae70ed677235fbfd344bc31cbabc76be5 -size 181478 +oid sha256:d7c47c713c74766c39d3b349d9e421ea588261e043105a5475cd8e68af782806 +size 185325 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png index 00c4b05824..db705106e0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5966cae164fed6a3a12c1e1dd940ae7b0601e4ba69d11f49d18740bdab8c520 -size 130130 +oid sha256:5d5479f3a6ea138b00c8f6a376cc4a67984385a087fb32bcdb764b2996e89402 +size 137137 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png index 7ff6d4dec6..affcb49660 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c0485788c8776536a01613058ab001bad02a67519cf0cb4892505c7c3715fea -size 144681 +oid sha256:c40273c36eb1479f284e75fa91d4a75b1ae97edd0242dda37a2d4a8f10394928 +size 138700 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png index 7dae7dddb0..cb4b57910b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4a259f036e555fdc52ecc8f0c9578dae70ed677235fbfd344bc31cbabc76be5 -size 181478 +oid sha256:d7c47c713c74766c39d3b349d9e421ea588261e043105a5475cd8e68af782806 +size 185325 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png index a603a6cc61..db705106e0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8cb21e08faf31779111d78c2be1e4e68e6f3bc994b16c108bd654f13d39fa02 -size 130130 +oid sha256:5d5479f3a6ea138b00c8f6a376cc4a67984385a087fb32bcdb764b2996e89402 +size 137137 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png index 0e6ff544a1..5361cd1a24 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2782edd31f68b7aa27e0c35b29d7c84574326cb56c65394738357479d408f5f -size 144667 +oid sha256:06617cda0f93ce0ea26b2a77a243371cdaf4f9a2956d8159ecb7196f7f6fe082 +size 139282 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png index b8b527778b..0e14867b04 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd352f748e3fd08225aa714181fdc18d53e91a8c62f8e5e860b67ff5aaeb7b8e -size 181969 +oid sha256:55d2d11ba729a68b1b62e9a69c3308594839fdb3612ff3db59850f0b346c28da +size 186118 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png index 6ee90c4b3a..da8a3d6499 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43da903ec671dd1cb591396306ce8c057432ffa8c1bfce7a509f28576e82b530 -size 130337 +oid sha256:62c57a45c2cb1aac23fa0c3af44f90a5d7b9a1e1626ec49eb94a2c126f53f96d +size 137535 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png index 0e6ff544a1..5361cd1a24 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2782edd31f68b7aa27e0c35b29d7c84574326cb56c65394738357479d408f5f -size 144667 +oid sha256:06617cda0f93ce0ea26b2a77a243371cdaf4f9a2956d8159ecb7196f7f6fe082 +size 139282 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png index b8b527778b..0e14867b04 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd352f748e3fd08225aa714181fdc18d53e91a8c62f8e5e860b67ff5aaeb7b8e -size 181969 +oid sha256:55d2d11ba729a68b1b62e9a69c3308594839fdb3612ff3db59850f0b346c28da +size 186118 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png index c4150178a1..da8a3d6499 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8141eaa257454258d2926df5ee970daf5ee165b774e4b948256b90e22a388d4c -size 130337 +oid sha256:62c57a45c2cb1aac23fa0c3af44f90a5d7b9a1e1626ec49eb94a2c126f53f96d +size 137535 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png index 5fd48ba7e6..722bd8c6a5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f95fbf1b51966c1c6b7b149c771f33400455d3c999b505e1aa65f0e3eb41c0ef -size 140928 +oid sha256:f0ad6895582183b697732ef032f89a6a0cad32106c9bbf30925c390dcab65ee6 +size 151752 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png index 3798fc1bc8..fb9457779e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8d522eb99079792d010e053d488f78a95e91f5a1b614b9d512bd005f0df81cf -size 146976 +oid sha256:676b62ab782652c45a7267aac5df12943fd181bea48964d28dce664884ae4182 +size 156619 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png index 5bc3b72bec..c39b41db87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eebf95f938f483da9b087eda86ae4a1baac594bc4b6f1f893d869b759679526c -size 123267 +oid sha256:b991a34a137d82ff4dedf48316a05ebbc008233984b11af70e64889a5fb5eda8 +size 127438 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png index 6e52c4b6d3..a6500ca748 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReplyLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4875df98092a8ef8bd1c2fda8c4a038ae2830b9ffa57e4ab71859523f97c26c9 -size 128062 +oid sha256:43b6514716d18382c8962520928d9d2ff6d0f665b2471e8a24e5d2e44a25c88c +size 132295 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png index 18e6545be9..307e6a7acf 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30119e8fcb65e8cbf058191268f0d70633a62b160b9f49f71879272d0d076537 -size 241818 +oid sha256:0d7bc773e70c57226840b30675f14a7fd99026100d61f48eeab64fb55d43f7c6 +size 230426 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png index cc3ad6b40e..4d97155b83 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-2_3_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73ca2b85c0f1f8f13cd3a0aae9d394116a460aa2c511ca1f2672a356eee496d2 -size 241553 +oid sha256:87f93b06f658352e7d97617c28dc0a4bd7454263fd402abfc2676f548c41d6b2 +size 231314 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png index 7fa7a38d87..946096b37e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff7953fabf75b346e61bd4335f3753331b498dbe5f17f9af3aad8a6a1ce051cd -size 239490 +oid sha256:f13fbb9bc776fa230b69c41e3faab659c52083d4e4f737f84b472c966f42c8dd +size 229746 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png index 45eafc5baa..419a96a180 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-2_4_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e262b1128df681c9a98bbefe426a891d02e0500646319f2e1756c1b5c93f2d23 -size 239303 +oid sha256:d312c80758e940b368e0b9eb2d41efb55c158691164bfde3456d7540080e46a9 +size 230651 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png index 434058e988..3c87d03c4f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:51931b01aa27677c8d29a79bf92f4e8b48fc2be05e80fdabedfb9026dcbd8899 -size 31634 +oid sha256:b967a0dc3bd9a466790503dd49c2fff6ce70156b51603022916aa9db3fc5c372 +size 29976 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png index 70b7534b8c..0d8fd2c681 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_null_DefaultRoomListTopBarLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5441c89fc077720b52479d4daf1ebd5fe5b98b63f35141a550dac228fe1c649f -size 10617 +oid sha256:8ec89c6b12c4eb1f8059d9d0d183f6635f5647393134c858720f3ef72b8c4c36 +size 36837 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png index c6ce4ced6b..dc92a3a311 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9156202a9f621b75cff3ca45aac33d72a938620049948828fc34aab3b9e0980d -size 55382 +oid sha256:71c2ac04d7fb904b648fc383f430e3b8a4003e93e5964b60eb545248186cd8dc +size 53912 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png index 21a3ec4a13..b8c2394645 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c7ee3acbf4653e49633e68f896fe0f5f73591c2cbc889204cc244b319996e0d -size 78348 +oid sha256:3277b51e1a7153487e2d9764d5c495419f8df7fa635574302237ebf3549a4b3c +size 76821 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png index c6ce4ced6b..dc92a3a311 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9156202a9f621b75cff3ca45aac33d72a938620049948828fc34aab3b9e0980d -size 55382 +oid sha256:71c2ac04d7fb904b648fc383f430e3b8a4003e93e5964b60eb545248186cd8dc +size 53912 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png index 3cc44b882b..d6981eb457 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55800431dfe4453fa3c11f97bfae53ceaf95f1c18b72bcc8620b8c3295b26b27 -size 56388 +oid sha256:0104fa9aca0b3d25f06225f54529e88d78f7d42aabd102b2c065c774427bbf3b +size 55038 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png index 0f8a496726..efe91c2960 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2d288f46eb76b8a71a8c1a2ec60ba7c3b8b1bf2a92be9d8daf33c06b3a0f126 -size 56593 +oid sha256:c2bf9d1733fc7230816cbcfbcef6780d34e687a064c289f2f9d651cf3047a1bd +size 55107 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png index 0306387553..f280592154 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewDark_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0e5bc6abe96bff50960c5ace2c4eccd5aabdd9f3ccd015fae867b4c3bc2b423 -size 56902 +oid sha256:a3cdb5de68791a0e5425ff9a29eaa8c1dc09aea9448211b9ad32f136bf11ace7 +size 55418 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png index 6b5e25ce2f..aa486dbf8e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f385e70f3a8bda7c0c2f7c090ba665575239299472c0fbd62f2821783ceb065 -size 39016 +oid sha256:3a9958e430c07445b9dcdc31a483c7925e2bd2a0d3fbbaf1ee5482051e2afe51 +size 65488 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png index c0b73d2764..4ae4e14d2e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bdb22d629e4bc3273aac4944802d1c91b43065858f4f4cc90052bd78ae6dd89 -size 62998 +oid sha256:c238218a16f7dc5c25125177434a8397821d5881971dd0404b9d79b7b181a592 +size 89294 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png index 6b5e25ce2f..aa486dbf8e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f385e70f3a8bda7c0c2f7c090ba665575239299472c0fbd62f2821783ceb065 -size 39016 +oid sha256:3a9958e430c07445b9dcdc31a483c7925e2bd2a0d3fbbaf1ee5482051e2afe51 +size 65488 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png index 8fe1fefb5d..b12ac33325 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ec1d951c96737ff8c5b401ef7c3af944f76be69348559401e40a12f60d5d459 -size 40807 +oid sha256:8176884d48589815521a35465f564858b4082b523f905e8d4cf7cbc96e25ac5e +size 65496 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png index c0550bff56..1f5a18bf95 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef7d9c31a72334294e93c67af1ca068ddff0062ae909ee8b682f0117c5c0ab6c -size 40331 +oid sha256:86f43007158129ed8e4a637df2db4044bdeb9d504e2a5c40da957bedea9ff395 +size 66618 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png index 340f3d07c3..f8847daf13 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_null_RoomListViewLight_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54ebfc606c04f37ed72edf5e9168a55628b59e69ea8a03cc3925cf25ca807195 -size 40695 +oid sha256:4543927c7e26cd464d28d3fe4dffda79479bcc8835d82088863031775bf6262e +size 67004 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png index 42af4e3ccb..2c9be4925e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom-N_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bd86a694456603dce070a7bef0646e553cefdb365f81c9d835b28d6b2521950 -size 71026 +oid sha256:0a2f25931e9de2edbcc29d149fcb656683d1ff30757b9acde43e058f214d8afc +size 70873 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png index 622b4080c5..a6024a3965 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67be26f120cbce266651737206a5f444b9a0605a4528cea30971f4629b340501 -size 85653 +oid sha256:52d6fc6f88ce1e80dfe48ad83476e70afa5b5499ec24e8a94bbbc4b0e611e16d +size 76231 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png index 2006811bc7..51aed9c9e7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7142834262eb7db1909a5a48621979cb1a2ee00bc3b70de08e90523f53083e2d -size 85294 +oid sha256:4611148bcc9140bf40a63859ec88bac212a9774d81a5fe5abcfea9afec4192bf +size 75130 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png index 637c2b6594..0860041efc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3424334cf7831701633ebe3b865a5696d6843c41acc372a6dcddadaaa371160f -size 83088 +oid sha256:39473b8fb90fcef316df257c4b3a45aa9c441199ef169b275e660d58d7fae52b +size 72606 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png index 474bb5ca7a..b5b50230ac 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e5583fd71bfe7ae518b4b90c3d3b00f1a65829dc015c6384ddd1a560ca77bdb -size 88567 +oid sha256:572db9d4c1796ec37e113907d5c13728cb87ce9959d94bb9396d7ea38914e52b +size 76355 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png index a69eca99b4..c7f31854cb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88902f2d5512e22e1f5cd50d0628c7f968a0ee9e88b16a9d0d55fd2e11aefcba -size 85255 +oid sha256:6ca9d811ba70d8642e4831a1d62b94960c79fb28f93a3c36d67d2d67c1b376fc +size 74706 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png index 07783dd2d7..81a543bd06 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a55cef72cf73e76104b74d55fe0abe92efa60e094116d871686fc4f525ca3649 -size 84298 +oid sha256:2319d9245e6f218f0b77d419d99ba101eda112184fc70729633006da0a4ee03d +size 74372 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png index 97b62022c8..781cf6f3a6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70919d061d76126b09642e2d0f1b41b3d0b6a4cff68f68c6bd2e43d141732dd3 -size 87805 +oid sha256:6131175dabf7e1835856d37c37f8cdacaaa7294b44d4676a0bd4d32d4d2a1337 +size 79118 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png index 8c93c67eb8..9f56ea678a 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_BloomInitials-N_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b62cd8043e21bed0a323d657f79605aa9a0ad3fae632387d175fdd764baf8ce -size 81507 +oid sha256:ce7f7219bd9027f0e6f3d8b44a4170b1e058c549cc143fbf63d67eab3e0eee2b +size 69351 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png index 5df89eca37..d06c97ace6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aafacbe3b1d14fdb11144d65148a24400fe964c4cd880796f8cc829abf37ae05 -size 5294 +oid sha256:3bf9d2e16fa86ec87e38fd82ecde90176542057d58729837d8aee73eb4828d12 +size 63936 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png index c40dfa4088..f0e507f655 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30bb9d0a709868ff29803e45265069aad6e75ea2e65cdd8524b83a490a666831 -size 5272 +oid sha256:e6575825152b070f8c2f6abe5ab89f5d1426d76df908638f3934c217193f1aac +size 58297 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png index 553e8c904c..4f5be56d3f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c56746d71fa25bf610f041b6c72e4559282407808bedbcdcc3c71a4497b3244 -size 5417 +oid sha256:17d225fbb3e9d7f1a954c0bc94b94cc1d7f131d226347b32c30940ba03991154 +size 67928 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png index 29ceb833be..cd121a5eb5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8be31e6a338f76e28550062911766dab5e4744e3e514f1348636100885ac1fe7 -size 5310 +oid sha256:1f05a11dcd4174a1784d6c7fcd32154a1064d0a3369b18c857f051ef72c09943 +size 64470 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png index 9cb6b0bb87..053b94e8a0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:813856d48fdb7b168b5cd662113a54dad9286b5f4191379471866ef6eda55e84 -size 5336 +oid sha256:1e6b22c6a7acbdbc77ebad06831318467ad40bdfbe8c56a0a81e8e9d69de4ff0 +size 66145 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png index 7faff66c03..a51c3b1758 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83adb2ece84370f3f7249765b391ca30dcb5ba9a2ceb04872bbb7f66101890a7 -size 5340 +oid sha256:29fd768d347c14c0e9f99de9e2c4e341f76850b8447ccd30fb240590bc8cd706 +size 68885 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png index 888d88b06c..5328ba5fe0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a71d6d556b72e3be69f0a9902771066259123f002f7fd35652a64aa8c26c9eea -size 5256 +oid sha256:8e18c010bfd1cf93b5b30cf38b58b3cc24d3e1fdb992050786e35004d112563f +size 61822 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png index 3d3e4db08f..46e82926c4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_BloomInitials_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:667ecdc1069d2111044ca8f55f2fe12ff7aff84529b65c89e1c0223d841fb455 -size 5465 +oid sha256:21465f36c39930d08edbe2b099ff0cd2765292ee29a724720f75760066845440 +size 67954 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png index 24f73f516c..17ad5a90a2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components_null_Bloom_Bloom_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c452593117cb003aca6d7d3c547b96a879c1bb10a169926c507c57a2abdc9b1 +oid sha256:b06bbc06573f8b25cb97e6de6c621c2580a29a2b0c688a5e5135e886af524eb8 size 77557 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png index 6d92ba07bc..37e8a8561f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-D-3_4_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:700c12595cb3df0b342b36816dd336424ae1a94245874cb1e989528e89964336 -size 79384 +oid sha256:e65e15c721a939ed700719cacbdee57e1ccb89d984e88bdb5ed772c4b583472a +size 81494 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png index d51e1ad32f..466f321959 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.textcomposer_null_TextComposerReply-N-3_5_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f562083dcd0746eab20db445fce2836628faf5b57077dbb63ddbc32a479a9a0 -size 76138 +oid sha256:49f6d3b7f93008640abf30a5a65ddca6845e16343ef97c3450faf9dd6d9b9cec +size 78788 From c0b5084c625cd7a8f832b9f21fb86a6e200f040b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Sep 2023 14:28:49 +0200 Subject: [PATCH 124/127] Fix overlapping issue - still not perfect when text is on several lines. --- .../impl/timeline/components/html/HtmlDocument.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt index 11eb1f421f..9df5399727 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt @@ -28,7 +28,7 @@ import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent @@ -61,10 +61,12 @@ import io.element.android.features.messages.impl.timeline.components.event.noExt import io.element.android.libraries.designsystem.components.ClickableLinkText import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkParser +import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.LinkColor import kotlinx.collections.immutable.persistentMapOf import org.jsoup.nodes.Document @@ -92,7 +94,12 @@ fun HtmlDocument( onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked, ) - Spacer(modifier = Modifier.width(extraPadding.getDpSize())) + Spacer( + modifier = Modifier.size( + width = extraPadding.getDpSize(), + height = ElementTheme.typography.fontBodyXsRegular.fontSize.toDp() * 1.25f + ) + ) } } From d48577d79210bf2841ee53bdb094c57303804a78 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 12 Sep 2023 12:37:51 +0000 Subject: [PATCH 125/127] Update screenshots --- ...lineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...lineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png index 5ff17ba18a..5bb87f7b39 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d1a1361432b343ef1bacc7e95bf1c4b50f9eab2e1bd3ab80024db4994f62508 -size 63028 +oid sha256:f6010f8c84263cad47587a20c9d7da64aef2a8520c01765ee4966e4b6bdd8327 +size 63371 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png index b7c334bef0..27e6956a21 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d573380414ffbabcb509bc9ae8e34f155daae61edf5c3c406d20eec929cc91a9 -size 65158 +oid sha256:6e12464ce600a1cd6ca6ea9dd930c2235e033896b336109e094b84dcf2d4e624 +size 65459 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png index d07e5c3c1f..21092833ec 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be16428b678680bf888d33beb07377faba36515c2d9aa0632c089f32330185ce -size 69640 +oid sha256:e74d57cb6f5cda78086989289d0f0543cfd3747e1cebec0bd656bd5be2d8bac1 +size 69944 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png index 784f05fd57..4bf217a2e5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampDark_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d220bc3af69c6e576b639bb98c9696cee71232caae5e164cc2b306821a2cd4c1 -size 71603 +oid sha256:9baf1ea5fca980be4744655283bd61de650c9f8399a9f3441a9a3f9c5f43566e +size 71852 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png index 372883de77..31b384c132 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6dd7c3eff7191c6ca0232fa467ac2ac723c81d7c8fdc60653ec49e2427990e3 -size 62067 +oid sha256:343d84dc714bb672084362155362b04936ae491f437e492332bff553d7776078 +size 62478 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png index 6bc82b809c..7fedf5139d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6dc81ed6a87958bd35754941d3a767b40f331822402db88fc21058bafae23628 -size 64681 +oid sha256:daee8f18d24bcc07cf8edd9b902b03c3fb406199a925606b1caf34cee08ff9a1 +size 65076 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png index b280c416b8..7bf4f6f57b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3169984328bc0ff82f602b6b136bbafbe8361df269bbb6169ffffd803086d8e -size 69016 +oid sha256:f0cb7b8bd23784f2323ab61baad1a910b343fc498ea61f7364edeff9111992d0 +size 69478 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png index 4415a6052e..ab0a440978 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestampLight_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e5905aabbe47b08864e6f6f3992b9e3a42d5b36bc101b53835ad91e7d7fd5f5 -size 71691 +oid sha256:54a52c6de5fd501e5c4f260343dd9ec582b0a1dd094a18f43f2fc4aa2c8acfcc +size 72145 From 664caf3041f74ac21a98d4d60a09466eb537ebf3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Sep 2023 15:13:19 +0200 Subject: [PATCH 126/127] Renane fun. --- .../android/features/messages/impl/timeline/TimelineView.kt | 4 ++-- .../impl/timeline/model/event/TimelineItemEventContent.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index b5187b4b30..e48eb4f72b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -63,7 +63,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentProvider import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent -import io.element.android.features.messages.impl.timeline.model.event.canBeReplied +import io.element.android.features.messages.impl.timeline.model.event.canBeRepliedTo import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.theme.components.FloatingActionButton @@ -190,7 +190,7 @@ fun TimelineItemRow( TimelineItemEventRow( event = timelineItem, isHighlighted = highlightedItem == timelineItem.identifier(), - canReply = userHasPermissionToSendMessage && timelineItem.content.canBeReplied(), + canReply = userHasPermissionToSendMessage && timelineItem.content.canBeRepliedTo(), onClick = { onClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) }, onUserDataClick = onUserDataClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index 4501e98e79..ef31d6249c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -38,7 +38,7 @@ fun TimelineItemEventContent.canBeCopied(): Boolean = * Determine if the event content can be replied to. * Note: it should match the logic in [io.element.android.features.messages.impl.actionlist.ActionListPresenter]. */ -fun TimelineItemEventContent.canBeReplied(): Boolean = +fun TimelineItemEventContent.canBeRepliedTo(): Boolean = when (this) { is TimelineItemRedactedContent, is TimelineItemStateContent, From 8abaee870805a5ccf24c9058d114c6403e67009e Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Tue, 12 Sep 2023 16:03:40 +0200 Subject: [PATCH 127/127] Polls analytics (#1285) Send poll analytics event (creation, vote, end) where appropriate. --- .../messages/impl/MessagesPresenter.kt | 9 +++++-- .../impl/timeline/TimelinePresenter.kt | 5 +++- .../messages/MessagesPresenterTest.kt | 17 +++++++++--- .../timeline/TimelinePresenterTest.kt | 18 ++++++++++--- features/poll/impl/build.gradle.kts | 2 ++ .../poll/impl/create/CreatePollNode.kt | 7 ++--- .../poll/impl/create/CreatePollPresenter.kt | 26 ++++++++++++++++--- .../impl/create/CreatePollPresenterTest.kt | 26 +++++++++++++++++-- 8 files changed, 90 insertions(+), 20 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index b0ff403984..0831afb699 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.setValue import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.features.analytics.plan.PollEnd import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListPresenter import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction @@ -74,6 +75,7 @@ import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType import io.element.android.libraries.matrix.ui.room.canRedactAsState import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.textcomposer.MessageComposerMode +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -92,6 +94,7 @@ class MessagesPresenter @AssistedInject constructor( private val messageSummaryFormatter: MessageSummaryFormatter, private val dispatchers: CoroutineDispatchers, private val clipboardHelper: ClipboardHelper, + private val analyticsService: AnalyticsService, @Assisted private val navigator: MessagesNavigator, ) : Presenter { @@ -321,8 +324,10 @@ class MessagesPresenter @AssistedInject constructor( } private suspend fun handleEndPollAction(event: TimelineItem.Event) { - event.eventId?.let { room.endPoll(it, "The poll with event id: $it has ended.") } - // TODO Polls: Send poll end analytic + event.eventId?.let { + room.endPoll(it, "The poll with event id: $it has ended.") + analyticsService.capture(PollEnd()) + } } private suspend fun handleCopyContents(event: TimelineItem.Event) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index bf0f61e258..a7e86d341f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable +import im.vector.app.features.analytics.plan.PollVote import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.libraries.architecture.Presenter @@ -35,6 +36,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin import io.element.android.libraries.matrix.ui.room.canSendMessageAsState +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn @@ -51,6 +53,7 @@ class TimelinePresenter @Inject constructor( private val room: MatrixRoom, private val dispatchers: CoroutineDispatchers, private val appScope: CoroutineScope, + private val analyticsService: AnalyticsService, ) : Presenter { private val timeline = room.timeline @@ -93,7 +96,7 @@ class TimelinePresenter @Inject constructor( pollStartId = event.pollStartId, answers = listOf(event.answerId), ) - // TODO Polls: Send poll vote analytic + analyticsService.capture(PollVote()) } } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index ed7c4a8064..2a601fbb90 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -21,6 +21,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import im.vector.app.features.analytics.plan.PollEnd import io.element.android.features.messages.fixtures.aMessageEvent import io.element.android.features.messages.fixtures.aTimelineItemsFactory import io.element.android.features.messages.impl.InviteDialogAction @@ -575,7 +576,11 @@ class MessagesPresenterTest { @Test fun `present - handle poll end`() = runTest { val room = FakeMatrixRoom() - val presenter = createMessagePresenter(matrixRoom = room) + val analyticsService = FakeAnalyticsService() + val presenter = createMessagePresenter( + matrixRoom = room, + analyticsService = analyticsService, + ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -586,7 +591,8 @@ class MessagesPresenterTest { assertThat(room.endPollInvocations.size).isEqualTo(1) assertThat(room.endPollInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID) assertThat(room.endPollInvocations.first().text).isEqualTo("The poll with event id: \$anEventId has ended.") - // TODO Polls: Test poll end analytic + assertThat(analyticsService.capturedEvents.size).isEqualTo(1) + assertThat(analyticsService.capturedEvents.last()).isEqualTo(PollEnd()) } } @@ -595,6 +601,7 @@ class MessagesPresenterTest { matrixRoom: MatrixRoom = FakeMatrixRoom(), navigator: FakeMessagesNavigator = FakeMessagesNavigator(), clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(), + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), ): MessagesPresenter { val messageComposerPresenter = MessageComposerPresenter( appCoroutineScope = this, @@ -604,7 +611,7 @@ class MessagesPresenterTest { localMediaFactory = FakeLocalMediaFactory(mockMediaUrl), mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom), snackbarDispatcher = SnackbarDispatcher(), - analyticsService = FakeAnalyticsService(), + analyticsService = analyticsService, messageComposerContext = MessageComposerContextImpl(), richTextEditorStateFactory = TestRichTextEditorStateFactory(), @@ -613,7 +620,8 @@ class MessagesPresenterTest { timelineItemsFactory = aTimelineItemsFactory(), room = matrixRoom, dispatchers = coroutineDispatchers, - appScope = this + appScope = this, + analyticsService = analyticsService, ) val buildMeta = aBuildMeta() val actionListPresenter = ActionListPresenter(buildMeta = buildMeta) @@ -633,6 +641,7 @@ class MessagesPresenterTest { messageSummaryFormatter = FakeMessageSummaryFormatter(), navigator = navigator, clipboardHelper = clipboardHelper, + analyticsService = analyticsService, dispatchers = coroutineDispatchers, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt index 4e8ab07d95..eb5a7b72e1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt @@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import im.vector.app.features.analytics.plan.PollVote import io.element.android.features.messages.fixtures.aTimelineItemsFactory import io.element.android.features.messages.impl.timeline.TimelineEvents import io.element.android.features.messages.impl.timeline.TimelinePresenter @@ -37,6 +38,7 @@ import io.element.android.libraries.matrix.test.room.aMessageContent import io.element.android.libraries.matrix.test.room.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.awaitWithLatch import io.element.android.tests.testutils.testCoroutineDispatchers @@ -260,7 +262,11 @@ class TimelinePresenterTest { @Test fun `present - PollAnswerSelected event calls into rust room api and analytics`() = runTest { val room = FakeMatrixRoom() - val presenter = createTimelinePresenter(room) + val analyticsService = FakeAnalyticsService() + val presenter = createTimelinePresenter( + room = room, + analyticsService = analyticsService, + ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -271,7 +277,8 @@ class TimelinePresenterTest { assertThat(room.sendPollResponseInvocations.size).isEqualTo(1) assertThat(room.sendPollResponseInvocations.first().answers).isEqualTo(listOf("anAnswerId")) assertThat(room.sendPollResponseInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID) - // TODO Polls: Test poll vote analytic + assertThat(analyticsService.capturedEvents.size).isEqualTo(1) + assertThat(analyticsService.capturedEvents.last()).isEqualTo(PollVote()) } private fun TestScope.createTimelinePresenter( @@ -282,18 +289,21 @@ class TimelinePresenterTest { timelineItemsFactory = timelineItemsFactory, room = FakeMatrixRoom(matrixTimeline = timeline), dispatchers = testCoroutineDispatchers(), - appScope = this + appScope = this, + analyticsService = FakeAnalyticsService(), ) } private fun TestScope.createTimelinePresenter( room: MatrixRoom, + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), ): TimelinePresenter { return TimelinePresenter( timelineItemsFactory = aTimelineItemsFactory(), room = room, dispatchers = testCoroutineDispatchers(), - appScope = this + appScope = this, + analyticsService = analyticsService, ) } } diff --git a/features/poll/impl/build.gradle.kts b/features/poll/impl/build.gradle.kts index e2139424e1..5ff9025aae 100644 --- a/features/poll/impl/build.gradle.kts +++ b/features/poll/impl/build.gradle.kts @@ -39,6 +39,7 @@ dependencies { implementation(projects.libraries.matrixui) implementation(projects.libraries.designsystem) implementation(projects.services.analytics.api) + implementation(projects.features.messages.api) implementation(projects.libraries.uiStrings) testImplementation(libs.test.junit) @@ -48,6 +49,7 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) + testImplementation(projects.features.messages.test) testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollNode.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollNode.kt index 387f57a597..506c39c177 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollNode.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollNode.kt @@ -24,15 +24,17 @@ import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import dagger.assisted.Assisted import dagger.assisted.AssistedInject +import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.anvilannotations.ContributesNode import io.element.android.libraries.di.RoomScope +import io.element.android.services.analytics.api.AnalyticsService @ContributesNode(RoomScope::class) class CreatePollNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, presenterFactory: CreatePollPresenter.Factory, - // analyticsService: AnalyticsService, // TODO Polls: add analytics + analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { private val presenter = presenterFactory.create(backNavigator = ::navigateUp) @@ -40,8 +42,7 @@ class CreatePollNode @AssistedInject constructor( init { lifecycle.subscribe( onResume = { - // TODO Polls: add analytics - // analyticsService.screen(MobileScreen(screenName = MobileScreen.ScreenName.PollView)) + analyticsService.screen(MobileScreen(screenName = MobileScreen.ScreenName.CreatePollView)) } ) } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt index b44afae9d1..44cc54a100 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt @@ -29,9 +29,13 @@ import androidx.compose.runtime.setValue import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.features.analytics.plan.Composer +import im.vector.app.features.analytics.plan.PollCreation +import io.element.android.features.messages.api.MessageComposerContext import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.MatrixRoom +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch @@ -44,9 +48,9 @@ private const val MAX_SELECTIONS = 1 class CreatePollPresenter @AssistedInject constructor( private val room: MatrixRoom, - // private val analyticsService: AnalyticsService, // TODO Polls: add analytics + private val analyticsService: AnalyticsService, + private val messageComposerContext: MessageComposerContext, @Assisted private val navigateUp: () -> Unit, - // private val messageComposerContext: MessageComposerContext, // TODO Polls: add analytics ) : Presenter { @AssistedFactory @@ -78,7 +82,21 @@ class CreatePollPresenter @AssistedInject constructor( maxSelections = MAX_SELECTIONS, pollKind = pollKind, ) - // analyticsService.capture(PollCreate()) // TODO Polls: add analytics + analyticsService.capture( + Composer( + inThread = messageComposerContext.composerMode.inThread, + isEditing = messageComposerContext.composerMode.isEditing, + isReply = messageComposerContext.composerMode.isReply, + messageType = Composer.MessageType.Poll, + ) + ) + analyticsService.capture( + PollCreation( + action = PollCreation.Action.Create, + isUndisclosed = pollKind == PollKind.Undisclosed, + numberOfAnswers = answers.size, + ) + ) navigateUp() } else { Timber.d("Cannot create poll") @@ -153,7 +171,7 @@ private val pollKindSaver: Saver, Boolean> = Saver( }, restore = { mutableStateOf( - when(it) { + when (it) { true -> PollKind.Undisclosed else -> PollKind.Disclosed } diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt index c54972e9d1..a58fb5476b 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt @@ -20,9 +20,13 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth +import im.vector.app.features.analytics.plan.Composer +import im.vector.app.features.analytics.plan.PollCreation +import io.element.android.features.messages.test.MessageComposerContextFake import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.test.room.CreatePollInvocation import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest @@ -37,11 +41,13 @@ class CreatePollPresenterTest { private var navUpInvocationsCount = 0 private val fakeMatrixRoom = FakeMatrixRoom() - // private val fakeAnalyticsService = FakeAnalyticsService() // TODO Polls: add analytics + private val fakeAnalyticsService = FakeAnalyticsService() + private val messageComposerContextFake = MessageComposerContextFake() private val presenter = CreatePollPresenter( room = fakeMatrixRoom, - // analyticsService = fakeAnalyticsService, // TODO Polls: add analytics + analyticsService = fakeAnalyticsService, + messageComposerContext = messageComposerContextFake, navigateUp = { navUpInvocationsCount++ }, ) @@ -104,6 +110,22 @@ class CreatePollPresenterTest { pollKind = PollKind.Disclosed ) ) + Truth.assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(2) + Truth.assertThat(fakeAnalyticsService.capturedEvents[0]).isEqualTo( + Composer( + inThread = false, + isEditing = false, + isReply = false, + messageType = Composer.MessageType.Poll, + ) + ) + Truth.assertThat(fakeAnalyticsService.capturedEvents[1]).isEqualTo( + PollCreation( + action = PollCreation.Action.Create, + isUndisclosed = false, + numberOfAnswers = 2, + ) + ) } }