From eb5a89623b78d5f8896d7af2dcdc5d89692188cd Mon Sep 17 00:00:00 2001 From: Denozordec Date: Mon, 12 Oct 2026 10:31:32 +0700 Subject: [PATCH] android: server delete confirmation as in the Final 2026 mockup Co-Authored-By: Claude Opus 5.5 --- .../android/ui/compose/ProfilesScreen.kt | 28 +++++++- .../android/ui/compose/design/ShxKit.kt | 65 +++++++++++++++++++ .../app/src/main/res/values-ru/strings.xml | 4 ++ .../app/src/main/res/values/strings.xml | 4 ++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/ProfilesScreen.kt b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/ProfilesScreen.kt index c5a2b3d52..18fb0d7f5 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/ProfilesScreen.kt +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/ProfilesScreen.kt @@ -97,6 +97,7 @@ import kotlinx.coroutines.delay import org.strongswan.android.logic.connectivity.ConnectivityProbe import org.strongswan.android.ui.compose.design.ShxButton import org.strongswan.android.ui.compose.design.ShxButtonStyle +import org.strongswan.android.ui.compose.design.ShxDialog import org.strongswan.android.ui.compose.design.ShxIcons import org.strongswan.android.ui.compose.design.ShxPanel import org.strongswan.android.ui.compose.design.ShxRow @@ -200,6 +201,7 @@ private fun ProfilesList( val snackbarHostState = remember { SnackbarHostState() } val scope = rememberCoroutineScope() var menuFor by remember { mutableStateOf(null) } + var deleteFor by remember { mutableStateOf(null) } val activeUuid = state.activeProfile?.getUUID() val connected = state.vpnState == State.CONNECTED val profiles = state.profiles @@ -237,6 +239,30 @@ private fun ProfilesList( } } + deleteFor?.let { profile -> + val current = profile.getUUID() == activeUuid && state.vpnState != State.DISABLED + ShxDialog( + title = stringResource(R.string.server_delete_title, profile.name ?: profile.gateway), + paragraphs = listOfNotNull( + if (current) stringResource(R.string.server_delete_current) else null, + stringResource(R.string.server_delete_restore), + ), + confirm = stringResource(R.string.server_delete_confirm), + dismiss = stringResource(android.R.string.cancel), + onConfirm = { + deleteFor = null + if (current) + { + onDisconnect() + } + deleteWithUndo(profile) + }, + onDismiss = { deleteFor = null }, + icon = ShxIcons.Trash, + danger = true, + ) + } + Box(Modifier.fillMaxSize().background(c.background)) { Column(Modifier.fillMaxSize().statusBarsPadding().verticalScroll(rememberScrollState())) @@ -327,7 +353,7 @@ private fun ProfilesList( stringResource(R.string.delete_profile), { menuFor = null - deleteWithUndo(profile) + deleteFor = profile }, style = ShxButtonStyle.DANGER, modifier = Modifier.fillMaxWidth(), diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/design/ShxKit.kt b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/design/ShxKit.kt index 5b5e099f6..9655a05db 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/design/ShxKit.kt +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/compose/design/ShxKit.kt @@ -737,3 +737,68 @@ fun ShxToggleRow(title: String, checked: Boolean, onChange: (Boolean) -> Unit, s } } } + +/** + * Confirmation dialog of the mockup (F_ServerDelete): 28dp card, a 48dp round + * icon, 22/800 title, 14sp paragraphs, a text «Cancel» and a filled action. + */ +@Composable +fun ShxDialog( + title: String, + paragraphs: List, + confirm: String, + dismiss: String, + onConfirm: () -> Unit, + onDismiss: () -> Unit, + icon: ImageVector? = null, + danger: Boolean = false, +) +{ + val c = LocalShxColors.current + androidx.compose.ui.window.Dialog(onDismissRequest = onDismiss) + { + Column( + verticalArrangement = Arrangement.spacedBy(14.dp), + modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(28.dp)).background(c.background).padding(24.dp), + ) + { + if (icon != null) + { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.size(48.dp).clip(CircleShape).background(if (danger) c.errorContainer else c.accentContainer), + ) + { + Icon(icon, contentDescription = null, tint = if (danger) c.error else c.onAccentContainer, modifier = Modifier.size(24.dp)) + } + } + Text(title, style = ShxType.pageTitle, color = c.text) + paragraphs.forEach { + Text(it, style = ShxType.note.copy(fontSize = 14.sp, lineHeight = 21.sp, fontWeight = FontWeight.Normal), color = c.textSoft) + } + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.End), + modifier = Modifier.fillMaxWidth().padding(top = 4.dp), + ) + { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.height(44.dp).clip(RoundedCornerShape(22.dp)) + .clickable(role = Role.Button, onClick = onDismiss).padding(horizontal = 16.dp), + ) + { + Text(dismiss, style = ShxType.button.copy(fontWeight = FontWeight.Bold), color = c.accentText) + } + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.height(44.dp).clip(RoundedCornerShape(22.dp)) + .background(if (danger) c.error else c.accent) + .clickable(role = Role.Button, onClick = onConfirm).padding(horizontal = 20.dp), + ) + { + Text(confirm, style = ShxType.button, color = if (danger) c.background else Color.White) + } + } + } + } +} diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index 4b09ffd05..c88310742 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -1026,4 +1026,8 @@ Сервер не отвечает Ошибка входа Проблема с подключением + Удалить «%1$s»? + Это текущий сервер — VPN отключится. + Вернуть можно, снова добавив профиль по ссылке, файлу или QR. + Удалить diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index 63b3cfa71..d0abdb43a 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -1012,4 +1012,8 @@ Sign-in failed Connection problem SHX VPN + Delete «%1$s»? + This is the current server — the VPN will disconnect. + You can get it back by adding the profile again from a link, file or QR. + Delete