From 97eacae7a41b000179df7714e91097c1a7d655e1 Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Tue, 23 Jan 2024 18:13:06 +0100 Subject: [PATCH] feat: improve enrollment dialog (WPB-4372) (#2610) Co-authored-by: AndroidBob --- .../wire/android/ui/WireActivityDialogs.kt | 3 +- .../android/ui/authentication/ServerTitle.kt | 59 ++++++--- .../login/sso/LoginSSOScreen.kt | 3 +- .../com/wire/android/ui/common/WireDialog.kt | 118 +++++++++-------- .../ui/common/dialogs/CustomServerDialog.kt | 119 +++++++++++++++--- app/src/main/res/values/strings.xml | 9 +- 6 files changed, 225 insertions(+), 86 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/WireActivityDialogs.kt b/app/src/main/kotlin/com/wire/android/ui/WireActivityDialogs.kt index 180c054480..e00b00b375 100644 --- a/app/src/main/kotlin/com/wire/android/ui/WireActivityDialogs.kt +++ b/app/src/main/kotlin/com/wire/android/ui/WireActivityDialogs.kt @@ -219,8 +219,7 @@ fun CustomBackendDialog( ) { if (globalAppState.customBackendDialog != null) { CustomServerDialog( - serverLinksTitle = globalAppState.customBackendDialog.serverLinks.title, - serverLinksApi = globalAppState.customBackendDialog.serverLinks.api, + serverLinks = globalAppState.customBackendDialog.serverLinks, onDismiss = onDismiss, onConfirm = onConfirm ) diff --git a/app/src/main/kotlin/com/wire/android/ui/authentication/ServerTitle.kt b/app/src/main/kotlin/com/wire/android/ui/authentication/ServerTitle.kt index da422d3947..d8ce0da998 100644 --- a/app/src/main/kotlin/com/wire/android/ui/authentication/ServerTitle.kt +++ b/app/src/main/kotlin/com/wire/android/ui/authentication/ServerTitle.kt @@ -44,9 +44,11 @@ import com.wire.android.ui.common.WireDialogButtonType import com.wire.android.ui.common.clickable import com.wire.android.ui.common.colorsScheme import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography +import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.android.util.ui.stringWithStyledArgs import com.wire.kalium.logic.configuration.server.ServerConfig import java.net.URL @@ -93,24 +95,47 @@ fun ServerTitle( ) if (serverFullDetailsDialogState) { - WireDialog( - title = stringResource(id = R.string.server_details_dialog_title), - text = LocalContext.current.resources.stringWithStyledArgs( - R.string.server_details_dialog_body, - MaterialTheme.wireTypography.body02, - MaterialTheme.wireTypography.body02, - normalColor = colorsScheme().secondaryText, - argsColor = colorsScheme().onBackground, - serverLinks.title, - serverLinks.api - ), - onDismiss = { serverFullDetailsDialogState = false }, - optionButton1Properties = WireDialogButtonProperties( - stringResource(id = R.string.label_ok), - onClick = { serverFullDetailsDialogState = false }, - type = WireDialogButtonType.Primary - ) + ServerEnrollmentDialogContent( + serverLinks = serverLinks, + onClick = { serverFullDetailsDialogState = false }, + onDismiss = { serverFullDetailsDialogState = false } ) } } } + +@Composable +private fun ServerEnrollmentDialogContent( + serverLinks: ServerConfig.Links, + onDismiss: () -> Unit, + onClick: () -> Unit, +) { + WireDialog( + title = stringResource(id = R.string.server_details_dialog_title), + text = LocalContext.current.resources.stringWithStyledArgs( + R.string.server_details_dialog_body, + MaterialTheme.wireTypography.body02, + MaterialTheme.wireTypography.body02, + normalColor = colorsScheme().secondaryText, + argsColor = colorsScheme().onBackground, + serverLinks.title, + serverLinks.api + ), + onDismiss = onDismiss, + optionButton1Properties = WireDialogButtonProperties( + stringResource(id = R.string.label_ok), + onClick = onClick, + type = WireDialogButtonType.Primary + ) + ) +} + +@PreviewMultipleThemes +@Composable +fun PreviewServerEnrollmentDialog() = WireTheme { + ServerEnrollmentDialogContent( + serverLinks = ServerConfig.DEFAULT, + onClick = { }, + onDismiss = { } + ) +} diff --git a/app/src/main/kotlin/com/wire/android/ui/authentication/login/sso/LoginSSOScreen.kt b/app/src/main/kotlin/com/wire/android/ui/authentication/login/sso/LoginSSOScreen.kt index d60f10de2d..211e26273c 100644 --- a/app/src/main/kotlin/com/wire/android/ui/authentication/login/sso/LoginSSOScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/authentication/login/sso/LoginSSOScreen.kt @@ -142,8 +142,7 @@ private fun LoginSSOContent( if (loginState.customServerDialogState != null) { CustomServerDialog( - serverLinksTitle = loginState.customServerDialogState.serverLinks.title, - serverLinksApi = loginState.customServerDialogState.serverLinks.api, + serverLinks = loginState.customServerDialogState.serverLinks, onDismiss = onCustomServerDialogDismiss, onConfirm = onCustomServerDialogConfirm ) diff --git a/app/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt b/app/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt index b3375ee30e..14f24856b5 100644 --- a/app/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt +++ b/app/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt @@ -188,29 +188,25 @@ private fun WireDialogContent( .padding(contentPadding), horizontalAlignment = if (centerContent) Alignment.CenterHorizontally else Alignment.Start ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = title, - style = MaterialTheme.wireTypography.title02, - ) - if (titleLoading) { - WireCircularProgressIndicator(progressColor = MaterialTheme.wireColorScheme.onBackground) - } - } - text?.let { - LazyColumn( - modifier = Modifier - .weight(1f, fill = false) - .fillMaxWidth() - ) { + // Title + TitleDialogSection(title, titleLoading) + + // Dynamic sized body content + LazyColumn( + modifier = Modifier + .weight(1f, fill = false) + .padding( + top = MaterialTheme.wireDimensions.dialogTextsSpacing, + bottom = MaterialTheme.wireDimensions.dialogTextsSpacing + ) + .fillMaxWidth() + ) { + text?.let { item { ClickableText( text = text, style = MaterialTheme.wireTypography.body01, - modifier = Modifier.padding( - top = MaterialTheme.wireDimensions.dialogTextsSpacing, - bottom = MaterialTheme.wireDimensions.dialogTextsSpacing, - ), + modifier = Modifier.padding(bottom = MaterialTheme.wireDimensions.dialogTextsSpacing), onClick = { offset -> text.getStringAnnotations( tag = MarkdownConstants.TAG_URL, @@ -221,42 +217,66 @@ private fun WireDialogContent( ) } } - } - content?.let { - Box { - it.invoke() - } - } - val containsAnyButton = dismissButtonProperties != null || optionButton1Properties != null || optionButton2Properties != null - val dialogButtonsSpacing = if (containsAnyButton) dimensions().dialogButtonsSpacing else dimensions().spacing0x - if (buttonsHorizontalAlignment) { - Row(Modifier.padding(top = dialogButtonsSpacing)) { - dismissButtonProperties.getButton(Modifier.weight(1f)) - if (dismissButtonProperties != null) { - Spacer(Modifier.width(dialogButtonsSpacing)) - } - optionButton1Properties.getButton(Modifier.weight(1f)) - if (optionButton2Properties != null) { - Spacer(Modifier.width(dialogButtonsSpacing)) + content?.let { + item { + Box { + it.invoke() + } } - optionButton2Properties.getButton(Modifier.weight(1f)) } - } else { - Column(Modifier.padding(top = dialogButtonsSpacing)) { - optionButton1Properties.getButton() + } - if (optionButton2Properties != null) { - Spacer(Modifier.height(dialogButtonsSpacing)) - } - optionButton2Properties.getButton() + // Buttons actions + DialogButtonsSection(dismissButtonProperties, optionButton1Properties, optionButton2Properties, buttonsHorizontalAlignment) + } + } +} - if (dismissButtonProperties != null) { - Spacer(Modifier.height(dialogButtonsSpacing)) - } - dismissButtonProperties.getButton() - } +@Composable +private fun TitleDialogSection(title: String, titleLoading: Boolean) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = title, style = MaterialTheme.wireTypography.title02) + if (titleLoading) { + WireCircularProgressIndicator(progressColor = MaterialTheme.wireColorScheme.onBackground) + } + } +} + +@Composable +private fun DialogButtonsSection( + dismissButtonProperties: WireDialogButtonProperties?, + optionButton1Properties: WireDialogButtonProperties?, + optionButton2Properties: WireDialogButtonProperties?, + buttonsHorizontalAlignment: Boolean +) { + val containsAnyButton = dismissButtonProperties != null || optionButton1Properties != null || optionButton2Properties != null + val dialogButtonsSpacing = if (containsAnyButton) dimensions().dialogButtonsSpacing else dimensions().spacing0x + if (buttonsHorizontalAlignment) { + Row(Modifier.padding(top = dialogButtonsSpacing)) { + dismissButtonProperties.getButton(Modifier.weight(1f)) + if (dismissButtonProperties != null) { + Spacer(Modifier.width(dialogButtonsSpacing)) + } + optionButton1Properties.getButton(Modifier.weight(1f)) + if (optionButton2Properties != null) { + Spacer(Modifier.width(dialogButtonsSpacing)) + } + optionButton2Properties.getButton(Modifier.weight(1f)) + } + } else { + Column(Modifier.padding(top = dialogButtonsSpacing)) { + optionButton1Properties.getButton() + + if (optionButton2Properties != null) { + Spacer(Modifier.height(dialogButtonsSpacing)) + } + optionButton2Properties.getButton() + + if (dismissButtonProperties != null) { + Spacer(Modifier.height(dialogButtonsSpacing)) } + dismissButtonProperties.getButton() } } } diff --git a/app/src/main/kotlin/com/wire/android/ui/common/dialogs/CustomServerDialog.kt b/app/src/main/kotlin/com/wire/android/ui/common/dialogs/CustomServerDialog.kt index 3e2c80feaf..a884f7266c 100644 --- a/app/src/main/kotlin/com/wire/android/ui/common/dialogs/CustomServerDialog.kt +++ b/app/src/main/kotlin/com/wire/android/ui/common/dialogs/CustomServerDialog.kt @@ -18,40 +18,46 @@ package com.wire.android.ui.common.dialogs +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext +import androidx.compose.runtime.getValue +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.res.stringResource +import androidx.compose.ui.text.style.TextDecoration import com.wire.android.R import com.wire.android.ui.common.WireDialog import com.wire.android.ui.common.WireDialogButtonProperties import com.wire.android.ui.common.WireDialogButtonType import com.wire.android.ui.common.button.WireButtonState import com.wire.android.ui.common.colorsScheme +import com.wire.android.ui.common.dimensions +import com.wire.android.ui.common.spacers.VerticalSpace import com.wire.android.ui.common.wireDialogPropertiesBuilder +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireTypography -import com.wire.android.util.ui.stringWithStyledArgs +import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.kalium.logic.configuration.server.ServerConfig @Composable internal fun CustomServerDialog( - serverLinksTitle: String, - serverLinksApi: String, + serverLinks: ServerConfig.Links, onDismiss: () -> Unit, onConfirm: () -> Unit ) { + var showDetails by remember { mutableStateOf(false) } WireDialog( title = stringResource(R.string.custom_backend_dialog_title), - text = LocalContext.current.resources.stringWithStyledArgs( - R.string.custom_backend_dialog_body, - MaterialTheme.wireTypography.body01, - MaterialTheme.wireTypography.body02, - colorsScheme().onBackground, - colorsScheme().onBackground, - serverLinksTitle, - serverLinksApi - ), - + text = stringResource(R.string.custom_backend_dialog_body), buttonsHorizontalAlignment = true, properties = wireDialogPropertiesBuilder( dismissOnBackPress = false, @@ -69,8 +75,91 @@ internal fun CustomServerDialog( type = WireDialogButtonType.Primary, state = WireButtonState.Default - ) + ), + content = { + Column { + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_name), + value = serverLinks.title + ) + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_api), + value = serverLinks.api + ) + if (showDetails) { + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_websocket), + value = serverLinks.webSocket + ) + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_blacklist), + value = serverLinks.blackList + ) + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_teams), + value = serverLinks.teams + ) + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_accounts), + value = serverLinks.accounts + ) + CustomServerPropertyInfo( + title = stringResource(id = R.string.custom_backend_dialog_body_backend_website), + value = serverLinks.website + ) + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = dimensions().spacing8x) + ) { + Text( + text = stringResource(id = if (showDetails) R.string.label_hide_details else R.string.label_show_details), + style = MaterialTheme.wireTypography.body02.copy( + textDecoration = TextDecoration.Underline, + color = MaterialTheme.colorScheme.primary + ), + modifier = Modifier + .align(Alignment.Start) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = { showDetails = !showDetails } + ) + ) + } + } + } ) } +@Composable +private fun CustomServerPropertyInfo( + title: String, + value: String +) { + Text( + text = title, + style = MaterialTheme.wireTypography.body01, + color = colorsScheme().onBackground, + ) + VerticalSpace.x4() + Text( + text = value, + style = MaterialTheme.wireTypography.body02, + color = colorsScheme().onBackground, + ) + VerticalSpace.x16() +} + data class CustomServerDialogState(val serverLinks: ServerConfig.Links) + +@PreviewMultipleThemes +@Composable +fun PreviewCustomServerDialog() = WireTheme { + CustomServerDialog( + serverLinks = ServerConfig.DEFAULT, + onConfirm = { }, + onDismiss = { } + ) +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5d0860c87b..2c08559428 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1009,7 +1009,14 @@ Open Profile You can\'t switch accounts while in a call Redirect to an on-premises backend? - If you proceed, your client will be redirected to the following on-premises backend:\n\nBackend name:\n%1$s\n\nBackend URL:\n%2$s + If you proceed, your client will be redirected to the following on-premises backend: + Backend name: + Backend URL: + blackListURL: + teamsURL: + accountsURL: + websiteURL: + backendWSURL: Receiving new messages Text copied to clipboard Logs