Use typed server menu actions and explicit delete dialogs (#5975)
* Use typed server actions and explicit dialogs * Add ConfirmDialog --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
1 parent
aacc8e091f
commit
e549000e5a
25 files changed
+343
-248
No files matched your search
@@ -10,11 +10,13 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.text.selection.TextSelectionColors
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||
@@ -22,37 +24,87 @@ import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.R
|
||||
|
||||
@Composable
|
||||
fun ConfirmDialog(
|
||||
title: String? = null,
|
||||
message: String,
|
||||
confirmText: String,
|
||||
dismissText: String,
|
||||
confirmText: String = stringResource(android.R.string.ok),
|
||||
dismissText: String? = stringResource(android.R.string.cancel),
|
||||
confirmIcon: @Composable (() -> Unit)? = null,
|
||||
onConfirm: () -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val confirmFocusRequester = remember { FocusRequester() }
|
||||
val dismissFocusRequester = remember { FocusRequester() }
|
||||
|
||||
LaunchedEffect(dismissText) {
|
||||
if (dismissText != null) dismissFocusRequester.requestFocus()
|
||||
else confirmFocusRequester.requestFocus()
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = title?.let { { Text(it) } },
|
||||
text = { Text(message, style = MaterialTheme.typography.bodyMedium) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { onConfirm(); onDismiss() }) { Text(confirmText) }
|
||||
TextButton(
|
||||
onClick = { onConfirm(); onDismiss() },
|
||||
modifier = Modifier.focusRequester(confirmFocusRequester)
|
||||
) {
|
||||
confirmIcon?.invoke()
|
||||
if (confirmIcon != null) Spacer(Modifier.width(8.dp))
|
||||
Text(confirmText)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) { Text(dismissText) }
|
||||
dismissButton = dismissText?.let { text ->
|
||||
{
|
||||
TextButton(
|
||||
onClick = onDismiss,
|
||||
modifier = Modifier.focusRequester(dismissFocusRequester)
|
||||
) {
|
||||
Text(text)
|
||||
}
|
||||
}
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DeleteConfirmDialog(
|
||||
message: String,
|
||||
onConfirm: () -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
ConfirmDialog(
|
||||
message = message,
|
||||
confirmText = stringResource(R.string.action_delete),
|
||||
confirmIcon = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_delete_24dp),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
},
|
||||
onConfirm = onConfirm,
|
||||
onDismiss = onDismiss
|
||||
)
|
||||
}
|
||||
|
||||
data class InputField(
|
||||
val label: String,
|
||||
val value: String,
|
||||
@@ -121,14 +173,14 @@ fun QRCodeDialog(
|
||||
text = {
|
||||
Image(
|
||||
bitmap = bitmap.asImageBitmap(),
|
||||
contentDescription = "QR Code",
|
||||
contentDescription = stringResource(R.string.title_qr_code),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f)
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) { Text(stringResource(android.R.string.ok)) }
|
||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.action_close)) }
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
)
|
||||
|
||||
@@ -118,8 +118,6 @@ class MainActivity : HelperBaseComponentActivity() {
|
||||
}
|
||||
},
|
||||
onNavigate = { route -> navigateTo(route) },
|
||||
shareMethodEntries = resources.getStringArray(R.array.share_method).toList(),
|
||||
shareMethodMoreEntries = resources.getStringArray(R.array.share_method_more).toList()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.v2ray.ang.ui.main
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
|
||||
@Composable
|
||||
fun MainDialogs(
|
||||
@@ -21,38 +21,30 @@ fun MainDialogs(
|
||||
onConfirmRemove: (String) -> Unit,
|
||||
) {
|
||||
if (showDelAllConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_visible_profiles),
|
||||
onConfirm = onConfirmDelAll,
|
||||
onDismiss = onDismissDelAll
|
||||
)
|
||||
}
|
||||
if (showDelDuplicateConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_duplicate_profiles),
|
||||
onConfirm = onConfirmDelDuplicate,
|
||||
onDismiss = onDismissDelDuplicate
|
||||
)
|
||||
}
|
||||
if (showDelInvalidConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_invalid_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_invalid_profiles),
|
||||
onConfirm = onConfirmDelInvalid,
|
||||
onDismiss = onDismissDelInvalid
|
||||
)
|
||||
}
|
||||
if (showRemoveConfirm != null) {
|
||||
val guid = showRemoveConfirm
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_profile),
|
||||
onConfirm = { onConfirmRemove(guid) },
|
||||
onDismiss = onDismissRemove
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.ui.main
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -10,6 +11,25 @@ import com.v2ray.ang.dto.entities.ProfileItem
|
||||
import com.v2ray.ang.enums.EConfigType
|
||||
import com.v2ray.ang.extension.isComplexType
|
||||
|
||||
internal enum class ServerMenuAction(
|
||||
@StringRes val labelRes: Int,
|
||||
val isShareAction: Boolean,
|
||||
val supportsComplexProfiles: Boolean,
|
||||
) {
|
||||
ShareQRCode(R.string.share_method_qrcode, isShareAction = true, supportsComplexProfiles = false),
|
||||
ShareClipboard(R.string.share_method_clipboard, isShareAction = true, supportsComplexProfiles = false),
|
||||
ShareFullContent(R.string.share_method_full_content, isShareAction = true, supportsComplexProfiles = true),
|
||||
Edit(R.string.action_edit, isShareAction = false, supportsComplexProfiles = true),
|
||||
Delete(R.string.action_delete, isShareAction = false, supportsComplexProfiles = true),
|
||||
}
|
||||
|
||||
internal fun serverMenuActions(
|
||||
isComplexProfile: Boolean,
|
||||
includeManagementActions: Boolean,
|
||||
): List<ServerMenuAction> = ServerMenuAction.entries.filter { action ->
|
||||
(includeManagementActions || action.isShareAction) && (!isComplexProfile || action.supportsComplexProfiles)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ImportMenuContent(
|
||||
onAction: (MainAction) -> Unit
|
||||
@@ -122,29 +142,24 @@ fun ShareMethodDialog(
|
||||
guid: String,
|
||||
profile: ProfileItem,
|
||||
more: Boolean,
|
||||
shareMethodEntries: List<String>,
|
||||
shareMethodMoreEntries: List<String>,
|
||||
onDismiss: () -> Unit,
|
||||
onAction: (MainAction) -> Unit
|
||||
onAction: (MainAction) -> Unit,
|
||||
onRemove: (String) -> Unit,
|
||||
) {
|
||||
val isCustom = profile.configType.isComplexType()
|
||||
val (shareOptions, skip) = if (more) {
|
||||
val options = if (isCustom) shareMethodMoreEntries.takeLast(3) else shareMethodMoreEntries
|
||||
options to if (isCustom) 2 else 0
|
||||
} else {
|
||||
val options = if (isCustom) shareMethodEntries.takeLast(1) else shareMethodEntries
|
||||
options to if (isCustom) 2 else 0
|
||||
}
|
||||
val menuActions = serverMenuActions(
|
||||
isComplexProfile = profile.configType.isComplexType(),
|
||||
includeManagementActions = more,
|
||||
)
|
||||
SelectListDialog(
|
||||
options = shareOptions,
|
||||
options = menuActions.map { stringResource(it.labelRes) },
|
||||
onSelected = { index, _ ->
|
||||
onDismiss()
|
||||
when (index + skip) {
|
||||
0 -> onAction(MainAction.ShareQRCode(guid))
|
||||
1 -> onAction(MainAction.ShareClipboard(guid))
|
||||
2 -> onAction(MainAction.ShareFullContent(guid))
|
||||
3 -> onAction(MainAction.EditServer(guid, profile))
|
||||
4 -> onAction(MainAction.RemoveServer(guid))
|
||||
when (menuActions[index]) {
|
||||
ServerMenuAction.ShareQRCode -> onAction(MainAction.ShareQRCode(guid))
|
||||
ServerMenuAction.ShareClipboard -> onAction(MainAction.ShareClipboard(guid))
|
||||
ServerMenuAction.ShareFullContent -> onAction(MainAction.ShareFullContent(guid))
|
||||
ServerMenuAction.Edit -> onAction(MainAction.EditServer(guid, profile))
|
||||
ServerMenuAction.Delete -> onRemove(guid)
|
||||
}
|
||||
},
|
||||
onDismiss = onDismiss
|
||||
|
||||
@@ -41,8 +41,6 @@ fun MainScreen(
|
||||
mainViewModel: MainViewModel,
|
||||
onAction: (MainAction) -> Unit,
|
||||
onNavigate: (String) -> Unit,
|
||||
shareMethodEntries: List<String>,
|
||||
shareMethodMoreEntries: List<String>
|
||||
) {
|
||||
val uiState by mainViewModel.uiState.collectAsStateWithLifecycle()
|
||||
val groups = uiState.groups
|
||||
@@ -65,6 +63,9 @@ fun MainScreen(
|
||||
var showRemoveConfirm by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
var shareTarget by remember { mutableStateOf<Triple<String, ProfileItem, Boolean>?>(null) }
|
||||
val removeServer: (String) -> Unit = { guid ->
|
||||
if (confirmRemove) showRemoveConfirm = guid else onAction(MainAction.RemoveServer(guid))
|
||||
}
|
||||
|
||||
val pagerState = rememberPagerState(
|
||||
initialPage = 0,
|
||||
@@ -177,10 +178,9 @@ fun MainScreen(
|
||||
guid = guid,
|
||||
profile = profile,
|
||||
more = more,
|
||||
shareMethodEntries = shareMethodEntries,
|
||||
shareMethodMoreEntries = shareMethodMoreEntries,
|
||||
onDismiss = { shareTarget = null },
|
||||
onAction = onAction
|
||||
onAction = onAction,
|
||||
onRemove = removeServer,
|
||||
)
|
||||
}
|
||||
if (shareQRCodeBitmap != null) {
|
||||
@@ -282,10 +282,7 @@ fun MainScreen(
|
||||
onMoreServer = { guid, profile ->
|
||||
shareTarget = Triple(guid, profile, true)
|
||||
},
|
||||
onRemoveServer = { guid ->
|
||||
if (confirmRemove) showRemoveConfirm = guid
|
||||
else onAction(MainAction.RemoveServer(guid))
|
||||
},
|
||||
onRemoveServer = removeServer,
|
||||
contentPadding = PaddingValues(
|
||||
start = 0.dp,
|
||||
top = 0.dp,
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.v2ray.ang.AppConfig.BUILTIN_OUTBOUND_TAGS
|
||||
import com.v2ray.ang.AppConfig.TAG_PROXY
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
@@ -293,10 +293,8 @@ fun RoutingEditScreen(
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_routing_rule),
|
||||
onConfirm = onDelete,
|
||||
onDismiss = { showDeleteConfirm = false }
|
||||
)
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.v2ray.ang.AppConfig.REALITY
|
||||
import com.v2ray.ang.AppConfig.TLS
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
@@ -474,10 +474,8 @@ abstract class BaseServerActivity : BaseComponentActivity() {
|
||||
)
|
||||
}
|
||||
if (showDeleteDialog) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_profile),
|
||||
onConfirm = {
|
||||
showDeleteDialog = false
|
||||
deleteServer(editGuid)
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.v2ray.ang.AppConfig.WIREGUARD_LOCAL_ADDRESS_V4
|
||||
import com.v2ray.ang.AppConfig.WIREGUARD_LOCAL_MTU
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
@@ -515,10 +515,8 @@ fun ServerScreen(
|
||||
}
|
||||
}
|
||||
if (showDeleteDialog) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_profile),
|
||||
onConfirm = { showDeleteDialog = false; onDelete() },
|
||||
onDismiss = { showDeleteDialog = false }
|
||||
)
|
||||
|
||||
@@ -56,7 +56,7 @@ import androidx.compose.ui.unit.sp
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.horizontalScrollbar
|
||||
import com.v2ray.ang.compose.verticalScrollbar
|
||||
@@ -477,10 +477,8 @@ fun ServerCustomConfigScreen(
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_profile),
|
||||
onConfirm = {
|
||||
showDeleteConfirm = false
|
||||
onDelete()
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.v2ray.ang.AppConfig.BUILTIN_OUTBOUND_TAGS
|
||||
import com.v2ray.ang.AppConfig.TAG_PROXY
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
@@ -302,10 +302,8 @@ fun ServerGroupScreen(
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_policy_group),
|
||||
onConfirm = onDelete,
|
||||
onDismiss = { showDeleteConfirm = false }
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.reorderableDragHandle
|
||||
@@ -198,10 +198,9 @@ fun ProxyChainScreen(
|
||||
onDelete: () -> Unit
|
||||
) {
|
||||
var remarks by rememberSaveable { mutableStateOf(initialRemarks) }
|
||||
var members by rememberSaveable { mutableStateOf(initialMembers.toList()) }
|
||||
// Member remarks may be blank or duplicated, so they cannot serve as stable Compose keys.
|
||||
var memberKeys by rememberSaveable { mutableStateOf(List(initialMembers.size) { UUID.randomUUID().toString() }) }
|
||||
var showDeleteConfirm by remember { mutableStateOf(false) }
|
||||
var members by rememberSaveable { mutableStateOf(initialMembers.toMutableList()) }
|
||||
var showProfileDeleteConfirm by remember { mutableStateOf(false) }
|
||||
var memberToDeleteIndex by rememberSaveable { mutableStateOf<Int?>(null) }
|
||||
val showDelete = editGuid.isNotEmpty() && !isRunning
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
@@ -225,7 +224,7 @@ fun ProxyChainScreen(
|
||||
onBackClick = onBackClick,
|
||||
actions = {
|
||||
if (showDelete) {
|
||||
IconButton(onClick = { showDeleteConfirm = true }) {
|
||||
IconButton(onClick = { showProfileDeleteConfirm = true }) {
|
||||
Icon(painterResource(R.drawable.ic_delete_24dp), contentDescription = stringResource(R.string.menu_item_del_config))
|
||||
}
|
||||
}
|
||||
@@ -309,8 +308,8 @@ fun ProxyChainScreen(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
IconButton(onClick = {
|
||||
members = members.toMutableList().also { it.removeAt(index) }
|
||||
memberKeys = memberKeys.toMutableList().also { it.removeAt(index) }
|
||||
if (member.isBlank()) members = members.toMutableList().also { it.removeAt(index) }
|
||||
else memberToDeleteIndex = index
|
||||
}) {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_delete_24dp),
|
||||
@@ -324,13 +323,21 @@ fun ProxyChainScreen(
|
||||
}
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
onConfirm = { showDeleteConfirm = false; onDelete() },
|
||||
onDismiss = { showDeleteConfirm = false }
|
||||
if (showProfileDeleteConfirm) {
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_profile),
|
||||
onConfirm = { showProfileDeleteConfirm = false; onDelete() },
|
||||
onDismiss = { showProfileDeleteConfirm = false }
|
||||
)
|
||||
}
|
||||
memberToDeleteIndex?.let { index ->
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_proxy_chain_member),
|
||||
onConfirm = {
|
||||
members = members.toMutableList().also { it.removeAt(index) }
|
||||
memberToDeleteIndex = null
|
||||
},
|
||||
onDismiss = { memberToDeleteIndex = null }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormDropdownField
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
@@ -241,10 +241,8 @@ fun SubEditScreen(
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_subscription_group),
|
||||
onConfirm = onDelete,
|
||||
onDismiss = { showDeleteConfirm = false }
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.ItemDivider
|
||||
import com.v2ray.ang.compose.QRCodeDialog
|
||||
import com.v2ray.ang.compose.ReorderableListItem
|
||||
@@ -274,10 +274,8 @@ fun SubSettingScreen(
|
||||
}
|
||||
|
||||
if (removeTarget != null) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_subscription_group),
|
||||
onConfirm = {
|
||||
onRemoveSub(removeTarget!!)
|
||||
removeTarget = null
|
||||
|
||||
@@ -46,7 +46,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.ItemDivider
|
||||
import com.v2ray.ang.compose.SettingsListItem
|
||||
import com.v2ray.ang.compose.verticalScrollbar
|
||||
@@ -344,10 +344,8 @@ fun UserAssetScreen(
|
||||
if (deleteTargetGuid != null) {
|
||||
val guid = deleteTargetGuid!!
|
||||
val assetName = assets.find { it.guid == guid }?.assetUrl?.remarks ?: ""
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm) + "\n$assetName",
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_asset_file, assetName),
|
||||
onConfirm = { onRemoveAsset(guid) },
|
||||
onDismiss = { deleteTargetGuid = null }
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.DeleteConfirmDialog
|
||||
import com.v2ray.ang.compose.FormTextField
|
||||
import com.v2ray.ang.dto.entities.AssetUrlItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
@@ -186,10 +186,8 @@ fun UserAssetUrlScreen(
|
||||
}
|
||||
|
||||
if (showDeleteConfirm) {
|
||||
ConfirmDialog(
|
||||
message = stringResource(R.string.del_config_comfirm),
|
||||
confirmText = stringResource(android.R.string.ok),
|
||||
dismissText = stringResource(android.R.string.cancel),
|
||||
DeleteConfirmDialog(
|
||||
message = stringResource(R.string.confirm_delete_asset_source),
|
||||
onConfirm = onDelete,
|
||||
onDismiss = { showDeleteConfirm = false }
|
||||
)
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">الكتابة يدويًا [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">الكتابة يدويًا [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">Type manually[Hysteria2]</string>
|
||||
<string name="del_config_comfirm">تأكيد الحذف؟</string>
|
||||
<string name="del_invalid_config_comfirm">Please test before deleting! Confirm delete ?</string>
|
||||
<string name="confirm_delete_visible_profiles">هل أنت متأكد من أنك تريد حذف جميع ملفات التعريف المعروضة حاليًا؟</string>
|
||||
<string name="confirm_delete_duplicate_profiles">هل أنت متأكد من أنك تريد حذف جميع ملفات التعريف المكررة المعروضة حاليًا؟</string>
|
||||
<string name="confirm_delete_invalid_profiles">يرجى اختبار ملفات التعريف أولًا. هل أنت متأكد من أنك تريد حذف جميع ملفات التعريف غير الصالحة المعروضة حاليًا؟</string>
|
||||
<string name="confirm_delete_profile">هل أنت متأكد من أنك تريد حذف ملف التعريف هذا؟</string>
|
||||
<string name="confirm_delete_policy_group">هل أنت متأكد من أنك تريد حذف مجموعة السياسات هذه؟</string>
|
||||
<string name="confirm_delete_proxy_chain_member">هل أنت متأكد من أنك تريد حذف هذا العضو من سلسلة الوكلاء؟</string>
|
||||
<string name="confirm_delete_routing_rule">هل أنت متأكد من أنك تريد حذف قاعدة التوجيه هذه؟</string>
|
||||
<string name="confirm_delete_subscription_group">هل أنت متأكد من أنك تريد حذف مجموعة الاشتراك هذه؟</string>
|
||||
<string name="confirm_delete_asset_file">هل أنت متأكد من أنك تريد حذف ملف الأصول \"%1$s\"؟</string>
|
||||
<string name="confirm_delete_asset_source">هل أنت متأكد من أنك تريد حذف مصدر الأصول هذا؟</string>
|
||||
<string name="server_lab_remarks">ملاحظات</string>
|
||||
<string name="server_lab_address">العنوان</string>
|
||||
<string name="server_lab_port">المنفذ</string>
|
||||
@@ -408,19 +416,12 @@
|
||||
<string name="title_webdav_pass">Password</string>
|
||||
<string name="title_webdav_remote_path">Remote directory (optional)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>رمز استجابة سريعة (QRcode)</item>
|
||||
<item>تصدير إلى الحافظة</item>
|
||||
<item>تصدير التكوين الكامل إلى الحافظة</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">رمز استجابة سريعة (QRcode)</string>
|
||||
<string name="share_method_clipboard">تصدير إلى الحافظة</string>
|
||||
<string name="share_method_full_content">تصدير التكوين الكامل إلى الحافظة</string>
|
||||
<string name="action_edit">تعديل</string>
|
||||
<string name="action_delete">حذف</string>
|
||||
<string name="action_close">إغلاق</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>رمز استجابة سريعة (QRcode)</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">ম্যানুয়ালি টাইপ করুন [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">ম্যানুয়ালি টাইপ করুন [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">Type manually[Hysteria2]</string>
|
||||
<string name="del_config_comfirm">মুছে ফেলুন নিশ্চিত করুন?</string>
|
||||
<string name="del_invalid_config_comfirm">Please test before deleting! Confirm delete ?</string>
|
||||
<string name="confirm_delete_visible_profiles">আপনি কি বর্তমানে প্রদর্শিত সব প্রোফাইল মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">আপনি কি বর্তমানে প্রদর্শিত সব সদৃশ প্রোফাইল মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_invalid_profiles">প্রথমে প্রোফাইলগুলো পরীক্ষা করুন। আপনি কি বর্তমানে প্রদর্শিত সব অবৈধ প্রোফাইল মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_profile">আপনি কি এই প্রোফাইলটি মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_policy_group">আপনি কি এই পলিসি গ্রুপটি মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">আপনি কি এই প্রক্সি চেইন সদস্যটিকে মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_routing_rule">আপনি কি এই রাউটিং নিয়মটি মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_subscription_group">আপনি কি এই সাবস্ক্রিপশন গ্রুপটি মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_asset_file">আপনি কি \"%1$s\" অ্যাসেট ফাইলটি মুছে ফেলতে চান?</string>
|
||||
<string name="confirm_delete_asset_source">আপনি কি এই অ্যাসেট উৎসটি মুছে ফেলতে চান?</string>
|
||||
<string name="server_lab_remarks">মন্তব্য</string>
|
||||
<string name="server_lab_address">ঠিকানা</string>
|
||||
<string name="server_lab_port">পোর্ট</string>
|
||||
@@ -407,19 +415,12 @@
|
||||
<string name="title_webdav_pass">Password</string>
|
||||
<string name="title_webdav_remote_path">Remote directory (optional)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QR কোড</item>
|
||||
<item>ক্লিপবোর্ডে রপ্তানি করুন</item>
|
||||
<item>পূর্ণ কনফিগারেশন ক্লিপবোর্ডে রপ্তানি করুন</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">QR কোড</string>
|
||||
<string name="share_method_clipboard">ক্লিপবোর্ডে রপ্তানি করুন</string>
|
||||
<string name="share_method_full_content">পূর্ণ কনফিগারেশন ক্লিপবোর্ডে রপ্তানি করুন</string>
|
||||
<string name="action_edit">সম্পাদনা</string>
|
||||
<string name="action_delete">মুছুন</string>
|
||||
<string name="action_close">বন্ধ করুন</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QR কোড</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">ٱووردن [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">ٱووردن [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">ٱووردن [Hysteria2]</string>
|
||||
<string name="del_config_comfirm">پاک بۊ؟</string>
|
||||
<string name="del_invalid_config_comfirm">پؽش ز پاک کردن، پینگ بگرین! الن اخۊین پاک کۊنین؟</string>
|
||||
<string name="confirm_delete_visible_profiles">آیا مطمئن هستید که میخواهید همه پروفایلهای نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_duplicate_profiles">آیا مطمئن هستید که میخواهید همه پروفایلهای تکراری نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_invalid_profiles">لطفاً ابتدا پروفایلها را آزمایش کنید. آیا مطمئن هستید که میخواهید همه پروفایلهای نامعتبر نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_profile">آیا مطمئن هستید که میخواهید این پروفایل را حذف کنید؟</string>
|
||||
<string name="confirm_delete_policy_group">آیا مطمئن هستید که میخواهید این گروه سیاست را حذف کنید؟</string>
|
||||
<string name="confirm_delete_proxy_chain_member">آیا مطمئن هستید که میخواهید این عضو زنجیره پراکسی را حذف کنید؟</string>
|
||||
<string name="confirm_delete_routing_rule">آیا مطمئن هستید که میخواهید این قانون مسیریابی را حذف کنید؟</string>
|
||||
<string name="confirm_delete_subscription_group">آیا مطمئن هستید که میخواهید این گروه اشتراک را حذف کنید؟</string>
|
||||
<string name="confirm_delete_asset_file">آیا مطمئن هستید که میخواهید فایل دارایی \"%1$s\" را حذف کنید؟</string>
|
||||
<string name="confirm_delete_asset_source">آیا مطمئن هستید که میخواهید این منبع دارایی را حذف کنید؟</string>
|
||||
<string name="server_lab_remarks">نیشتنا</string>
|
||||
<string name="server_lab_address">نشۊوی</string>
|
||||
<string name="server_lab_port">پورت</string>
|
||||
@@ -413,19 +421,12 @@
|
||||
<string name="title_webdav_pass">رزم</string>
|
||||
<string name="title_webdav_remote_path">دایرکتوری ره دیر (اختیاری)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
<item>و در کشیڌن من کلیپ بورد</item>
|
||||
<item>و در کشیڌن پوی کانفیگ من کلیپ بورد</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>و در کشیڌن من کلیپ بورد</item>
|
||||
<item>و در کشیڌن پوی کانفیگ من کلیپ بورد</item>
|
||||
<item>آلشت</item>
|
||||
<item>پاک کردن</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">QRcode</string>
|
||||
<string name="share_method_clipboard">و در کشیڌن من کلیپ بورد</string>
|
||||
<string name="share_method_full_content">و در کشیڌن پوی کانفیگ من کلیپ بورد</string>
|
||||
<string name="action_edit">آلشتکاری</string>
|
||||
<string name="action_delete">پاک کردن</string>
|
||||
<string name="action_close">بستن</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">افزودن [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">افزودن [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">افزودن [Hysteria2]</string>
|
||||
<string name="del_config_comfirm">از حذف این کانفیگ اطمینان دارید؟</string>
|
||||
<string name="del_invalid_config_comfirm">لطفاً قبل از حذف، پینگ بگیرید! آیا از حذف اطمینان دارید؟</string>
|
||||
<string name="confirm_delete_visible_profiles">آیا مطمئن هستید که میخواهید همه پروفایلهای نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_duplicate_profiles">آیا مطمئن هستید که میخواهید همه پروفایلهای تکراری نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_invalid_profiles">لطفاً ابتدا پروفایلها را آزمایش کنید. آیا مطمئن هستید که میخواهید همه پروفایلهای نامعتبر نمایشدادهشده را حذف کنید؟</string>
|
||||
<string name="confirm_delete_profile">آیا مطمئن هستید که میخواهید این پروفایل را حذف کنید؟</string>
|
||||
<string name="confirm_delete_policy_group">آیا مطمئن هستید که میخواهید این گروه سیاست را حذف کنید؟</string>
|
||||
<string name="confirm_delete_proxy_chain_member">آیا مطمئن هستید که میخواهید این عضو زنجیره پراکسی را حذف کنید؟</string>
|
||||
<string name="confirm_delete_routing_rule">آیا مطمئن هستید که میخواهید این قانون مسیریابی را حذف کنید؟</string>
|
||||
<string name="confirm_delete_subscription_group">آیا مطمئن هستید که میخواهید این گروه اشتراک را حذف کنید؟</string>
|
||||
<string name="confirm_delete_asset_file">آیا مطمئن هستید که میخواهید فایل دارایی \"%1$s\" را حذف کنید؟</string>
|
||||
<string name="confirm_delete_asset_source">آیا مطمئن هستید که میخواهید این منبع دارایی را حذف کنید؟</string>
|
||||
<string name="server_lab_remarks">ملاحظات</string>
|
||||
<string name="server_lab_address">نشانی</string>
|
||||
<string name="server_lab_port">پورت</string>
|
||||
@@ -404,19 +412,12 @@
|
||||
<string name="title_webdav_pass">پسورد</string>
|
||||
<string name="title_webdav_remote_path">دایرکتوری راه دور (اختیاری)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
<item>خروجی گرفتن در کلیپ بورد</item>
|
||||
<item>خروجی گرفتن کانفیگ کامل در کلیپ بورد</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>صادر کردن به کلیپ بورد</item>
|
||||
<item>صادر کردن پیکربندی کامل به کلیپ بورد</item>
|
||||
<item>ویرایش کردن</item>
|
||||
<item>حذف کردن</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">QRcode</string>
|
||||
<string name="share_method_clipboard">خروجی گرفتن در کلیپ بورد</string>
|
||||
<string name="share_method_full_content">خروجی گرفتن کانفیگ کامل در کلیپ بورد</string>
|
||||
<string name="action_edit">ویرایش</string>
|
||||
<string name="action_delete">حذف</string>
|
||||
<string name="action_close">بستن</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">Добавить Trojan</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">Добавить WireGuard</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">Добавить Hysteria2</string>
|
||||
<string name="del_config_comfirm">Подтверждаете удаление?</string>
|
||||
<string name="del_invalid_config_comfirm">Выполните проверку перед удалением! Подтверждаете удаление?</string>
|
||||
<string name="confirm_delete_visible_profiles">Вы уверены, что хотите удалить все отображаемые профили?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">Вы уверены, что хотите удалить все отображаемые дубликаты профилей?</string>
|
||||
<string name="confirm_delete_invalid_profiles">Сначала проверьте профили. Вы уверены, что хотите удалить все отображаемые недействительные профили?</string>
|
||||
<string name="confirm_delete_profile">Вы уверены, что хотите удалить этот профиль?</string>
|
||||
<string name="confirm_delete_policy_group">Вы уверены, что хотите удалить эту группу политик?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">Вы уверены, что хотите удалить этот элемент цепочки прокси?</string>
|
||||
<string name="confirm_delete_routing_rule">Вы уверены, что хотите удалить это правило маршрутизации?</string>
|
||||
<string name="confirm_delete_subscription_group">Вы уверены, что хотите удалить эту группу подписки?</string>
|
||||
<string name="confirm_delete_asset_file">Вы уверены, что хотите удалить файл ресурсов \"%1$s\"?</string>
|
||||
<string name="confirm_delete_asset_source">Вы уверены, что хотите удалить этот источник ресурсов?</string>
|
||||
<string name="server_lab_remarks">Название</string>
|
||||
<string name="server_lab_address">Адрес</string>
|
||||
<string name="server_lab_port">Порт</string>
|
||||
@@ -420,19 +428,12 @@
|
||||
<string name="title_webdav_pass">Пароль</string>
|
||||
<string name="title_webdav_remote_path">Удалённый путь (необязательно)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QR-код</item>
|
||||
<item>Экспорт в буфер обмена</item>
|
||||
<item>Экспорт конфигурации в буфер обмена</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QR-код</item>
|
||||
<item>Экспорт в буфер обмена</item>
|
||||
<item>Экспорт конфигурации в буфер обмена</item>
|
||||
<item>Изменить</item>
|
||||
<item>Удалить</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">QR-код</string>
|
||||
<string name="share_method_clipboard">Экспорт в буфер обмена</string>
|
||||
<string name="share_method_full_content">Экспорт конфигурации в буфер обмена</string>
|
||||
<string name="action_edit">Изменить</string>
|
||||
<string name="action_delete">Удалить</string>
|
||||
<string name="action_close">Закрыть</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QR-код</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">Nhập thủ công [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">Nhập thủ công [WireGuard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">Type manually[Hysteria2]</string>
|
||||
<string name="del_config_comfirm">Xác nhận xóa?</string>
|
||||
<string name="del_invalid_config_comfirm">Please test before deleting! Confirm delete ?</string>
|
||||
<string name="confirm_delete_visible_profiles">Bạn có chắc muốn xóa tất cả cấu hình đang hiển thị không?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">Bạn có chắc muốn xóa tất cả cấu hình trùng lặp đang hiển thị không?</string>
|
||||
<string name="confirm_delete_invalid_profiles">Vui lòng kiểm tra các cấu hình trước. Bạn có chắc muốn xóa tất cả cấu hình không hợp lệ đang hiển thị không?</string>
|
||||
<string name="confirm_delete_profile">Bạn có chắc muốn xóa cấu hình này không?</string>
|
||||
<string name="confirm_delete_policy_group">Bạn có chắc muốn xóa nhóm chính sách này không?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">Bạn có chắc muốn xóa thành viên này khỏi chuỗi proxy không?</string>
|
||||
<string name="confirm_delete_routing_rule">Bạn có chắc muốn xóa quy tắc định tuyến này không?</string>
|
||||
<string name="confirm_delete_subscription_group">Bạn có chắc muốn xóa nhóm đăng ký này không?</string>
|
||||
<string name="confirm_delete_asset_file">Bạn có chắc muốn xóa tệp tài nguyên \"%1$s\" không?</string>
|
||||
<string name="confirm_delete_asset_source">Bạn có chắc muốn xóa nguồn tài nguyên này không?</string>
|
||||
<string name="server_lab_remarks">Tên cấu hình</string>
|
||||
<string name="server_lab_address">Địa chỉ</string>
|
||||
<string name="server_lab_port">Cổng</string>
|
||||
@@ -409,19 +417,12 @@
|
||||
<string name="title_webdav_pass">Password</string>
|
||||
<string name="title_webdav_remote_path">Remote directory (optional)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>Xuất ra mã QR (Chụp màn hình để lưu)</item>
|
||||
<item>Sao chép vào Clipboard</item>
|
||||
<item>Sao chép thành cấu hình tùy chỉnh</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">Xuất ra mã QR (Chụp màn hình để lưu)</string>
|
||||
<string name="share_method_clipboard">Sao chép vào Clipboard</string>
|
||||
<string name="share_method_full_content">Sao chép thành cấu hình tùy chỉnh</string>
|
||||
<string name="action_edit">Chỉnh sửa</string>
|
||||
<string name="action_delete">Xoá</string>
|
||||
<string name="action_close">Đóng</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>Xuất gói ra mã QR (Chụp màn hình để lưu)</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">添加 [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">添加 [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">添加 [Hysteria2]</string>
|
||||
<string name="del_config_comfirm">确认删除?</string>
|
||||
<string name="del_invalid_config_comfirm">删除前请先测试!确认删除?</string>
|
||||
<string name="confirm_delete_visible_profiles">确定要删除当前显示的所有配置吗?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">确定要删除当前显示的所有重复配置吗?</string>
|
||||
<string name="confirm_delete_invalid_profiles">请先测试配置。确定要删除当前显示的所有无效配置吗?</string>
|
||||
<string name="confirm_delete_profile">确定要删除此配置吗?</string>
|
||||
<string name="confirm_delete_policy_group">确定要删除此策略组吗?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">确定要删除此代理链成员吗?</string>
|
||||
<string name="confirm_delete_routing_rule">确定要删除此路由规则吗?</string>
|
||||
<string name="confirm_delete_subscription_group">确定要删除此订阅组吗?</string>
|
||||
<string name="confirm_delete_asset_file">确定要删除资源文件“%1$s”吗?</string>
|
||||
<string name="confirm_delete_asset_source">确定要删除此资源来源吗?</string>
|
||||
<string name="server_lab_remarks">别名 (remarks)</string>
|
||||
<string name="server_lab_address">地址 (address)</string>
|
||||
<string name="server_lab_port">端口 (port)</string>
|
||||
@@ -423,19 +431,12 @@
|
||||
<string name="title_webdav_pass">密码</string>
|
||||
<string name="title_webdav_remote_path">远程文件夹名(可选)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>二维码</item>
|
||||
<item>导出至剪贴板</item>
|
||||
<item>导出完整配置至剪贴板</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>二维码</item>
|
||||
<item>导出至剪贴板</item>
|
||||
<item>导出完整配置至剪贴板</item>
|
||||
<item>编辑</item>
|
||||
<item>删除</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">二维码</string>
|
||||
<string name="share_method_clipboard">导出至剪贴板</string>
|
||||
<string name="share_method_full_content">导出完整配置至剪贴板</string>
|
||||
<string name="action_edit">编辑</string>
|
||||
<string name="action_delete">删除</string>
|
||||
<string name="action_close">关闭</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>二维码</item>
|
||||
|
||||
@@ -39,8 +39,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">新增 [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">新增 [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">新增 [Hysteria2]</string>
|
||||
<string name="del_config_comfirm">確定刪除?</string>
|
||||
<string name="del_invalid_config_comfirm">刪除前請先測試!確認刪除?</string>
|
||||
<string name="confirm_delete_visible_profiles">確定要刪除目前顯示的所有設定檔嗎?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">確定要刪除目前顯示的所有重複設定檔嗎?</string>
|
||||
<string name="confirm_delete_invalid_profiles">請先測試設定檔。確定要刪除目前顯示的所有無效設定檔嗎?</string>
|
||||
<string name="confirm_delete_profile">確定要刪除此設定檔嗎?</string>
|
||||
<string name="confirm_delete_policy_group">確定要刪除此策略組嗎?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">確定要刪除此代理鏈成員嗎?</string>
|
||||
<string name="confirm_delete_routing_rule">確定要刪除此路由規則嗎?</string>
|
||||
<string name="confirm_delete_subscription_group">確定要刪除此訂閱群組嗎?</string>
|
||||
<string name="confirm_delete_asset_file">確定要刪除資源檔案「%1$s」嗎?</string>
|
||||
<string name="confirm_delete_asset_source">確定要刪除此資源來源嗎?</string>
|
||||
<string name="server_lab_remarks">備註</string>
|
||||
<string name="server_lab_address">位址</string>
|
||||
<string name="server_lab_port">埠</string>
|
||||
@@ -421,19 +429,12 @@
|
||||
<string name="title_webdav_pass">密碼</string>
|
||||
<string name="title_webdav_remote_path">遠端目錄(可選)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>二維碼</item>
|
||||
<item>匯出至剪貼簿</item>
|
||||
<item>匯出完整設定至剪貼簿</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QR Code</item>
|
||||
<item>匯出至剪貼簿</item>
|
||||
<item>匯出完整設定至剪貼簿</item>
|
||||
<item>編輯</item>
|
||||
<item>刪除</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">二維碼</string>
|
||||
<string name="share_method_clipboard">匯出至剪貼簿</string>
|
||||
<string name="share_method_full_content">匯出完整設定至剪貼簿</string>
|
||||
<string name="action_edit">編輯</string>
|
||||
<string name="action_delete">刪除</string>
|
||||
<string name="action_close">關閉</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>二維碼</item>
|
||||
|
||||
@@ -40,8 +40,16 @@
|
||||
<string name="menu_item_import_config_manually_trojan">Add [Trojan]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">Add [Wireguard]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">Add [Hysteria2]</string>
|
||||
<string name="del_config_comfirm">Confirm delete ?</string>
|
||||
<string name="del_invalid_config_comfirm">Please test before deleting! Confirm delete ?</string>
|
||||
<string name="confirm_delete_visible_profiles">Are you sure you want to delete all profiles currently shown?</string>
|
||||
<string name="confirm_delete_duplicate_profiles">Are you sure you want to delete all duplicate profiles currently shown?</string>
|
||||
<string name="confirm_delete_invalid_profiles">Please test the profiles first. Are you sure you want to delete all invalid profiles currently shown?</string>
|
||||
<string name="confirm_delete_profile">Are you sure you want to delete this profile?</string>
|
||||
<string name="confirm_delete_policy_group">Are you sure you want to delete this policy group?</string>
|
||||
<string name="confirm_delete_proxy_chain_member">Are you sure you want to delete this chain member?</string>
|
||||
<string name="confirm_delete_routing_rule">Are you sure you want to delete this routing rule?</string>
|
||||
<string name="confirm_delete_subscription_group">Are you sure you want to delete this subscription group?</string>
|
||||
<string name="confirm_delete_asset_file">Are you sure you want to delete the asset file \"%1$s\"?</string>
|
||||
<string name="confirm_delete_asset_source">Are you sure you want to delete this asset source?</string>
|
||||
<string name="server_lab_remarks">remarks</string>
|
||||
<string name="server_lab_address">address</string>
|
||||
<string name="server_lab_port">port</string>
|
||||
@@ -429,19 +437,12 @@
|
||||
<string name="title_webdav_pass">Password</string>
|
||||
<string name="title_webdav_remote_path">Remote directory (optional)</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full config to clipboard</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full config to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
<string name="share_method_qrcode">QRcode</string>
|
||||
<string name="share_method_clipboard">Export to clipboard</string>
|
||||
<string name="share_method_full_content">Export full config to clipboard</string>
|
||||
<string name="action_edit">Edit</string>
|
||||
<string name="action_delete">Delete</string>
|
||||
<string name="action_close">Close</string>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.v2ray.ang.ui.main
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class MainImportMenuTest {
|
||||
|
||||
@Test
|
||||
fun regularShareMenuContainsOnlyShareActions() {
|
||||
val expected = listOf(
|
||||
ServerMenuAction.ShareQRCode,
|
||||
ServerMenuAction.ShareClipboard,
|
||||
ServerMenuAction.ShareFullContent,
|
||||
)
|
||||
assertEquals(expected, serverMenuActions(isComplexProfile = false, includeManagementActions = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun regularMoreMenuContainsEveryActionInDisplayOrder() {
|
||||
assertEquals(
|
||||
ServerMenuAction.entries,
|
||||
serverMenuActions(isComplexProfile = false, includeManagementActions = true),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun complexShareMenuContainsOnlyFullContent() {
|
||||
assertEquals(
|
||||
listOf(ServerMenuAction.ShareFullContent),
|
||||
serverMenuActions(isComplexProfile = true, includeManagementActions = false),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun complexMoreMenuRetainsManagementActions() {
|
||||
val expected = listOf(
|
||||
ServerMenuAction.ShareFullContent,
|
||||
ServerMenuAction.Edit,
|
||||
ServerMenuAction.Delete,
|
||||
)
|
||||
assertEquals(expected, serverMenuActions(isComplexProfile = true, includeManagementActions = true))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user