diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt index 47784bbc..8f38e8ba 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt @@ -99,4 +99,6 @@ object AppConfig { const val SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL = "1440" // 24 hours const val SUBSCRIPTION_UPDATE_TASK_NAME = "subscription_updater" + const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id" + const val CACHE_KEYWORD_FILTER = "cache_keyword_filter" } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt index 8a1e05ce..1e44ba19 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -25,12 +25,28 @@ import kotlinx.coroutines.* import java.util.* class MainViewModel(application: Application) : AndroidViewModel(application) { - private val mainStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_MAIN, MMKV.MULTI_PROCESS_MODE) } - private val serverRawStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SERVER_RAW, MMKV.MULTI_PROCESS_MODE) } + private val mainStorage by lazy { + MMKV.mmkvWithID( + MmkvManager.ID_MAIN, + MMKV.MULTI_PROCESS_MODE + ) + } + private val serverRawStorage by lazy { + MMKV.mmkvWithID( + MmkvManager.ID_SERVER_RAW, + MMKV.MULTI_PROCESS_MODE + ) + } + private val settingsStorage by lazy { + MMKV.mmkvWithID( + MmkvManager.ID_SETTING, + MMKV.MULTI_PROCESS_MODE + ) + } var serverList = MmkvManager.decodeServerList() - var subscriptionId: String = "" - var keywordFilter: String = "" + var subscriptionId: String = settingsStorage.decodeString(AppConfig.CACHE_SUBSCRIPTION_ID, "")!! + var keywordFilter: String = settingsStorage.decodeString(AppConfig.CACHE_KEYWORD_FILTER, "")!! private set val serversCache = mutableListOf() val isRunning by lazy { MutableLiveData() } @@ -74,7 +90,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { serverList.remove(guid) MmkvManager.removeServer(guid) val index = getPosition(guid) - if(index >= 0){ + if (index >= 0) { serversCache.removeAt(index) } } @@ -87,7 +103,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { val key = MmkvManager.encodeServerConfig("", config) serverRawStorage?.encode(key, server) serverList.add(0, key) - serversCache.add(0, ServersCache(key,config)) + serversCache.add(0, ServersCache(key, config)) } fun swapServer(fromPosition: Int, toPosition: Int) { @@ -127,7 +143,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { val testResult = SpeedtestUtil.tcping(serverAddress, serverPort) launch(Dispatchers.Main) { MmkvManager.encodeServerTestDelayMillis(item.guid, testResult) - updateListAction.value = getPosition(item.guid) + updateListAction.value = getPosition(item.guid) } } } @@ -147,7 +163,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { for (item in serversCopy) { val config = V2rayConfigUtil.getV2rayConfig(getApplication(), item.guid) if (config.status) { - MessageUtil.sendMsg2TestService(getApplication(), AppConfig.MSG_MEASURE_CONFIG, Pair(item.guid, config.content)) + MessageUtil.sendMsg2TestService( + getApplication(), + AppConfig.MSG_MEASURE_CONFIG, + Pair(item.guid, config.content) + ) } } } @@ -157,7 +177,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { MessageUtil.sendMsg2Service(getApplication(), AppConfig.MSG_MEASURE_DELAY, "") } - fun filterConfig(context :Context) { + fun filterConfig(context: Context) { val subscriptions = MmkvManager.decodeSubscriptions() val listId = subscriptions.map { it.first }.toList().toMutableList() val listRemarks = subscriptions.map { it.second.remarks }.toList().toMutableList() @@ -169,7 +189,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } val ivBinding = DialogConfigFilterBinding.inflate(LayoutInflater.from(context)) - ivBinding.spSubscriptionId.adapter = ArrayAdapter( context, android.R.layout.simple_spinner_dropdown_item, listRemarks) + ivBinding.spSubscriptionId.adapter = ArrayAdapter( + context, + android.R.layout.simple_spinner_dropdown_item, + listRemarks + ) ivBinding.spSubscriptionId.setSelection(checkedItem) ivBinding.etKeyword.text = Utils.getEditable(keywordFilter) val builder = AlertDialog.Builder(context).setView(ivBinding.root) @@ -183,6 +207,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { subscriptions[position].first } keywordFilter = ivBinding.etKeyword.text.toString() + settingsStorage?.encode(AppConfig.CACHE_SUBSCRIPTION_ID, subscriptionId) + settingsStorage?.encode(AppConfig.CACHE_KEYWORD_FILTER, keywordFilter) reloadServerList() dialogInterface?.dismiss() @@ -207,7 +233,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { // }.show() } - fun getPosition(guid: String) : Int { + fun getPosition(guid: String): Int { serversCache.forEachIndexed { index, it -> if (it.guid == guid) return index @@ -220,20 +246,24 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { serversCache.forEachIndexed { index, it -> val outbound = it.config.getProxyOutbound() serversCache.forEachIndexed { index2, it2 -> - if(index2 > index){ + if (index2 > index) { val outbound2 = it2.config.getProxyOutbound() - if( outbound == outbound2 && !deleteServer.contains(it2.guid)) - { + if (outbound == outbound2 && !deleteServer.contains(it2.guid)) { deleteServer.add(it2.guid) } } } } - for(it in deleteServer){ + for (it in deleteServer) { MmkvManager.removeServer(it) } reloadServerList() - getApplication().toast(getApplication().getString(R.string.title_del_duplicate_config_count, deleteServer.count())) + getApplication().toast( + getApplication().getString( + R.string.title_del_duplicate_config_count, + deleteServer.count() + ) + ) } private val mMsgReceiver = object : BroadcastReceiver() { @@ -242,23 +272,29 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { AppConfig.MSG_STATE_RUNNING -> { isRunning.value = true } + AppConfig.MSG_STATE_NOT_RUNNING -> { isRunning.value = false } + AppConfig.MSG_STATE_START_SUCCESS -> { getApplication().toast(R.string.toast_services_success) isRunning.value = true } + AppConfig.MSG_STATE_START_FAILURE -> { getApplication().toast(R.string.toast_services_failure) isRunning.value = false } + AppConfig.MSG_STATE_STOP_SUCCESS -> { isRunning.value = false } + AppConfig.MSG_MEASURE_DELAY_SUCCESS -> { updateTestResultAction.value = intent.getStringExtra("content") } + AppConfig.MSG_MEASURE_CONFIG_SUCCESS -> { val resultPair = intent.getSerializableExtra("content") as Pair MmkvManager.encodeServerTestDelayMillis(resultPair.first, resultPair.second)