diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt index f4cd34a6..e9022106 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt @@ -123,17 +123,14 @@ object SettingsManager { } /** - * Get a routing ruleset by index. - * @param index The index of the ruleset. - * @return The RulesetItem. - */ - fun getRoutingRuleset(index: Int): RulesetItem? { - if (index < 0) return null + * Get a routing ruleset by id. + * @param id The id of the ruleset. + * @return The RulesetItem. + */ + fun getRoutingRuleset(index: String?): RulesetItem? { + if (index.isNullOrEmpty()) return null - val rulesetList = MmkvManager.decodeRoutingRulesets() - if (rulesetList.isNullOrEmpty()) return null - - return rulesetList[index] + return MmkvManager.decodeRoutingRulesets()?.firstOrNull { it.id == index } } /** @@ -142,33 +139,48 @@ object SettingsManager { * @param ruleset The RulesetItem to save. */ fun saveRoutingRuleset(index: Int, ruleset: RulesetItem?) { - if (ruleset == null) return + if (ruleset == null) return - var rulesetList = MmkvManager.decodeRoutingRulesets() - if (rulesetList.isNullOrEmpty()) { - rulesetList = mutableListOf() + var rulesetList = MmkvManager.decodeRoutingRulesets() + if (rulesetList.isNullOrEmpty()) { + rulesetList = mutableListOf() } - if (index < 0 || index >= rulesetList.count()) { - rulesetList.add(0, ruleset) - } else { - rulesetList[index] = ruleset - } - MmkvManager.encodeRoutingRulesets(rulesetList) + if (index < 0 || index >= rulesetList.count()) { + rulesetList.add(0, ruleset) + } else { + rulesetList[index] = ruleset + } + MmkvManager.encodeRoutingRulesets(rulesetList) } - /** - * Remove a routing ruleset by index. - * @param index The index of the ruleset. - */ - fun removeRoutingRuleset(index: Int) { - if (index < 0) return + fun saveRoutingRuleset(index: String?, ruleset: RulesetItem?) { + if (ruleset == null) return + if (ruleset.id.isBlank()) { + ruleset.id = java.util.UUID.randomUUID().toString() + } - val rulesetList = MmkvManager.decodeRoutingRulesets() - if (rulesetList.isNullOrEmpty()) return + val rulesetList = MmkvManager.decodeRoutingRulesets()?.toMutableList() ?: mutableListOf() + val targetId = if (index.isNullOrEmpty()) ruleset.id else index + val index = rulesetList.indexOfFirst { it.id == targetId } - rulesetList.removeAt(index) - MmkvManager.encodeRoutingRulesets(rulesetList) + if (index >= 0) { + rulesetList[index] = ruleset + } else { + rulesetList.add(0, ruleset) + } + MmkvManager.encodeRoutingRulesets(rulesetList) + } + + fun removeRoutingRuleset(index: String?) { + if (index.isNullOrEmpty()) return + + val rulesetList = MmkvManager.decodeRoutingRulesets() ?: return + val targetIndex = rulesetList.indexOfFirst { it.id == index } + if (targetIndex < 0) return + + rulesetList.removeAt(targetIndex) + MmkvManager.encodeRoutingRulesets(rulesetList) } /** diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingEditActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingEditActivity.kt index 9d428a4a..5b866a63 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingEditActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingEditActivity.kt @@ -57,7 +57,7 @@ import java.util.UUID private val ROUTING_NETWORK_OPTIONS = listOf("tcp", "udp", "tcp,udp") class RoutingEditActivity : BaseComponentActivity() { - private val position by lazy { intent.getIntExtra("position", -1) } + private val rulesetId by lazy { intent.getStringExtra("ruleset_id") } private var initial: RulesetItem? = null private lateinit var outboundSuggestions: List @@ -65,7 +65,11 @@ class RoutingEditActivity : BaseComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - initial = SettingsManager.getRoutingRuleset(position) + initial = rulesetId?.let { SettingsManager.getRoutingRuleset(it) } + if (initial == null) { + finish() + return + } val profileRemarks = SettingsManager.getProfileRemarks() outboundSuggestions = (BUILTIN_OUTBOUND_TAGS.toList() + profileRemarks).distinct() canUseProcess = SettingsManager.canUseProcessRouting() @@ -74,7 +78,7 @@ class RoutingEditActivity : BaseComponentActivity() { @Composable override fun ScreenContent() { RoutingEditScreen( - position = position, + rulesetId = rulesetId, initial = initial, outboundSuggestions = outboundSuggestions, canUseProcess = canUseProcess, @@ -89,19 +93,19 @@ class RoutingEditActivity : BaseComponentActivity() { toast(R.string.sub_setting_remarks) return false } - if (position < 0 && rulesetItem.id.isEmpty()) { + if (rulesetItem.id.isEmpty()) { rulesetItem.id = UUID.randomUUID().toString() } - SettingsManager.saveRoutingRuleset(position, rulesetItem) + SettingsManager.saveRoutingRuleset(rulesetId, rulesetItem) toastSuccess(R.string.toast_success) finish() return true } private fun deleteServer(): Boolean { - if (position >= 0) { + if (!rulesetId.isNullOrEmpty()) { lifecycleScope.launch(Dispatchers.IO) { - SettingsManager.removeRoutingRuleset(position) + SettingsManager.removeRoutingRuleset(rulesetId) withContext(Dispatchers.Main) { finish() } } } @@ -111,7 +115,7 @@ class RoutingEditActivity : BaseComponentActivity() { @Composable fun RoutingEditScreen( - position: Int, + rulesetId: String?, initial: RulesetItem?, outboundSuggestions: List, canUseProcess: Boolean, @@ -147,7 +151,7 @@ fun RoutingEditScreen( } fun buildRuleset(): RulesetItem { - val rulesetItem = SettingsManager.getRoutingRuleset(position) ?: RulesetItem() + val rulesetItem = SettingsManager.getRoutingRuleset(rulesetId) ?: RulesetItem() rulesetItem.apply { this.remarks = remarks this.locked = locked @@ -185,7 +189,7 @@ fun RoutingEditScreen( title = stringResource(R.string.routing_settings_rule_title), onBackClick = onBackClick, actions = { - if (position >= 0) { + if (initial != null) { IconButton(onClick = { showDeleteConfirm = true }) { Icon( painterResource(R.drawable.ic_delete_24dp), diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingSettingActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingSettingActivity.kt index 0be63809..78bb9543 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingSettingActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/routing/RoutingSettingActivity.kt @@ -101,8 +101,8 @@ class RoutingSettingActivity : HelperBaseComponentActivity() { domainStrategyState = domainStrategyState, onBackClick = { finish() }, onAddRule = { startActivity(Intent(this, RoutingEditActivity::class.java)) }, - onEditRule = { position -> - startActivity(Intent(this, RoutingEditActivity::class.java).putExtra("position", position)) + onEditRule = { rulesetId -> + startActivity(Intent(this, RoutingEditActivity::class.java).putExtra("ruleset_id", rulesetId)) }, onDomainStrategySelected = { value -> MmkvManager.encodeSettings(AppConfig.PREF_ROUTING_DOMAIN_STRATEGY, value) @@ -194,7 +194,7 @@ fun RoutingSettingScreen( domainStrategyState: MutableStateFlow, onBackClick: () -> Unit, onAddRule: () -> Unit, - onEditRule: (Int) -> Unit, + onEditRule: (String) -> Unit, onDomainStrategySelected: (String) -> Unit, onImportPredefined: (RoutingType) -> Unit, onImportClipboard: () -> Unit, @@ -291,7 +291,7 @@ fun RoutingSettingScreen( ) { RoutingRulesetItem( ruleset = ruleset, - onEdit = { onEditRule(index) }, + onEdit = { onEditRule(ruleset.id) }, onEnabledChange = { checked -> val updated = ruleset.copy(enabled = checked) viewModel.update(index, updated)