diff options
| author | David Göransson <david.goransson90@gmail.com> | 2023-09-29 09:22:54 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson90@gmail.com> | 2023-10-04 09:19:41 +0200 |
| commit | 6612e427a8090f55b2423557241c5727770fb923 (patch) | |
| tree | 198376c0b1501abad7344752681c14358dfc92d0 | |
| parent | a9af8f6f877f32431b87bb69b517e8c261042ca2 (diff) | |
| download | mullvadvpn-6612e427a8090f55b2423557241c5727770fb923.tar.xz mullvadvpn-6612e427a8090f55b2423557241c5727770fb923.zip | |
Update design to fullscreen
5 files changed, 155 insertions, 21 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt index 27946aae44..7417d6ae7c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt @@ -37,7 +37,7 @@ fun ReportProblemNoEmailDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) { Icon( painter = painterResource(id = R.drawable.icon_alert), contentDescription = null, - modifier = Modifier.size(Dimens.dialogIconSize), + modifier = Modifier.size(Dimens.dialogIconHeight), tint = Color.Unspecified ) }, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt index bbaecd78a9..f58552c671 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.window.DialogProperties -import androidx.compose.ui.window.SecureFlagPolicy import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.button.ActionButton import net.mullvad.mullvadvpn.lib.theme.AppTheme @@ -31,7 +30,7 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens import net.mullvad.mullvadvpn.viewmodel.SendingReportUiState @Composable -fun ShowReportProblemStateDialog( +fun ShowReportProblemState( sendingState: SendingReportUiState, onDismiss: () -> Unit, onClearForm: () -> Unit, @@ -98,7 +97,7 @@ fun ReportProblemSuccessDialog(email: String?, onConfirm: () -> Unit) { Icon( painter = painterResource(id = R.drawable.icon_success), contentDescription = stringResource(id = R.string.sent), - modifier = Modifier.size(Dimens.dialogIconSize), + modifier = Modifier.size(Dimens.dialogIconHeight), tint = Color.Unspecified ) }, @@ -154,11 +153,6 @@ fun ReportProblemSuccessDialog(email: String?, onConfirm: () -> Unit) { ) }, containerColor = MaterialTheme.colorScheme.background, - properties = - DialogProperties( - securePolicy = - if (email != null) SecureFlagPolicy.SecureOn else SecureFlagPolicy.Inherit - ) ) } @@ -181,7 +175,7 @@ fun ReportProblemErrorDialog(onDismiss: () -> Unit, retry: () -> Unit) { Icon( painter = painterResource(id = R.drawable.icon_fail), contentDescription = stringResource(id = R.string.failed_to_send), - modifier = Modifier.size(Dimens.dialogIconSize), + modifier = Modifier.size(Dimens.dialogIconHeight), tint = Color.Unspecified ) }, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt index 1a06c3ae77..f536523ccf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt @@ -2,10 +2,16 @@ package net.mullvad.mullvadvpn.compose.screen import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer 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.size import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -13,11 +19,19 @@ import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue 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 +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import me.onebone.toolbar.ScrollStrategy import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState @@ -26,7 +40,6 @@ import net.mullvad.mullvadvpn.compose.button.ActionButton import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar import net.mullvad.mullvadvpn.compose.dialog.ReportProblemNoEmailDialog -import net.mullvad.mullvadvpn.compose.dialog.ShowReportProblemStateDialog import net.mullvad.mullvadvpn.compose.textfield.mullvadWhiteTextFieldColors import net.mullvad.mullvadvpn.dataproxy.SendProblemReportResult import net.mullvad.mullvadvpn.lib.theme.AppTheme @@ -59,7 +72,7 @@ private fun ReportProblemConfirmNoEmailScreenPreview() { private fun ReportProblemSuccessScreenPreview() { AppTheme { ReportProblemScreen( - uiState = ReportProblemUiState(false, SendingReportUiState.Success(null)) + uiState = ReportProblemUiState(false, SendingReportUiState.Success("email@mail.com")) ) } } @@ -116,15 +129,28 @@ fun ReportProblemScreen( // Dialog to show sending states if (uiState.sendingState != null) { - ShowReportProblemStateDialog( - uiState.sendingState, - onDismiss = onClearSendResult, - onClearForm = { - email = "" - description = "" - }, - retry = { onSendReport(email, description) } - ) + Column( + modifier = + Modifier.fillMaxSize() + .padding(vertical = Dimens.mediumPadding, horizontal = Dimens.sideMargin) + ) { + when (uiState.sendingState) { + SendingReportUiState.Sending -> SendingContent() + is SendingReportUiState.Error -> + ErrorContent({ onSendReport(email, description) }, onClearSendResult) + is SendingReportUiState.Success -> SentContent(uiState.sendingState) + } + // ShowReportProblemState( + // uiState.sendingState, + // onDismiss = onClearSendResult, + // onClearForm = { + // email = "" + // description = "" + // }, + // retry = { onSendReport(email, description) } + // ) + return@CollapsingToolbarScaffold + } } // Dialog to show confirm if no email was added @@ -189,3 +215,115 @@ fun ReportProblemScreen( } } } + +@Composable +private fun ColumnScope.SendingContent() { + CircularProgressIndicator( + modifier = Modifier.align(Alignment.CenterHorizontally), + strokeCap = StrokeCap.Round, + strokeWidth = Dimens.loadingSpinnerStrokeWidth + ) + Spacer(modifier = Modifier.height(Dimens.problemReportIconToTitlePadding)) + Text( + text = stringResource(id = R.string.sending), + style = MaterialTheme.typography.headlineLarge, + color = MaterialTheme.colorScheme.onBackground + ) +} + +@Composable +private fun ColumnScope.SentContent(sendingState: SendingReportUiState.Success) { + Icon( + painter = painterResource(id = R.drawable.icon_success), + contentDescription = stringResource(id = R.string.sent), + modifier = Modifier.align(Alignment.CenterHorizontally).size(Dimens.dialogIconHeight), + tint = Color.Unspecified + ) + + Spacer(modifier = Modifier.height(Dimens.problemReportIconToTitlePadding)) + Text( + text = stringResource(id = R.string.sent), + style = MaterialTheme.typography.headlineLarge, + color = MaterialTheme.colorScheme.onBackground + ) + Text( + text = + buildAnnotatedString { + withStyle(SpanStyle(color = MaterialTheme.colorScheme.surface)) { + append(stringResource(id = R.string.sent_thanks)) + } + append(" ") + withStyle(SpanStyle(color = MaterialTheme.colorScheme.onPrimary)) { + append(stringResource(id = R.string.we_will_look_into_this)) + } + }, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth() + ) + + Spacer(modifier = Modifier.height(Dimens.smallPadding)) + sendingState.email?.let { + val emailTemplate = stringResource(R.string.sent_contact) + val annotatedEmailString = + remember(it) { + val emailStart = emailTemplate.indexOf('%') + + buildAnnotatedString { + append(emailTemplate.substring(0, emailStart)) + withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { + append(sendingState.email) + } + } + } + + Text( + text = annotatedEmailString, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.fillMaxWidth() + ) + } +} + +@Composable +private fun ColumnScope.ErrorContent(retry: () -> Unit, onDismiss: () -> Unit) { + Icon( + painter = painterResource(id = R.drawable.icon_fail), + contentDescription = stringResource(id = R.string.failed_to_send), + modifier = Modifier.size(Dimens.dialogIconHeight).align(Alignment.CenterHorizontally), + tint = Color.Unspecified + ) + Spacer(modifier = Modifier.height(Dimens.problemReportIconToTitlePadding)) + Text( + text = stringResource(id = R.string.failed_to_send), + style = MaterialTheme.typography.headlineLarge, + color = MaterialTheme.colorScheme.onBackground, + ) + Text( + text = stringResource(id = R.string.failed_to_send_details), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.weight(1f)) + ActionButton( + modifier = Modifier.fillMaxWidth().padding(vertical = Dimens.mediumPadding), + colors = + ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, + ), + onClick = onDismiss, + text = stringResource(id = R.string.edit_message) + ) + ActionButton( + modifier = Modifier.fillMaxWidth(), + colors = + ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.surface, + contentColor = MaterialTheme.colorScheme.onPrimary, + ), + onClick = retry, + text = stringResource(id = R.string.try_again) + ) +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt index 67eaeca48d..6ea8f198f1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt @@ -5,6 +5,7 @@ import java.io.File import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import kotlin.random.Random const val PROBLEM_REPORT_LOGS_FILE = "problem_report.txt" diff --git a/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt b/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt index 6445c51b56..190527ae73 100644 --- a/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt +++ b/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt @@ -40,6 +40,7 @@ data class Dimensions( val notificationBannerStartPadding: Dp = 16.dp, val notificationEndIconPadding: Dp = 4.dp, val notificationStatusIconSize: Dp = 10.dp, + val problemReportIconToTitlePadding: Dp = 60.dp, val progressIndicatorSize: Dp = 48.dp, val relayCircleSize: Dp = 16.dp, val relayRowPadding: Dp = 50.dp, |
