mirror of
https://github.com/2dust/v2rayNG.git
synced 2026-10-29 06:31:54 +00:00
Refactor BaseViewModel, which inherits from AndroidViewModel.
This commit is contained in:
1 parent
1dee6230f9
commit
1b9401fc42
13 files changed
+47
-28
No files matched your search
@@ -9,7 +9,6 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.v2ray.ang.AngApplication
|
|
||||||
import com.v2ray.ang.compose.AppSnackbarManager
|
import com.v2ray.ang.compose.AppSnackbarManager
|
||||||
import com.v2ray.ang.compose.ToastType
|
import com.v2ray.ang.compose.ToastType
|
||||||
import com.v2ray.ang.enums.EConfigType
|
import com.v2ray.ang.enums.EConfigType
|
||||||
@@ -17,9 +16,6 @@ import java.io.Serializable
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
val myApp: AngApplication
|
|
||||||
get() = AngApplication.application
|
|
||||||
|
|
||||||
private inline fun runOnMain(crossinline block: () -> Unit) {
|
private inline fun runOnMain(crossinline block: () -> Unit) {
|
||||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||||
block()
|
block()
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ import kotlinx.coroutines.withContext
|
|||||||
class MainActivity : HelperBaseComponentActivity() {
|
class MainActivity : HelperBaseComponentActivity() {
|
||||||
|
|
||||||
private val mainViewModel: MainViewModel by viewModels {
|
private val mainViewModel: MainViewModel by viewModels {
|
||||||
MainViewModel.Factory(MainRepository(application as AngApplication))
|
MainViewModel.Factory(application, MainRepository(application as AngApplication))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val requestVpnPermission =
|
private val requestVpnPermission =
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.dto.AppInfo
|
import com.v2ray.ang.dto.AppInfo
|
||||||
@@ -15,7 +16,7 @@ import java.text.Collator
|
|||||||
/**
|
/**
|
||||||
* ViewModel for AppPicker screen.
|
* ViewModel for AppPicker screen.
|
||||||
*/
|
*/
|
||||||
class AppPickerViewModel : BaseViewModel() {
|
class AppPickerViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
private val _selectedPackages = MutableStateFlow<Set<String>>(emptySet())
|
private val _selectedPackages = MutableStateFlow<Set<String>>(emptySet())
|
||||||
val selectedPackages: StateFlow<Set<String>> = _selectedPackages.asStateFlow()
|
val selectedPackages: StateFlow<Set<String>> = _selectedPackages.asStateFlow()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.tencent.mmkv.MMKV
|
import com.tencent.mmkv.MMKV
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
@@ -19,7 +20,7 @@ import java.io.File
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class BackupViewModel : BaseViewModel() {
|
class BackupViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
private val _webDavConfig = MutableStateFlow(MmkvManager.decodeWebDavConfig())
|
private val _webDavConfig = MutableStateFlow(MmkvManager.decodeWebDavConfig())
|
||||||
val webDavConfig: StateFlow<WebDavConfig?> = _webDavConfig.asStateFlow()
|
val webDavConfig: StateFlow<WebDavConfig?> = _webDavConfig.asStateFlow()
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.v2ray.ang.extension.myApp
|
import com.v2ray.ang.AngApplication
|
||||||
import com.v2ray.ang.extension.toast
|
import com.v2ray.ang.extension.toast
|
||||||
import com.v2ray.ang.extension.toastError
|
import com.v2ray.ang.extension.toastError
|
||||||
import com.v2ray.ang.extension.toastSuccess
|
import com.v2ray.ang.extension.toastSuccess
|
||||||
@@ -17,7 +18,14 @@ import kotlinx.coroutines.launch
|
|||||||
/**
|
/**
|
||||||
* Base ViewModel that encapsulates common UI event handling logic.
|
* Base ViewModel that encapsulates common UI event handling logic.
|
||||||
*/
|
*/
|
||||||
abstract class BaseViewModel : ViewModel() {
|
abstract class BaseViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safe access to custom application instance.
|
||||||
|
*/
|
||||||
|
protected val app: AngApplication by lazy {
|
||||||
|
application as AngApplication
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("PropertyName")
|
@Suppress("PropertyName")
|
||||||
protected val _isLoading = MutableStateFlow(false)
|
protected val _isLoading = MutableStateFlow(false)
|
||||||
@@ -31,56 +39,56 @@ abstract class BaseViewModel : ViewModel() {
|
|||||||
* Send neutral toast event (Resource ID).
|
* Send neutral toast event (Resource ID).
|
||||||
*/
|
*/
|
||||||
fun toast(resId: Int) {
|
fun toast(resId: Int) {
|
||||||
myApp.toast(resId)
|
app.toast(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send neutral toast event (String).
|
* Send neutral toast event (String).
|
||||||
*/
|
*/
|
||||||
fun toast(message: String) {
|
fun toast(message: String) {
|
||||||
myApp.toast(message)
|
app.toast(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send success toast event (Resource ID).
|
* Send success toast event (Resource ID).
|
||||||
*/
|
*/
|
||||||
fun toastSuccess(resId: Int) {
|
fun toastSuccess(resId: Int) {
|
||||||
myApp.toastSuccess(resId)
|
app.toastSuccess(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send success toast event (String).
|
* Send success toast event (String).
|
||||||
*/
|
*/
|
||||||
fun toastSuccess(message: String) {
|
fun toastSuccess(message: String) {
|
||||||
myApp.toastSuccess(message)
|
app.toastSuccess(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send error toast event (Resource ID).
|
* Send error toast event (Resource ID).
|
||||||
*/
|
*/
|
||||||
fun toastError(resId: Int) {
|
fun toastError(resId: Int) {
|
||||||
myApp.toastError(resId)
|
app.toastError(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send error toast event (String).
|
* Send error toast event (String).
|
||||||
*/
|
*/
|
||||||
fun toastError(message: String) {
|
fun toastError(message: String) {
|
||||||
myApp.toastError(message)
|
app.toastError(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get string from resource ID.
|
* Get string from resource ID.
|
||||||
*/
|
*/
|
||||||
fun getString(resId: Int): String {
|
fun getString(resId: Int): String {
|
||||||
return myApp.getString(resId)
|
return app.getString(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get formatted string from resource ID.
|
* Get formatted string from resource ID.
|
||||||
*/
|
*/
|
||||||
fun getString(resId: Int, vararg formatArgs: Any?): String {
|
fun getString(resId: Int, vararg formatArgs: Any?): String {
|
||||||
return myApp.getString(resId, *formatArgs)
|
return app.getString(resId, *formatArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.dto.CheckUpdateResult
|
import com.v2ray.ang.dto.CheckUpdateResult
|
||||||
@@ -10,7 +11,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
class CheckUpdateViewModel : BaseViewModel() {
|
class CheckUpdateViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
private val _checkPreRelease = MutableStateFlow(
|
private val _checkPreRelease = MutableStateFlow(
|
||||||
MmkvManager.decodeSettingsBool(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, false)
|
MmkvManager.decodeSettingsBool(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, false)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||||
import com.v2ray.ang.util.LogUtil
|
import com.v2ray.ang.util.LogUtil
|
||||||
@@ -8,7 +9,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
class LogcatViewModel : BaseViewModel() {
|
class LogcatViewModel(application: Application) : BaseViewModel(application) {
|
||||||
private val logsetsAll: MutableList<String> = mutableListOf()
|
private val logsetsAll: MutableList<String> = mutableListOf()
|
||||||
private var currentFilter: String = ""
|
private var currentFilter: String = ""
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
@@ -39,8 +40,9 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
import java.util.regex.PatternSyntaxException
|
import java.util.regex.PatternSyntaxException
|
||||||
|
|
||||||
class MainViewModel(
|
class MainViewModel(
|
||||||
|
application: Application,
|
||||||
private val dataSource: MainDataSource
|
private val dataSource: MainDataSource
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel(application) {
|
||||||
|
|
||||||
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
|
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||||
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
|
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
|
||||||
@@ -759,11 +761,11 @@ class MainViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Factory ----------
|
// ---------- Factory ----------
|
||||||
class Factory(private val dataSource: MainDataSource) : ViewModelProvider.Factory {
|
class Factory(private val application: Application, private val dataSource: MainDataSource) : ViewModelProvider.Factory {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
|
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
|
||||||
return MainViewModel(dataSource) as T
|
return MainViewModel(application, dataSource) as T
|
||||||
}
|
}
|
||||||
throw IllegalArgumentException("Unknown ViewModel class")
|
throw IllegalArgumentException("Unknown ViewModel class")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||||
@@ -23,7 +24,7 @@ import java.text.Collator
|
|||||||
* ViewModel for PerAppProxy screen.
|
* ViewModel for PerAppProxy screen.
|
||||||
* Holds all UI state and business logic.
|
* Holds all UI state and business logic.
|
||||||
*/
|
*/
|
||||||
class PerAppProxyViewModel : BaseViewModel() {
|
class PerAppProxyViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
// Blacklist (apps to be proxied or bypassed)
|
// Blacklist (apps to be proxied or bypassed)
|
||||||
private val _blacklist = MutableStateFlow(loadBlacklist())
|
private val _blacklist = MutableStateFlow(loadBlacklist())
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import com.v2ray.ang.dto.entities.RulesetItem
|
import com.v2ray.ang.dto.entities.RulesetItem
|
||||||
import com.v2ray.ang.handler.MmkvManager
|
import com.v2ray.ang.handler.MmkvManager
|
||||||
import com.v2ray.ang.handler.SettingsManager
|
import com.v2ray.ang.handler.SettingsManager
|
||||||
@@ -8,7 +9,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class RoutingSettingsViewModel : BaseViewModel() {
|
class RoutingSettingsViewModel(application: Application) : BaseViewModel(application) {
|
||||||
private val rulesets: MutableList<RulesetItem> = mutableListOf()
|
private val rulesets: MutableList<RulesetItem> = mutableListOf()
|
||||||
|
|
||||||
private val _rulesetsFlow = MutableStateFlow<List<RulesetItem>>(emptyList())
|
private val _rulesetsFlow = MutableStateFlow<List<RulesetItem>>(emptyList())
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.root.RootManager
|
import com.v2ray.ang.root.RootManager
|
||||||
@@ -7,7 +8,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class SettingsViewModel : BaseViewModel() {
|
class SettingsViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for root access and requests it if necessary.
|
* Checks for root access and requests it if necessary.
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.dto.entities.SubscriptionCache
|
import com.v2ray.ang.dto.entities.SubscriptionCache
|
||||||
import com.v2ray.ang.dto.entities.SubscriptionItem
|
import com.v2ray.ang.dto.entities.SubscriptionItem
|
||||||
import com.v2ray.ang.handler.AngConfigManager
|
import com.v2ray.ang.handler.AngConfigManager
|
||||||
import com.v2ray.ang.handler.MmkvManager
|
import com.v2ray.ang.handler.MmkvManager
|
||||||
|
import com.v2ray.ang.handler.MmkvManager.rememberMmkvBool
|
||||||
import com.v2ray.ang.handler.SettingsChangeManager
|
import com.v2ray.ang.handler.SettingsChangeManager
|
||||||
import com.v2ray.ang.handler.SettingsManager
|
import com.v2ray.ang.handler.SettingsManager
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -14,7 +19,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class SubscriptionsViewModel : BaseViewModel() {
|
class SubscriptionsViewModel(application: Application) : BaseViewModel(application) {
|
||||||
private val subscriptions: MutableList<SubscriptionCache> =
|
private val subscriptions: MutableList<SubscriptionCache> =
|
||||||
MmkvManager.decodeSubscriptions().toMutableList()
|
MmkvManager.decodeSubscriptions().toMutableList()
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.v2ray.ang.viewmodel
|
package com.v2ray.ang.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.dto.UrlContentRequest
|
import com.v2ray.ang.dto.UrlContentRequest
|
||||||
import com.v2ray.ang.dto.entities.AssetUrlCache
|
import com.v2ray.ang.dto.entities.AssetUrlCache
|
||||||
@@ -14,7 +15,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class UserAssetViewModel : BaseViewModel() {
|
class UserAssetViewModel(application: Application) : BaseViewModel(application) {
|
||||||
private val assets = mutableListOf<AssetUrlCache>()
|
private val assets = mutableListOf<AssetUrlCache>()
|
||||||
private val builtInGeoFiles = listOf(AppConfig.GEOSITE_DAT, AppConfig.GEOIP_DAT, AppConfig.GEOIP_ONLY_CN_PRIVATE_DAT)
|
private val builtInGeoFiles = listOf(AppConfig.GEOSITE_DAT, AppConfig.GEOIP_DAT, AppConfig.GEOIP_ONLY_CN_PRIVATE_DAT)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user