Address design comments on the change server screen (#196)

* Address design comments on the change server screen

* Update screenshots

* Address review comments.
This commit is contained in:
Jorge Martin Espinosa
2023-03-09 14:51:44 +01:00
committed by GitHub
parent f6dc48bec8
commit b149914c73
51 changed files with 167 additions and 105 deletions

1
changelog.d/101.bugfix Normal file
View File

@@ -0,0 +1 @@
Address design issues in the change server screen

View File

@@ -17,6 +17,7 @@
package io.element.android.features.login.changeserver
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -44,16 +45,26 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.UrlAnnotation
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
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.login.R
import io.element.android.features.login.error.changeServerError
import io.element.android.features.login.util.LoginConstants
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.LinkColor
import io.element.android.libraries.designsystem.components.ClickableLinkText
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.form.textFieldState
@@ -70,12 +81,13 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextField
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.theme.components.onTabOrEnterKeyFocusNext
import io.element.android.libraries.designsystem.theme.roomListRoomName
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag
import org.matrix.rustcomponents.sdk.AuthenticationException
import io.element.android.libraries.ui.strings.R as StringR
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class)
@Composable
fun ChangeServerView(
state: ChangeServerState,
@@ -215,12 +227,27 @@ fun ChangeServerView(
}
}
Spacer(Modifier.height(8.dp))
Text(
text = stringResource(StringR.string.server_selection_server_footer),
val footerMessage = stringResource(StringR.string.server_selection_server_footer)
val footerAction = stringResource(StringR.string.server_selection_server_footer_action)
val footerText = buildAnnotatedString {
val defaultColor = MaterialTheme.colorScheme.tertiary
withStyle(ParagraphStyle(textAlign = TextAlign.Start)) {
withStyle(SpanStyle(color = defaultColor)) {
append(footerMessage)
append(" ")
}
val start = length
withStyle(SpanStyle(color = LinkColor)) {
append(footerAction)
}
addUrlAnnotation(UrlAnnotation(LoginConstants.SLIDING_SYNC_READ_MORE_URL), start, length)
}
}
ClickableLinkText(
text = footerText,
interactionSource = MutableInteractionSource(),
modifier = Modifier.padding(horizontal = 16.dp),
style = ElementTextStyles.Regular.caption1,
textAlign = TextAlign.Start,
color = MaterialTheme.colorScheme.tertiary,
)
Spacer(Modifier.height(32.dp))
Button(
@@ -259,6 +286,8 @@ internal fun SlidingSyncNotSupportedDialog(onLearnMoreClicked: () -> Unit, onDis
onDismiss = onDismiss,
submitText = stringResource(StringR.string.action_learn_more),
onSubmitClicked = onLearnMoreClicked,
onCancelClicked = onDismiss,
emphasizeSubmitButton = true,
title = stringResource(StringR.string.server_selection_sliding_sync_alert_title),
content = stringResource(StringR.string.server_selection_sliding_sync_alert_message),
)

View File

@@ -68,4 +68,4 @@ val ElementGreen = Color(0xFF0DBD8B)
val ElementOrange = Color(0xFFD9B072)
val Vermilion = Color(0xFFFF5B55)
val LinkColor = Color(0xFF054F6E)
val LinkColor = Color(0xFF0086E6)

View File

@@ -30,6 +30,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
@@ -40,14 +41,15 @@ import io.element.android.libraries.designsystem.theme.components.Text
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf
@OptIn(ExperimentalTextApi::class)
@Composable
fun ClickableLinkText(
text: AnnotatedString,
linkAnnotationTag: String,
onClick: () -> Unit,
onLongClick: () -> Unit,
interactionSource: MutableInteractionSource,
modifier: Modifier = Modifier,
linkAnnotationTag: String = "",
onClick: () -> Unit = {},
onLongClick: () -> Unit = {},
style: TextStyle = LocalTextStyle.current,
inlineContent: ImmutableMap<String, InlineTextContent> = persistentMapOf(),
) {
@@ -71,12 +73,14 @@ fun ClickableLinkText(
) { offset ->
layoutResult.value?.let { layoutResult ->
val position = layoutResult.getOffsetForPosition(offset)
val linkAnnotations =
val linkUrlAnnotations = text.getUrlAnnotations(position, position)
.map { AnnotatedString.Range(it.item.url, it.start, it.end, linkAnnotationTag) }
val linkStringAnnotations = linkUrlAnnotations +
text.getStringAnnotations(linkAnnotationTag, position, position)
if (linkAnnotations.isEmpty()) {
if (linkStringAnnotations.isEmpty()) {
onClick()
} else {
uriHandler.openUri(linkAnnotations.first().item)
uriHandler.openUri(linkStringAnnotations.first().item)
}
}
}

View File

@@ -16,9 +16,6 @@
package io.element.android.libraries.designsystem.components.dialogs
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.MaterialTheme
@@ -29,28 +26,33 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
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.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.BooleanProvider
import io.element.android.libraries.ui.strings.R as StringR
@Composable
fun ConfirmationDialog(
title: String,
content: String,
onSubmitClicked: () -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
submitText: String = stringResource(id = StringR.string.ok),
cancelText: String = stringResource(id = StringR.string.action_cancel),
thirdButtonText: String? = null,
onSubmitClicked: () -> Unit = {},
onCancelClicked: () -> Unit = {},
emphasizeSubmitButton: Boolean = false,
onCancelClicked: () -> Unit = onDismiss,
onThirdButtonClicked: () -> Unit = {},
onDismiss: () -> Unit = {},
shape: Shape = AlertDialogDefaults.shape,
containerColor: Color = AlertDialogDefaults.containerColor,
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
// According to the design team, `primary` should be used here instead of the default `onSurface`
titleContentColor: Color = MaterialTheme.colorScheme.primary,
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
) {
@@ -79,9 +81,16 @@ fun ConfirmationDialog(
TextButton(
onClick = {
onSubmitClicked()
}
},
) {
Text(submitText)
Text(
submitText,
style = if (emphasizeSubmitButton) {
ElementTextStyles.Bold.subheadline
} else {
MaterialTheme.typography.labelLarge
}
)
}
},
shape = shape,
@@ -95,17 +104,22 @@ fun ConfirmationDialog(
@Preview
@Composable
internal fun ConfirmationDialogLightPreview() = ElementPreviewLight { ContentToPreview() }
internal fun ConfirmationDialogLightPreview(@PreviewParameter(BooleanProvider::class) emphasizeSubmitButton: Boolean) =
ElementPreviewLight { ContentToPreview(emphasizeSubmitButton) }
@Preview
@Composable
internal fun ConfirmationDialogDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun ConfirmationDialogDarkPreview(@PreviewParameter(BooleanProvider::class) emphasizeSubmitButton: Boolean) =
ElementPreviewDark { ContentToPreview(emphasizeSubmitButton) }
@Composable
private fun ContentToPreview() {
private fun ContentToPreview(emphasizeSubmitButton: Boolean) {
ConfirmationDialog(
title = "Title",
content = "Content",
thirdButtonText = "Disable"
thirdButtonText = "Disable",
onSubmitClicked = {},
onDismiss = {},
emphasizeSubmitButton = emphasizeSubmitButton,
)
}

View File

@@ -24,6 +24,7 @@ import io.element.android.libraries.designsystem.Azure
import io.element.android.libraries.designsystem.Black_800
import io.element.android.libraries.designsystem.Black_950
import io.element.android.libraries.designsystem.DarkGrey
import io.element.android.libraries.designsystem.Gray_300
import io.element.android.libraries.designsystem.Gray_400
import io.element.android.libraries.designsystem.Gray_450
import io.element.android.libraries.designsystem.SystemGrey5Dark
@@ -59,7 +60,7 @@ val materialColorSchemeDark = darkColorScheme(
surface = Black_800,
onSurface = Color.White,
surfaceVariant = Black_950,
onSurfaceVariant = Color.White,
onSurfaceVariant = Gray_300,
// TODO surfaceTint = primary,
// TODO inverseSurface = ColorDarkTokens.InverseSurface,
// TODO inverseOnSurface = ColorDarkTokens.InverseOnSurface,

View File

@@ -12,6 +12,7 @@
<string name="login_hide_password">Hide password</string>
<string name="ex_choose_server_subtitle">What is the address of your server?</string>
<string name="server_selection_server_footer">You can only connect to an existing server that supports sliding sync. Your homeserver admin will need to configure it.</string>
<string name="server_selection_server_footer_action">Learn more</string>
<string name="server_selection_sliding_sync_alert_title">Server not supported</string>
<string name="server_selection_sliding_sync_alert_message">This server currently doesn\'t support sliding sync.</string>
<!-- Create room -->