diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt index 55fc2e263..a5ea796c8 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt @@ -34,12 +34,14 @@ class AngApplication : MultiDexApplication() { MMKV.initialize(this) + // Ensure critical preference defaults are present in MMKV early + SettingsManager.ensureDefaultSettings() + SettingsManager.setNightMode() // Initialize WorkManager with the custom configuration WorkManager.initialize(this, workManagerConfiguration) - // Ensure critical preference defaults are present in MMKV early - SettingsManager.initApp(this) - SettingsManager.setNightMode() + SettingsManager.initRoutingRulesets(this) + SettingsManager.migrateHysteria2PinSHA256() es.dmoral.toasty.Toasty.Config.getInstance() .setGravity(android.view.Gravity.BOTTOM, 0, 300) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index 5413bef0a..598c3b85a 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -16,9 +16,6 @@ object AppConfig { /** Legacy configuration keys. */ const val ANG_CONFIG = "ang_config" - // Default subscription ID for ungrouped servers - const val DEFAULT_SUBSCRIPTION_ID = "__default_subscription__" - /** Preferences mapped to MMKV storage. */ const val PREF_SNIFFING_ENABLED = "pref_sniffing_enabled" const val PREF_ROUTE_ONLY_ENABLED = "pref_route_only_enabled" diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionItem.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionItem.kt index 485d2b974..8ab871c3c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionItem.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionItem.kt @@ -13,6 +13,5 @@ data class SubscriptionItem( var filter: String? = null, var allowInsecureUrl: Boolean = false, var userAgent: String? = null, - var serverList: MutableList = mutableListOf(), ) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt index e62d10047..ca3c4e1dd 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt @@ -1,7 +1,6 @@ package com.v2ray.ang.handler import com.tencent.mmkv.MMKV -import com.v2ray.ang.AppConfig.DEFAULT_SUBSCRIPTION_ID import com.v2ray.ang.AppConfig.PREF_IS_BOOTED import com.v2ray.ang.AppConfig.PREF_ROUTING_RULESET import com.v2ray.ang.dto.AssetUrlCache @@ -45,24 +44,6 @@ object MmkvManager { //region Server - /** - * Reads the legacy server list from KEY_ANG_CONFIGS for migration. - * This method is for migration purposes only. - * - * @return The JSON string of legacy server list, or null if not exists. - */ - fun readLegacyServerList(): String? { - return mainStorage.decodeString(KEY_ANG_CONFIGS) - } - -// /** -// * Removes the legacy KEY_ANG_CONFIGS after migration. -// * This method is for migration purposes only. -// */ -// fun removeLegacyServerListKey() { -// mainStorage.remove(KEY_ANG_CONFIGS) -// } - /** * Gets the selected server GUID. * @@ -82,62 +63,19 @@ object MmkvManager { } /** - * Encodes the server list for a given subscription. - * Saves to the subscription's serverList (including default subscription for ungrouped servers). + * Encodes the server list. * * @param serverList The list of server GUIDs. - * @param subscriptionId The subscription ID. */ - fun encodeServerList(serverList: MutableList, subscriptionId: String) { - val subId = getSubscriptionId(subscriptionId) - val subItem = decodeSubscription(subId) ?: return - - subItem.serverList = serverList - encodeSubscription(subId, subItem) - } - - // Legacy method for compatibility - // TODO: Remove after migration and update all callers - /* fun encodeServerList(serverList: MutableList) { mainStorage.encode(KEY_ANG_CONFIGS, JsonUtil.toJson(serverList)) } - */ /** - * Decodes the server list for a given subscription. - * If subscriptionId is empty, returns ungrouped servers. - * Otherwise, returns servers from the specified subscription's serverList. + * Decodes the server list. * - * @param subscriptionId The subscription ID. * @return The list of server GUIDs. */ - fun decodeServerList(subscriptionId: String): MutableList { - val subId = getSubscriptionId(subscriptionId) - - return decodeSubscription(subId)?.serverList ?: mutableListOf() - } - - /** - * Decodes all server list (merged from all subscriptions including default subscription). - * Use this when you need the complete server list. - * - * @return The list of all server GUIDs. - */ - fun decodeAllServerList(): MutableList { - val allServers = mutableListOf() - - // Add servers from all subscriptions (including default subscription) - decodeSubscriptions().forEach { sub -> - allServers.addAll(sub.subscription.serverList) - } - - return allServers - } - - // Legacy method for compatibility - reads all servers - // TODO: Remove after migration and update all callers - /* fun decodeServerList(): MutableList { val json = mainStorage.decodeString(KEY_ANG_CONFIGS) return if (json.isNullOrBlank()) { @@ -146,7 +84,6 @@ object MmkvManager { JsonUtil.fromJson(json, Array::class.java)?.toMutableList() ?: mutableListOf() } } - */ /** * Decodes the server configuration. @@ -186,21 +123,6 @@ object MmkvManager { fun encodeServerConfig(guid: String, config: ProfileItem): String { val key = guid.ifBlank { Utils.getUuid() } profileFullStorage.encode(key, JsonUtil.toJson(config)) - - // Use default subscription for servers without subscription - val subId = getSubscriptionId(config.subscriptionId) - val serverList = decodeServerList(subId) - - if (!serverList.contains(key)) { - serverList.add(0, key) - encodeServerList(serverList, subId) - if (getSelectServer().isNullOrBlank()) { - mainStorage.encode(KEY_SELECTED_SERVER, key) - } - } - - // Legacy code - keep for reference during migration - /* val serverList = decodeServerList() if (!serverList.contains(key)) { serverList.add(0, key) @@ -209,7 +131,6 @@ object MmkvManager { mainStorage.encode(KEY_SELECTED_SERVER, key) } } - */ // val profile = ProfileLiteItem( // configType = config.configType, // subscriptionId = config.subscriptionId, @@ -230,30 +151,12 @@ object MmkvManager { if (guid.isBlank()) { return } - - // Get config to determine which subscription to update - val config = decodeServerConfig(guid) - val subId = getSubscriptionId(config?.subscriptionId) - - // Remove from appropriate server list - val serverList = decodeServerList(subId) - serverList.remove(guid) - encodeServerList(serverList, subId) - - // Legacy code - keep for reference during migration - /* if (getSelectServer() == guid) { mainStorage.remove(KEY_SELECTED_SERVER) } val serverList = decodeServerList() serverList.remove(guid) encodeServerList(serverList) - */ - - // Clean up storage - if (getSelectServer() == guid) { - mainStorage.remove(KEY_SELECTED_SERVER) - } profileFullStorage.remove(guid) //profileStorage.remove(guid) serverAffStorage.remove(guid) @@ -264,28 +167,10 @@ object MmkvManager { * * @param subid The subscription ID. */ - fun removeServerViaSubid(subid: String?) { - val subId2 = getSubscriptionId(subid) - - // Get server list from subscription - val subItem = decodeSubscription(subId2) ?: return - val serverList = subItem.serverList - - // Remove all servers in the list - serverList.forEach { guid -> - if (getSelectServer() == guid) { - mainStorage.remove(KEY_SELECTED_SERVER) - } - profileFullStorage.remove(guid) - serverAffStorage.remove(guid) + fun removeServerViaSubid(subid: String) { + if (subid.isBlank()) { + return } - - // Clear subscription's serverList - subItem.serverList.clear() - encodeSubscription(subId2, subItem) - - // Legacy code - keep for reference during migration - /* profileFullStorage.allKeys()?.forEach { key -> decodeServerConfig(key)?.let { config -> if (config.subscriptionId == subid) { @@ -293,7 +178,6 @@ object MmkvManager { } } } - */ } /** @@ -349,22 +233,13 @@ object MmkvManager { */ fun removeAllServer(): Int { val count = profileFullStorage.allKeys()?.count() ?: 0 - - decodeSubscriptions().forEach { sub -> - sub.subscription.serverList.clear() - encodeSubscription(sub.guid, sub.subscription) - } - - // Clear all storage mainStorage.clearAll() profileFullStorage.clearAll() //profileStorage.clearAll() serverAffStorage.clearAll() - return count } - /** * Removes invalid server configurations. * @@ -417,10 +292,6 @@ object MmkvManager { //region Subscriptions - private fun getSubscriptionId(subscriptionId: String?):String { - return subscriptionId?.ifEmpty { DEFAULT_SUBSCRIPTION_ID } ?: DEFAULT_SUBSCRIPTION_ID - } - /** * Initializes the subscription list. */ @@ -460,11 +331,6 @@ object MmkvManager { * @param subid The subscription ID. */ fun removeSubscription(subid: String) { - // Protect default subscription from being deleted - if (subid == DEFAULT_SUBSCRIPTION_ID) { - return - } - subStorage.remove(subid) val subsList = decodeSubsList() subsList.remove(subid) 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 9d8141bd5..46fdb4123 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 @@ -7,24 +7,20 @@ import android.util.Log import androidx.appcompat.app.AppCompatDelegate import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig.ANG_PACKAGE -import com.v2ray.ang.AppConfig.DEFAULT_SUBSCRIPTION_ID import com.v2ray.ang.AppConfig.GEOIP_PRIVATE import com.v2ray.ang.AppConfig.GEOSITE_PRIVATE import com.v2ray.ang.AppConfig.TAG_DIRECT import com.v2ray.ang.AppConfig.VPN -import com.v2ray.ang.dto.ProfileItem -import com.v2ray.ang.dto.RulesetItem -import com.v2ray.ang.dto.SubscriptionItem -import com.v2ray.ang.dto.V2rayConfig import com.v2ray.ang.enums.EConfigType import com.v2ray.ang.enums.Language +import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.enums.RoutingType +import com.v2ray.ang.dto.RulesetItem +import com.v2ray.ang.dto.ServersCache +import com.v2ray.ang.dto.V2rayConfig import com.v2ray.ang.enums.VpnInterfaceAddressConfig -import com.v2ray.ang.handler.MmkvManager.decodeAllServerList import com.v2ray.ang.handler.MmkvManager.decodeServerConfig -import com.v2ray.ang.handler.MmkvManager.decodeSubsList -import com.v2ray.ang.handler.MmkvManager.decodeSubscription -import com.v2ray.ang.handler.MmkvManager.encodeSubscription +import com.v2ray.ang.handler.MmkvManager.decodeServerList import com.v2ray.ang.util.JsonUtil import com.v2ray.ang.util.Utils import java.io.File @@ -34,19 +30,11 @@ import java.util.Locale object SettingsManager { - fun initApp(context: Context) { - ensureDefaultSettings() - ensureDefaultSubscription() - initRoutingRulesets(context) - migrateServerListToSubscriptions() - migrateHysteria2PinSHA256() - } - /** * Initialize routing rulesets. * @param context The application context. */ - private fun initRoutingRulesets(context: Context) { + fun initRoutingRulesets(context: Context) { val exist = MmkvManager.decodeRoutingRulesets() if (exist.isNullOrEmpty()) { val rulesetList = getPresetRoutingRulesets(context) @@ -234,10 +222,14 @@ object SettingsManager { if (remarks.isNullOrEmpty()) { return null } - val serverList = decodeAllServerList() - return serverList - .mapNotNull { guid -> decodeServerConfig(guid) } - .firstOrNull { it.remarks == remarks } + val serverList = decodeServerList() + for (guid in serverList) { + val profile = decodeServerConfig(guid) + if (profile != null && profile.remarks == remarks) { + return profile + } + } + return null } /** @@ -408,7 +400,7 @@ object SettingsManager { /** * Ensure default settings are present in MMKV. */ - private fun ensureDefaultSettings() { + fun ensureDefaultSettings() { // Write defaults in the exact order requested by the user ensureDefaultValue(AppConfig.PREF_MODE, AppConfig.VPN) ensureDefaultValue(AppConfig.PREF_VPN_DNS, AppConfig.DNS_VPN) @@ -432,14 +424,14 @@ object SettingsManager { } } - private fun migrateHysteria2PinSHA256() { + fun migrateHysteria2PinSHA256() { // Check if migration has already been done val migrationKey = "hysteria2_pin_sha256_migrated" if (MmkvManager.decodeSettingsBool(migrationKey, false)) { return } - val serverList = decodeAllServerList() + val serverList = decodeServerList() for (guid in serverList) { val profile = decodeServerConfig(guid) ?: continue @@ -457,81 +449,4 @@ object SettingsManager { MmkvManager.encodeSettings(migrationKey, true) } - /** - * Migrates server list from legacy KEY_ANG_CONFIGS to subscription-based storage. - * This method should be called once during app initialization after the storage structure change. - * Servers are grouped by their subscriptionId into respective subscription's serverList. - * Servers without subscription are moved to the default subscription. - * After migration, KEY_ANG_CONFIGS is removed. - */ - private fun migrateServerListToSubscriptions() { - // Check if migration has already been done - val migrationKey = "server_list_to_subscriptions_migrated" - if (MmkvManager.decodeSettingsBool(migrationKey, false)) { - return - } - - // Ensure default subscription exists before migration - ensureDefaultSubscription() - - // Read existing server list from legacy KEY_ANG_CONFIGS - val oldJson = MmkvManager.readLegacyServerList() - if (oldJson.isNullOrBlank()) { - // No data to migrate, mark as done - MmkvManager.encodeSettings(migrationKey, true) - return - } - - val guids = JsonUtil.fromJson(oldJson, Array::class.java) ?: run { - MmkvManager.encodeSettings(migrationKey, true) - return - } - - val subscriptionServerMap = mutableMapOf>() - - // Group servers by subscription (use default subscription for empty subscriptionId) - guids.forEach { guid -> - val config = decodeServerConfig(guid) ?: return@forEach - val subId = config.subscriptionId.ifEmpty { DEFAULT_SUBSCRIPTION_ID } - - subscriptionServerMap.getOrPut(subId) { mutableListOf() }.add(guid) - } - - // Update each subscription's serverList (including default subscription) - subscriptionServerMap.forEach { (subId, serverGuids) -> - val subItem = decodeSubscription(subId) - if (subItem != null) { - subItem.serverList = serverGuids - encodeSubscription(subId, subItem) - } - } - - // Remove legacy KEY_ANG_CONFIGS data - // MmkvManager.removeLegacyServerListKey() - - // Mark migration as complete - MmkvManager.encodeSettings(migrationKey, true) - } - - /** - * Ensures the default subscription exists for ungrouped servers. - * This subscription is used internally to store servers without a subscription. - * Made public for migration in SettingsManager. - */ - private fun ensureDefaultSubscription() { - if (decodeSubscription(DEFAULT_SUBSCRIPTION_ID) == null) { - val defaultSub = SubscriptionItem( - remarks = "Default", - serverList = mutableListOf() - ) - encodeSubscription(DEFAULT_SUBSCRIPTION_ID, defaultSub) - - // Move top - val subsList = decodeSubsList() - if (subsList.count() > 1) { - swapSubscriptions(0, subsList.count() - 1) - } - } - } - } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index e2c7c7fbf..2f9b9a54c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -6,6 +6,8 @@ import android.util.Log import com.google.gson.JsonArray import com.v2ray.ang.AppConfig import com.v2ray.ang.dto.ConfigResult +import com.v2ray.ang.enums.EConfigType +import com.v2ray.ang.enums.NetworkType import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.dto.RulesetItem import com.v2ray.ang.dto.V2rayConfig @@ -13,8 +15,6 @@ import com.v2ray.ang.dto.V2rayConfig.OutboundBean import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean import com.v2ray.ang.dto.V2rayConfig.OutboundBean.StreamSettingsBean import com.v2ray.ang.dto.V2rayConfig.RoutingBean.RulesBean -import com.v2ray.ang.enums.EConfigType -import com.v2ray.ang.enums.NetworkType import com.v2ray.ang.extension.isNotNullEmpty import com.v2ray.ang.extension.nullIfBlank import com.v2ray.ang.fmt.HttpFmt @@ -139,7 +139,7 @@ object V2rayConfigManager { private fun getV2rayGroupConfig(context: Context, guid: String, config: ProfileItem): ConfigResult { val result = ConfigResult(false) - val serverList = MmkvManager.decodeAllServerList() + val serverList = MmkvManager.decodeServerList() val configList = serverList .mapNotNull { id -> MmkvManager.decodeServerConfig(id) } .filter { profile -> diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/BackupActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/BackupActivity.kt index 4ca884247..4f29b5d4a 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/BackupActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/BackupActivity.kt @@ -18,7 +18,6 @@ import com.v2ray.ang.extension.toastError import com.v2ray.ang.extension.toastSuccess import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.handler.SettingsChangeManager -import com.v2ray.ang.handler.SettingsManager import com.v2ray.ang.handler.WebDavManager import com.v2ray.ang.util.ZipUtil import kotlinx.coroutines.Dispatchers @@ -125,8 +124,6 @@ class BackupActivity : HelperBaseActivity() { val count = MMKV.restoreAllFromDirectory(backupDir) SettingsChangeManager.makeSetupGroupTab() SettingsChangeManager.makeRestartService() - - SettingsManager.initApp(this) return count > 0 } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt index e70237218..988c37462 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt @@ -164,7 +164,6 @@ class GroupServerFragment : BaseFragment() { val intent = Intent().putExtra("guid", guid) .putExtra("isRunning", mainViewModel.isRunning.value) .putExtra("createConfigType", profile.configType.value) - .putExtra("subscriptionId", subId) when (profile.configType) { EConfigType.CUSTOM -> { ownerActivity.startActivity(intent.setClass(ownerActivity, ServerCustomConfigActivity::class.java)) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt index 5c7db83ec..8169f1990 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt @@ -145,7 +145,7 @@ class SubEditActivity : BaseActivity() { del_config = menu.findItem(R.id.del_config) save_config = menu.findItem(R.id.save_config) - if (editSubId.isEmpty() || editSubId == AppConfig.DEFAULT_SUBSCRIPTION_ID) { + if (editSubId.isEmpty()) { del_config?.isVisible = false } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt index 164fba6af..0c482499a 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt @@ -5,9 +5,7 @@ import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import com.v2ray.ang.AppConfig import com.v2ray.ang.contracts.BaseAdapterListener import com.v2ray.ang.databinding.ItemRecyclerSubSettingBinding import com.v2ray.ang.helper.ItemTouchHelperAdapter @@ -39,7 +37,6 @@ class SubSettingRecyclerAdapter( holder.itemSubSettingBinding.layoutRemove.setOnClickListener { adapterListener?.onRemove(subId, position) } - holder.itemSubSettingBinding.layoutRemove.isVisible = subId != AppConfig.DEFAULT_SUBSCRIPTION_ID holder.itemSubSettingBinding.chkEnable.setOnCheckedChangeListener { it, isChecked -> if (!it.isPressed) return@setOnCheckedChangeListener diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/TaskerActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/TaskerActivity.kt index 41f5430b8..89f4fbe1d 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/TaskerActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/TaskerActivity.kt @@ -30,7 +30,7 @@ class TaskerActivity : BaseActivity() { lstData.add("Default") lstGuid.add(AppConfig.TASKER_DEFAULT_GUID) - MmkvManager.decodeAllServerList().forEach { key -> + MmkvManager.decodeServerList().forEach { key -> MmkvManager.decodeServerConfig(key)?.let { config -> lstData.add(config.remarks) lstGuid.add(key) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt index 668c5aefe..0b0de8316 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -35,7 +35,7 @@ import kotlinx.coroutines.withContext import java.util.Collections class MainViewModel(application: Application) : AndroidViewModel(application) { - private var serverList = mutableListOf() // MmkvManager.decodeServerList() + private var serverList = MmkvManager.decodeServerList() var subscriptionId: String = MmkvManager.decodeSettingsString(AppConfig.CACHE_SUBSCRIPTION_ID, "").orEmpty() //var keywordFilter: String = MmkvManager.MmkvManager.decodeSettingsString(AppConfig.CACHE_KEYWORD_FILTER, "")?:"" @@ -69,15 +69,10 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } /** - * Reloads the server list based on current subscription filter. + * Reloads the server list. */ fun reloadServerList() { - serverList = if (subscriptionId.isEmpty()) { - MmkvManager.decodeAllServerList() - } else { - MmkvManager.decodeServerList(subscriptionId) - } - + serverList = MmkvManager.decodeServerList() updateCache() updateListAction.value = -1 } @@ -134,13 +129,14 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { */ fun swapServer(fromPosition: Int, toPosition: Int) { if (subscriptionId.isEmpty()) { - return + Collections.swap(serverList, fromPosition, toPosition) + } else { + val fromPosition2 = serverList.indexOf(serversCache[fromPosition].guid) + val toPosition2 = serverList.indexOf(serversCache[toPosition].guid) + Collections.swap(serverList, fromPosition2, toPosition2) } - - Collections.swap(serverList, fromPosition, toPosition) Collections.swap(serversCache, fromPosition, toPosition) - - MmkvManager.encodeServerList(serverList, subscriptionId) + MmkvManager.encodeServerList(serverList) } /** @@ -164,9 +160,9 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { // MmkvManager.encodeServerConfig(guid, config) // } -// if (subscriptionId.isNotEmpty() && subscriptionId != profile.subscriptionId) { -// continue -// } + if (subscriptionId.isNotEmpty() && subscriptionId != profile.subscriptionId) { + continue + } if (keywordFilter.isEmpty() || profile.remarks.lowercase().contains(keywordFilter.lowercase())) { serversCache.add(ServersCache(guid, profile)) @@ -283,21 +279,14 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } val groups = mutableListOf() - if (subscriptions.count() > 1) { - groups.add( - GroupMapItem( - id = "", - remarks = context.getString(R.string.filter_config_all) - ) + groups.add( + GroupMapItem( + id = "", + remarks = context.getString(R.string.filter_config_all) ) - } + ) subscriptions.forEach { sub -> - groups.add( - GroupMapItem( - id = sub.guid, - remarks = sub.subscription.remarks - ) - ) + groups.add(GroupMapItem(id = sub.guid, remarks = sub.subscription.remarks)) } return groups } @@ -382,9 +371,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { data class ServerDelay(var guid: String, var testDelayMillis: Long) val serverDelays = mutableListOf() - // Use current subscription filter - val serverListToSort = MmkvManager.decodeServerList(subscriptionId) - serverListToSort.forEach { key -> + val serverList = MmkvManager.decodeServerList() + serverList.forEach { key -> val delay = MmkvManager.decodeServerAffiliationInfo(key)?.testDelayMillis ?: 0L serverDelays.add(ServerDelay(key, if (delay <= 0L) 999999 else delay)) } @@ -395,8 +383,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { serverList.add(it.guid) } - // Save to appropriate list based on subscriptionId - MmkvManager.encodeServerList(serverList, subscriptionId) + MmkvManager.encodeServerList(serverList) } /**