Browse Source

[Compound] Implement Snackbars based on designs (#1054)

* Make `InternalButton` internal instead of private so it can be customised.

Also, change the `ButtonColors.contentColor` for text buttons to `LocalContentColor.current` by default.

* Add temporary color for Snackbar action label

* Implement `Snackbar` component based on Compound

* Propagate changes to all other components

* Use right Preview annotation config

* Move `ButtonVisuals` to their own file

* Update screenshots

* Make previews internal

* Update screenshots

* Set a custom token for contentColor in AppBars

* Change 'Label' to 'Action' in the previews

* Add changelog

* Update screenshots

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
pull/1063/head
Jorge Martin Espinosa 1 year ago committed by GitHub
parent
commit
9e1ff513e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      changelog.d/1054.misc
  2. 2
      features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt
  3. 4
      features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/components/InviteSummaryRow.kt
  4. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt
  5. 14
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt
  6. 11
      features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt
  7. 11
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt
  8. 2
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt
  9. 53
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/ButtonVisuals.kt
  10. 1
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt
  11. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ruler/WithRulers.kt
  12. 6
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt
  13. 143
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt
  14. 23
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt
  15. 147
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Snackbar.kt
  16. 23
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt
  17. 19
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt
  18. 5
      libraries/theme/src/main/kotlin/io/element/android/libraries/theme/LegacyColors.kt
  19. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
  20. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
  21. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
  22. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
  23. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
  24. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
  25. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
  26. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
  27. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
  28. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
  29. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
  30. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
  31. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
  32. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
  33. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
  34. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
  35. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
  36. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
  37. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png
  38. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_9,NEXUS_5,1.0,en].png
  39. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png
  40. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png
  41. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl_null_DefaultGroup_RoomDetailsDarkPreview--1_1_null_8,NEXUS_5,1.0,en].png
  42. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl_null_DefaultGroup_RoomDetailsLightPreview--0_0_null_8,NEXUS_5,1.0,en].png
  43. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_MediumTopAppBarPreview_0_null,NEXUS_5,1.0,en].png
  44. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_TopAppBarPreview_0_null,NEXUS_5,1.0,en].png
  45. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbar_0_null,NEXUS_5,1.0,en].png
  46. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithaction_0_null,NEXUS_5,1.0,en].png
  47. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactionandclosebutton_0_null,NEXUS_5,1.0,en].png
  48. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactionandclosebuttononnewline_0_null,NEXUS_5,1.0,en].png
  49. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactiononnewline_0_null,NEXUS_5,1.0,en].png

1
changelog.d/1054.misc

@ -0,0 +1 @@ @@ -0,0 +1 @@
Compound: implement Snackbar component.

2
features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt

@ -195,7 +195,7 @@ private fun AnalyticsOptInFooter( @@ -195,7 +195,7 @@ private fun AnalyticsOptInFooter(
)
TextButton(
text = stringResource(id = CommonStrings.action_not_now),
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
onClick = onTermsDeclined,
modifier = Modifier.fillMaxWidth(),
)

4
features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/components/InviteSummaryRow.kt

@ -135,7 +135,7 @@ internal fun DefaultInviteSummaryRow( @@ -135,7 +135,7 @@ internal fun DefaultInviteSummaryRow(
text = stringResource(CommonStrings.action_decline),
onClick = onDeclineClicked,
modifier = Modifier.weight(1f),
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
)
Spacer(modifier = Modifier.width(12.dp))
@ -144,7 +144,7 @@ internal fun DefaultInviteSummaryRow( @@ -144,7 +144,7 @@ internal fun DefaultInviteSummaryRow(
text = stringResource(CommonStrings.action_accept),
onClick = onAcceptClicked,
modifier = Modifier.weight(1f),
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
)
}
}

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt

@ -35,7 +35,6 @@ import androidx.compose.foundation.layout.width @@ -35,7 +35,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHost
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
@ -78,6 +77,7 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold @@ -78,6 +77,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.designsystem.utils.LogCompositions
import io.element.android.libraries.designsystem.utils.SnackbarHost
import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState

14
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt

@ -34,9 +34,6 @@ import androidx.compose.material.icons.filled.OpenInNew @@ -34,9 +34,6 @@ import androidx.compose.material.icons.filled.OpenInNew
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@ -64,6 +61,7 @@ import io.element.android.libraries.designsystem.theme.components.Icon @@ -64,6 +61,7 @@ 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.Scaffold
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.utils.SnackbarHost
import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.ui.media.MediaRequestData
@ -99,15 +97,7 @@ fun MediaViewerView( @@ -99,15 +97,7 @@ fun MediaViewerView(
eventSink = state.eventSink
)
},
snackbarHost = {
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.primary
)
}
},
snackbarHost = { SnackbarHost(snackbarHostState) },
) {
Column(
modifier = Modifier

11
features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt

@ -24,8 +24,6 @@ import androidx.compose.material.icons.outlined.DeveloperMode @@ -24,8 +24,6 @@ import androidx.compose.material.icons.outlined.DeveloperMode
import androidx.compose.material.icons.outlined.Help
import androidx.compose.material.icons.outlined.InsertChart
import androidx.compose.material.icons.outlined.VerifiedUser
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@ -41,6 +39,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight @@ -41,6 +39,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.SnackbarHost
import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.MatrixUserProvider
@ -65,13 +64,7 @@ fun PreferencesRootView( @@ -65,13 +64,7 @@ fun PreferencesRootView(
modifier = modifier,
onBackPressed = onBackPressed,
title = stringResource(id = CommonStrings.common_settings),
snackbarHost = {
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
)
}
}
snackbarHost = { SnackbarHost(snackbarHostState) }
) {
UserPreferences(state.myUser)
if (state.showCompleteVerification) {

11
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt

@ -28,8 +28,6 @@ import androidx.compose.foundation.lazy.itemsIndexed @@ -28,8 +28,6 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
@ -59,6 +57,7 @@ import io.element.android.libraries.designsystem.theme.components.FloatingAction @@ -59,6 +57,7 @@ import io.element.android.libraries.designsystem.theme.components.FloatingAction
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
import io.element.android.libraries.designsystem.utils.SnackbarHost
import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.designsystem.R as DrawableR
@ -227,13 +226,7 @@ fun RoomListContent( @@ -227,13 +226,7 @@ fun RoomListContent(
)
}
},
snackbarHost = {
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
)
}
},
snackbarHost = { SnackbarHost(snackbarHostState) },
)
}

2
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt

@ -83,7 +83,7 @@ internal fun RequestVerificationHeader( @@ -83,7 +83,7 @@ internal fun RequestVerificationHeader(
Spacer(modifier = Modifier.height(12.dp))
Button(
text = stringResource(CommonStrings.action_continue),
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
modifier = Modifier.fillMaxWidth(),
onClick = onVerifyClicked,
)

53
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/ButtonVisuals.kt

@ -0,0 +1,53 @@ @@ -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.designsystem.components.button
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import io.element.android.libraries.designsystem.theme.components.Button
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.TextButton
/**
* A sealed class that represents the different visual styles that a button can have.
*/
sealed interface ButtonVisuals {
val action: () -> Unit
/**
* Creates a [Button] composable based on the visual state.
*/
@Composable
fun Composable()
data class Text(val text: String, override val action: () -> Unit) : ButtonVisuals {
@Composable
override fun Composable() {
TextButton(text = text, onClick = action)
}
}
data class Icon(val iconSource: IconSource, override val action: () -> Unit) : ButtonVisuals {
@Composable
override fun Composable() {
IconButton(onClick = action) {
Icon(iconSource.getPainter(), iconSource.contentDescription)
}
}
}
}

1
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/PreviewGroup.kt

@ -30,6 +30,7 @@ object PreviewGroup { @@ -30,6 +30,7 @@ object PreviewGroup {
const val Preferences = "Preferences"
const val Progress = "Progress Indicators"
const val Search = "Search views"
const val Snackbars = "Snackbars"
const val Sliders = "Sliders"
const val Text = "Text"
const val TextFields = "TextFields"

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ruler/WithRulers.kt

@ -78,7 +78,7 @@ private fun ContentToPreview() { @@ -78,7 +78,7 @@ private fun ContentToPreview() {
WithRulers(xRulersOffset = 20.dp, yRulersOffset = 15.dp) {
OutlinedButton(
text = "A Button with rulers on it!",
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
onClick = {},
)
}

6
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt

@ -72,19 +72,19 @@ internal fun SimpleAlertDialogContent( @@ -72,19 +72,19 @@ internal fun SimpleAlertDialogContent(
// Having this 3rd action is discouraged, see https://m3.material.io/components/dialogs/guidelines#e13b68f5-e367-4275-ad6f-c552ee8e358f
TextButton(
text = thirdButtonText,
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
onClick = onThirdButtonClicked,
)
}
TextButton(
text = cancelText,
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
onClick = onCancelClicked,
)
if (submitText != null) {
Button(
text = submitText,
buttonSize = ButtonSize.Medium,
size = ButtonSize.Medium,
onClick = onSubmitClicked,
)
}

143
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt

@ -32,6 +32,7 @@ import androidx.compose.foundation.progressSemantics @@ -32,6 +32,7 @@ import androidx.compose.foundation.progressSemantics
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
@ -41,6 +42,7 @@ import androidx.compose.ui.Alignment @@ -41,6 +42,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.isSpecified
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
@ -60,10 +62,19 @@ fun Button( @@ -60,10 +62,19 @@ fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
buttonSize: ButtonSize = ButtonSize.Large,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(text, onClick, ButtonStyle.Filled, modifier, enabled, buttonSize, showProgress, leadingIcon)
) = ButtonInternal(
text = text,
onClick = onClick,
style = ButtonStyle.Filled,
modifier = modifier,
enabled = enabled,
size = size,
showProgress = showProgress,
leadingIcon = leadingIcon
)
@Composable
fun OutlinedButton(
@ -71,10 +82,19 @@ fun OutlinedButton( @@ -71,10 +82,19 @@ fun OutlinedButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
buttonSize: ButtonSize = ButtonSize.Large,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(text, onClick, ButtonStyle.Outlined, modifier, enabled, buttonSize, showProgress, leadingIcon)
) = ButtonInternal(
text = text,
onClick = onClick,
style = ButtonStyle.Outlined,
modifier = modifier,
enabled = enabled,
size = size,
showProgress = showProgress,
leadingIcon = leadingIcon
)
@Composable
fun TextButton(
@ -82,17 +102,27 @@ fun TextButton( @@ -82,17 +102,27 @@ fun TextButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
buttonSize: ButtonSize = ButtonSize.Large,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(text, onClick, ButtonStyle.Text, modifier, enabled, buttonSize, showProgress, leadingIcon)
) = ButtonInternal(
text = text,
onClick = onClick,
style = ButtonStyle.Text,
modifier = modifier,
enabled = enabled,
size = size,
showProgress = showProgress,
leadingIcon = leadingIcon
)
@Composable
private fun ButtonInternal(
internal fun ButtonInternal(
text: String,
onClick: () -> Unit,
style: ButtonStyle,
modifier: Modifier = Modifier,
colors: ButtonColors = style.getColors(),
enabled: Boolean = true,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
@ -123,21 +153,6 @@ private fun ButtonInternal( @@ -123,21 +153,6 @@ private fun ButtonInternal(
ButtonStyle.Text -> RectangleShape
}
val colors = when (style) {
ButtonStyle.Filled -> ButtonDefaults.buttonColors(
containerColor = ElementTheme.materialColors.primary,
contentColor = ElementTheme.materialColors.onPrimary,
disabledContainerColor = ElementTheme.colors.bgActionPrimaryDisabled,
disabledContentColor = ElementTheme.colors.textOnSolidPrimary
)
ButtonStyle.Outlined, ButtonStyle.Text -> ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = ElementTheme.materialColors.primary,
disabledContainerColor = Color.Transparent,
disabledContentColor = ElementTheme.colors.textDisabled,
)
}
val border = when (style) {
ButtonStyle.Filled, ButtonStyle.Text -> null
ButtonStyle.Outlined -> BorderStroke(
@ -202,8 +217,10 @@ private fun ButtonInternal( @@ -202,8 +217,10 @@ private fun ButtonInternal(
}
sealed interface IconSource {
data class Resource(val id: Int) : IconSource
data class Vector(val vector: ImageVector) : IconSource
val contentDescription: String?
data class Resource(val id: Int, override val contentDescription: String? = null) : IconSource
data class Vector(val vector: ImageVector, override val contentDescription: String? = null) : IconSource
@Composable
fun getPainter(): Painter = when (this) {
@ -216,16 +233,38 @@ enum class ButtonSize { @@ -216,16 +233,38 @@ enum class ButtonSize {
Medium, Large
}
private enum class ButtonStyle {
Filled, Outlined, Text
internal enum class ButtonStyle {
Filled, Outlined, Text;
@Composable
fun getColors(): ButtonColors = when (this) {
Filled -> ButtonDefaults.buttonColors(
containerColor = ElementTheme.materialColors.primary,
contentColor = ElementTheme.materialColors.onPrimary,
disabledContainerColor = ElementTheme.colors.bgActionPrimaryDisabled,
disabledContentColor = ElementTheme.colors.textOnSolidPrimary
)
Outlined -> ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = ElementTheme.materialColors.primary,
disabledContainerColor = Color.Transparent,
disabledContentColor = ElementTheme.colors.textDisabled,
)
Text -> ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary,
disabledContainerColor = Color.Transparent,
disabledContentColor = ElementTheme.colors.textDisabled,
)
}
}
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun FilledButtonMediumPreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Filled,
buttonSize = ButtonSize.Medium,
style = ButtonStyle.Filled,
size = ButtonSize.Medium,
)
}
@ -233,8 +272,8 @@ internal fun FilledButtonMediumPreview() { @@ -233,8 +272,8 @@ internal fun FilledButtonMediumPreview() {
@Composable
internal fun FilledButtonLargePreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Filled,
buttonSize = ButtonSize.Large,
style = ButtonStyle.Filled,
size = ButtonSize.Large,
)
}
@ -242,8 +281,8 @@ internal fun FilledButtonLargePreview() { @@ -242,8 +281,8 @@ internal fun FilledButtonLargePreview() {
@Composable
internal fun OutlinedButtonMediumPreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Outlined,
buttonSize = ButtonSize.Medium,
style = ButtonStyle.Outlined,
size = ButtonSize.Medium,
)
}
@ -251,8 +290,8 @@ internal fun OutlinedButtonMediumPreview() { @@ -251,8 +290,8 @@ internal fun OutlinedButtonMediumPreview() {
@Composable
internal fun OutlinedButtonLargePreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Outlined,
buttonSize = ButtonSize.Large,
style = ButtonStyle.Outlined,
size = ButtonSize.Large,
)
}
@ -260,8 +299,8 @@ internal fun OutlinedButtonLargePreview() { @@ -260,8 +299,8 @@ internal fun OutlinedButtonLargePreview() {
@Composable
internal fun TextButtonMediumPreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Text,
buttonSize = ButtonSize.Medium,
style = ButtonStyle.Text,
size = ButtonSize.Medium,
)
}
@ -269,15 +308,15 @@ internal fun TextButtonMediumPreview() { @@ -269,15 +308,15 @@ internal fun TextButtonMediumPreview() {
@Composable
internal fun TextButtonLargePreview() {
ButtonCombinationPreview(
buttonStyle = ButtonStyle.Text,
buttonSize = ButtonSize.Large,
style = ButtonStyle.Text,
size = ButtonSize.Large,
)
}
@Composable
private fun ButtonCombinationPreview(
buttonStyle: ButtonStyle,
buttonSize: ButtonSize,
style: ButtonStyle,
size: ButtonSize,
modifier: Modifier = Modifier,
) {
ElementThemedPreview {
@ -290,24 +329,24 @@ private fun ButtonCombinationPreview( @@ -290,24 +329,24 @@ private fun ButtonCombinationPreview(
// Normal
ButtonRowPreview(
modifier = Modifier.then(modifier),
buttonStyle = buttonStyle,
buttonSize = buttonSize,
style = style,
size = size,
)
// With icon
ButtonRowPreview(
modifier = Modifier.then(modifier),
leadingIcon = IconSource.Vector(Icons.Outlined.Share),
buttonStyle = buttonStyle,
buttonSize = buttonSize,
style = style,
size = size,
)
// With progress
ButtonRowPreview(
modifier = Modifier.then(modifier),
showProgress = true,
buttonStyle = buttonStyle,
buttonSize = buttonSize,
style = style,
size = size,
)
}
}
@ -315,8 +354,8 @@ private fun ButtonCombinationPreview( @@ -315,8 +354,8 @@ private fun ButtonCombinationPreview(
@Composable
private fun ButtonRowPreview(
buttonStyle: ButtonStyle,
buttonSize: ButtonSize,
style: ButtonStyle,
size: ButtonSize,
modifier: Modifier = Modifier,
leadingIcon: IconSource? = null,
showProgress: Boolean = false,
@ -326,8 +365,8 @@ private fun ButtonRowPreview( @@ -326,8 +365,8 @@ private fun ButtonRowPreview(
text = "A button",
showProgress = showProgress,
onClick = {},
style = buttonStyle,
size = buttonSize,
style = style,
size = size,
leadingIcon = leadingIcon,
modifier = Modifier.then(modifier),
)
@ -336,8 +375,8 @@ private fun ButtonRowPreview( @@ -336,8 +375,8 @@ private fun ButtonRowPreview(
showProgress = showProgress,
enabled = false,
onClick = {},
style = buttonStyle,
size = buttonSize,
style = style,
size = size,
leadingIcon = leadingIcon,
modifier = Modifier.then(modifier),
)

23
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt

@ -18,15 +18,21 @@ package io.element.android.libraries.designsystem.theme.components @@ -18,15 +18,21 @@ package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.theme.ElementTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -43,7 +49,11 @@ fun MediumTopAppBar( @@ -43,7 +49,11 @@ fun MediumTopAppBar(
title = title,
modifier = modifier,
navigationIcon = navigationIcon,
actions = actions,
actions = {
CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.textActionPrimary) {
actions()
}
},
windowInsets = windowInsets,
colors = colors,
scrollBehavior = scrollBehavior,
@ -58,5 +68,14 @@ internal fun MediumTopAppBarPreview() = @@ -58,5 +68,14 @@ internal fun MediumTopAppBarPreview() =
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ContentToPreview() {
MediumTopAppBar(title = { Text(text = "Title") })
MediumTopAppBar(
title = { Text(text = "Title") },
navigationIcon = { BackButton(onClick = {}) },
actions = {
TextButton(text = "Action", onClick = {})
IconButton(onClick = {}) {
Icon(imageVector = Icons.Default.Share, contentDescription = null)
}
}
)
}

147
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Snackbar.kt

@ -0,0 +1,147 @@ @@ -0,0 +1,147 @@
/*
* 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.theme.components
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.SnackbarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.button.ButtonVisuals
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.theme.SnackBarLabelColorDark
import io.element.android.libraries.theme.SnackBarLabelColorLight
@Composable
fun Snackbar(
message: String,
modifier: Modifier = Modifier,
action: ButtonVisuals? = null,
dismissAction: ButtonVisuals? = null,
actionOnNewLine: Boolean = false,
shape: Shape = RoundedCornerShape(8.dp),
containerColor: Color = SnackbarDefaults.color,
contentColor: Color = ElementTheme.materialColors.inverseOnSurface,
actionContentColor: Color = actionContentColor(),
dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor,
) {
Snackbar(
modifier = modifier,
action = action?.let { @Composable { it.Composable() } },
dismissAction = dismissAction?.let { @Composable { it.Composable() } },
actionOnNewLine = actionOnNewLine,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
actionContentColor = actionContentColor,
dismissActionContentColor = dismissActionContentColor,
content = { Text(text = message) },
)
}
@Composable
fun Snackbar(
modifier: Modifier = Modifier,
action: @Composable (() -> Unit)? = null,
dismissAction: @Composable (() -> Unit)? = null,
actionOnNewLine: Boolean = false,
shape: Shape = RoundedCornerShape(8.dp),
containerColor: Color = SnackbarDefaults.color,
contentColor: Color = ElementTheme.materialColors.inverseOnSurface,
actionContentColor: Color = actionContentColor(),
dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor,
content: @Composable () -> Unit
) {
androidx.compose.material3.Snackbar(
modifier = modifier,
action = action,
dismissAction = dismissAction,
actionOnNewLine = actionOnNewLine,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
actionContentColor = actionContentColor,
dismissActionContentColor = dismissActionContentColor,
content = content,
)
}
// TODO this color is temporary, an `inverse` version should be added to the semantic colors instead
@Composable
private fun actionContentColor(): Color {
return if (ElementTheme.isLightTheme) {
SnackBarLabelColorLight
} else {
SnackBarLabelColorDark
}
}
@Preview(name = "Snackbar", group = PreviewGroup.Snackbars)
@Composable
internal fun SnackbarPreview() {
ElementThemedPreview {
Snackbar(message = "Snackbar supporting text")
}
}
@Preview(name = "Snackbar with action", group = PreviewGroup.Snackbars)
@Composable
internal fun SnackbarWithActionPreview() {
ElementThemedPreview {
Snackbar(message = "Snackbar supporting text", action = ButtonVisuals.Text("Action", {}))
}
}
@Preview(name = "Snackbar with action and close button", group = PreviewGroup.Snackbars)
@Composable
internal fun SnackbarWithActionAndCloseButtonPreview() {
ElementThemedPreview {
Snackbar(
message = "Snackbar supporting text",
action = ButtonVisuals.Text("Action", {}),
dismissAction = ButtonVisuals.Icon(IconSource.Vector(Icons.Default.Close), {})
)
}
}
@Preview(name = "Snackbar with action on new line", group = PreviewGroup.Snackbars)
@Composable
internal fun SnackbarWithActionOnNewLinePreview() {
ElementThemedPreview {
Snackbar(message = "Snackbar supporting text", action = ButtonVisuals.Text("Action", {}), actionOnNewLine = true)
}
}
@Preview(name = "Snackbar with action and close button on new line", group = PreviewGroup.Snackbars)
@Composable
internal fun SnackbarWithActionOnNewLineAndCloseButtonPreview() {
ElementThemedPreview {
Snackbar(
message = "Snackbar supporting text",
action = ButtonVisuals.Text("Action", {}),
dismissAction = ButtonVisuals.Icon(IconSource.Vector(Icons.Default.Close), {}),
actionOnNewLine = true
)
}
}

23
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt

@ -18,15 +18,21 @@ package io.element.android.libraries.designsystem.theme.components @@ -18,15 +18,21 @@ package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.theme.ElementTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -43,7 +49,11 @@ fun TopAppBar( @@ -43,7 +49,11 @@ fun TopAppBar(
title = title,
modifier = modifier,
navigationIcon = navigationIcon,
actions = actions,
actions = {
CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.textActionPrimary) {
actions()
}
},
windowInsets = windowInsets,
colors = colors,
scrollBehavior = scrollBehavior,
@ -58,5 +68,14 @@ internal fun TopAppBarPreview() = @@ -58,5 +68,14 @@ internal fun TopAppBarPreview() =
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ContentToPreview() {
TopAppBar(title = { Text(text = "Title") })
TopAppBar(
title = { Text(text = "Title") },
navigationIcon = { BackButton(onClick = {}) },
actions = {
TextButton(text = "Action", onClick = {})
IconButton(onClick = {}) {
Icon(imageVector = Icons.Default.Share, contentDescription = null)
}
}
)
}

19
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt

@ -17,6 +17,8 @@ @@ -17,6 +17,8 @@
package io.element.android.libraries.designsystem.utils
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
@ -25,7 +27,11 @@ import androidx.compose.runtime.State @@ -25,7 +27,11 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import io.element.android.libraries.designsystem.components.button.ButtonVisuals
import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.Snackbar
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@ -65,6 +71,19 @@ fun SnackbarDispatcher.collectSnackbarMessageAsState(): State<SnackbarMessage?> @@ -65,6 +71,19 @@ fun SnackbarDispatcher.collectSnackbarMessageAsState(): State<SnackbarMessage?>
return snackbarMessage.collectAsState(initial = null)
}
@Composable
fun SnackbarHost(hostState: SnackbarHostState, modifier: Modifier = Modifier) {
androidx.compose.material3.SnackbarHost(hostState, modifier) { data ->
Snackbar(
message = data.visuals.message,
action = data.visuals.actionLabel?.let { ButtonVisuals.Text(it, data::performAction) },
dismissAction = if (data.visuals.withDismissAction) {
ButtonVisuals.Icon(IconSource.Vector(Icons.Default.Close), data::dismiss)
} else null,
)
}
}
@Composable
fun rememberSnackbarHostState(snackbarMessage: SnackbarMessage?): SnackbarHostState {
val snackbarHostState = remember { SnackbarHostState() }

5
libraries/theme/src/main/kotlin/io/element/android/libraries/theme/LegacyColors.kt

@ -17,6 +17,8 @@ @@ -17,6 +17,8 @@
package io.element.android.libraries.theme
import androidx.compose.ui.graphics.Color
import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens
import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens
// =================================================================================================
// IMPORTANT!
@ -26,3 +28,6 @@ import androidx.compose.ui.graphics.Color @@ -26,3 +28,6 @@ import androidx.compose.ui.graphics.Color
// =================================================================================================
val LinkColor = Color(0xFF0086E6)
val SnackBarLabelColorLight = LightDesignTokens.colorGray700
val SnackBarLabelColorDark = DarkDesignTokens.colorGray700

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_4,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_5,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.screens.waitlistscreen_null_DefaultGroup_WaitListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.media.viewer_null_DefaultGroup_MediaViewerViewDarkPreview_0_null_9,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl_null_DefaultGroup_RoomDetailsDarkPreview--1_1_null_8,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl_null_DefaultGroup_RoomDetailsLightPreview--0_0_null_8,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_MediumTopAppBarPreview_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_TopAppBarPreview_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbar_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithaction_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactionandclosebutton_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactionandclosebuttononnewline_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Snackbars_Snackbarwithactiononnewline_0_null,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.
Loading…
Cancel
Save