diff --git a/app/src/main/java/com/android/skip/data/download/ApkDownloadRepository.kt b/app/src/main/java/com/android/skip/data/download/ApkDownloadRepository.kt new file mode 100644 index 00000000..6a15fb72 --- /dev/null +++ b/app/src/main/java/com/android/skip/data/download/ApkDownloadRepository.kt @@ -0,0 +1,17 @@ +package com.android.skip.data.download + +import com.android.skip.data.network.MyApiNetwork +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ApkDownloadRepository @Inject constructor( + private val myApiNetwork: MyApiNetwork +) { + suspend fun downloadAPK(latestVersion: String, onDownloadProcess: (process: Int) -> Unit) = + withContext(Dispatchers.IO) { + myApiNetwork.fetchAPK(latestVersion, onDownloadProcess) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/data/download/ApkDownloadViewModel.kt b/app/src/main/java/com/android/skip/data/download/ApkDownloadViewModel.kt new file mode 100644 index 00000000..d6c7ca92 --- /dev/null +++ b/app/src/main/java/com/android/skip/data/download/ApkDownloadViewModel.kt @@ -0,0 +1,40 @@ +package com.android.skip.data.download + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import javax.inject.Inject + +@HiltViewModel +class ApkDownloadViewModel @Inject constructor( + private val apkDownloadRepository: ApkDownloadRepository +) : ViewModel() { + private val _isShowDialog = MutableLiveData(false) + val isShowDialog: LiveData = _isShowDialog + + private val _apkDownloadProcess = MutableLiveData(0) + val apkDownloadProcess: LiveData = _apkDownloadProcess + + fun changeDialogState(showDialog: Boolean) { + _isShowDialog.postValue(showDialog) + } + + private fun changeApkDownloadProcess(process: Int) { + _apkDownloadProcess.postValue(process) + } + + fun downloadAPK(latestVersion: String) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + apkDownloadRepository.downloadAPK(latestVersion) { + changeApkDownloadProcess(it) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/data/network/MyApiNetwork.kt b/app/src/main/java/com/android/skip/data/network/MyApiNetwork.kt index 565449b3..7ffa7236 100644 --- a/app/src/main/java/com/android/skip/data/network/MyApiNetwork.kt +++ b/app/src/main/java/com/android/skip/data/network/MyApiNetwork.kt @@ -1,9 +1,17 @@ package com.android.skip.data.network +import com.android.skip.MyApp import com.android.skip.data.network.api.MyApiService import com.blankj.utilcode.util.AppUtils +import com.blankj.utilcode.util.FileUtils +import com.blankj.utilcode.util.LogUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.floor @Singleton class MyApiNetwork @Inject constructor() { @@ -26,4 +34,50 @@ class MyApiNetwork @Inject constructor() { AppUtils.getAppVersionName() } } + + suspend fun fetchAPK(latestVersion: String, onDownloadProcess: (process: Int)->Unit) { + try { + val response = myApiService.downloadAPK(latestVersion) + + if (response.isSuccessful) { + response.body()?.let { body-> + val contentLength = body.contentLength() + val inputStream = body.byteStream() + + val path = "${MyApp.context.filesDir}/apk" + val fileDir = File(path) + if (!fileDir.exists()) { + fileDir.mkdir() + } else { + FileUtils.deleteFilesInDir(fileDir) + } + + val file = File(path, "SKIP-v$latestVersion.apk") + val outputStream = FileOutputStream(file) + + val buffer = ByteArray(2048) + var downloaded = 0L + var read: Int + + withContext(Dispatchers.IO) { + while (inputStream.read(buffer).also { read = it } != -1) { + outputStream.write(buffer, 0, read) + downloaded += read + val progress = (downloaded.toFloat() / contentLength.toFloat()) * 100 + withContext(Dispatchers.Main) { + onDownloadProcess(floor(progress).toInt()) + } + } + outputStream.flush() + outputStream.close() + inputStream.close() + } + } + } else { + throw Exception("Failed to download file: ${response.errorBody()?.string()}") + } + } catch (e: Exception) { + LogUtils.e(e) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/data/network/api/MyApiService.kt b/app/src/main/java/com/android/skip/data/network/api/MyApiService.kt index 504acde1..22d12d0c 100644 --- a/app/src/main/java/com/android/skip/data/network/api/MyApiService.kt +++ b/app/src/main/java/com/android/skip/data/network/api/MyApiService.kt @@ -1,7 +1,10 @@ package com.android.skip.data.network.api +import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Streaming import retrofit2.http.Url interface MyApiService { @@ -10,4 +13,8 @@ interface MyApiService { @GET("/latest_version.txt") suspend fun getLatestVersion(): Response + + @GET("/SKIP-v{version}.apk") + @Streaming + suspend fun downloadAPK(@Path("version") latestVersion: String): Response } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/data/version/ApkVersionRepository.kt b/app/src/main/java/com/android/skip/data/version/ApkVersionRepository.kt index c6542354..9462ae86 100644 --- a/app/src/main/java/com/android/skip/data/version/ApkVersionRepository.kt +++ b/app/src/main/java/com/android/skip/data/version/ApkVersionRepository.kt @@ -25,12 +25,19 @@ class ApkVersionRepository @Inject constructor( _versionPostState.postValue(versionPostState) val version = myApiNetwork.fetchLatestVersion() if (version == AppUtils.getAppVersionName()) { - _versionPostState.postValue(VersionPostSchema(VersionState.CURRENT_LATEST, version)) + _versionPostState.postValue( + VersionPostSchema( + VersionState.CURRENT_LATEST, + version, + version + ) + ) } else { _versionPostState.postValue( VersionPostSchema( VersionState.DISCOVER_LATEST, - getString(R.string.about_discover_latest) + getString(R.string.about_discover_latest), + version ) ) } @@ -38,7 +45,7 @@ class ApkVersionRepository @Inject constructor( suspend fun checkVersion() { changeVersionState( - VersionPostSchema(VersionState.PENDING, getString(R.string.checking)) + VersionPostSchema(VersionState.PENDING, getString(R.string.checking), String()) ) } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/dataclass/VersionPostSchema.kt b/app/src/main/java/com/android/skip/dataclass/VersionPostSchema.kt index 7d893032..b4eb768e 100644 --- a/app/src/main/java/com/android/skip/dataclass/VersionPostSchema.kt +++ b/app/src/main/java/com/android/skip/dataclass/VersionPostSchema.kt @@ -6,5 +6,6 @@ enum class VersionState { data class VersionPostSchema( val status: VersionState, - val value: String + val value: String, + val latestVersion: String ) \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/about/AboutActivity.kt b/app/src/main/java/com/android/skip/ui/about/AboutActivity.kt index fe6cc84e..1ea2e8ad 100644 --- a/app/src/main/java/com/android/skip/ui/about/AboutActivity.kt +++ b/app/src/main/java/com/android/skip/ui/about/AboutActivity.kt @@ -13,7 +13,10 @@ import com.android.skip.MyApp import com.android.skip.R import com.android.skip.data.config.ConfigViewModel import com.android.skip.data.version.ApkVersionViewModel +import com.android.skip.dataclass.VersionState import com.android.skip.ui.about.config.ConfigVersionButton +import com.android.skip.ui.about.download.ApkDownloadDialog +import com.android.skip.data.download.ApkDownloadViewModel import com.android.skip.ui.about.version.ApkVersionButton import com.android.skip.ui.components.FlatButton import com.android.skip.ui.components.ResourceIcon @@ -32,6 +35,8 @@ class AboutActivity : AppCompatActivity() { private val apkVersionViewModel by viewModels() + private val apkDownloadViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { @@ -52,6 +57,7 @@ class AboutActivity : AppCompatActivity() { } ApkVersionButton(apkVersionViewModel) ConfigVersionButton(configViewModel) + ApkDownloadDialog(apkDownloadViewModel, apkVersionViewModel) }, { DropdownMenuItem( leadingIcon = { ResourceIcon(iconResource = R.drawable.help) }, @@ -65,6 +71,12 @@ class AboutActivity : AppCompatActivity() { }) } } + + apkVersionViewModel.versionPostState.observe(this) { + if (it.status == VersionState.DISCOVER_LATEST) { + apkDownloadViewModel.changeDialogState(true) + } + } } } diff --git a/app/src/main/java/com/android/skip/ui/about/download/ApkDownloadDialog.kt b/app/src/main/java/com/android/skip/ui/about/download/ApkDownloadDialog.kt new file mode 100644 index 00000000..256f0df3 --- /dev/null +++ b/app/src/main/java/com/android/skip/ui/about/download/ApkDownloadDialog.kt @@ -0,0 +1,81 @@ +package com.android.skip.ui.about.download + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import com.android.skip.R +import com.android.skip.data.download.ApkDownloadViewModel +import com.android.skip.data.version.ApkVersionViewModel +import com.blankj.utilcode.util.AppUtils +import com.blankj.utilcode.util.StringUtils.getString + +@Composable +fun ApkDownloadDialog( + apkDownloadViewModel: ApkDownloadViewModel, + apkVersionViewModel: ApkVersionViewModel +) { + val showDialog = apkDownloadViewModel.isShowDialog.observeAsState() + + val versionPostState = apkVersionViewModel.versionPostState.observeAsState() + + val apkDownloadProcess = apkDownloadViewModel.apkDownloadProcess.observeAsState() + + if (showDialog.value == true) { + AlertDialog( + modifier = Modifier.fillMaxWidth(), + containerColor = MaterialTheme.colorScheme.background, + title = { + Text(text = stringResource(id = R.string.dialog_new_version_released)) + }, + text = { + Column { + Text( + text = getString( + R.string.dialog_update_version, + AppUtils.getAppVersionName(), + versionPostState.value?.latestVersion + ) + ) + apkDownloadProcess.value?.let { process -> + if (process > 0) { + Text( + text = getString( + R.string.dialog_downloading, + apkDownloadProcess.value + ) + ) + } + } + } + + }, + onDismissRequest = { + apkDownloadViewModel.changeDialogState(false) + }, + confirmButton = { + Button(onClick = { + versionPostState.value?.latestVersion?.let { + apkDownloadViewModel.downloadAPK( + it + ) + } + }) { + Text(text = stringResource(id = R.string.dialog_update_now)) + } + }, + dismissButton = { + TextButton(onClick = { apkDownloadViewModel.changeDialogState(false) }) { + Text(text = stringResource(id = R.string.dialog_not_update)) + } + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarRepository.kt b/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarRepository.kt index 100cf179..f1afb3e5 100644 --- a/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarRepository.kt +++ b/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarRepository.kt @@ -17,6 +17,5 @@ class NotificationBarRepository @Inject constructor() { fun changeEnable(enable: Boolean) { _enable.postValue(enable) - DataStoreUtils.putSyncData(getString(R.string.store_resident_notification_bar), enable) } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarViewModel.kt b/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarViewModel.kt index 3096f420..6249a2a2 100644 --- a/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/alive/notificationbar/NotificationBarViewModel.kt @@ -1,7 +1,14 @@ package com.android.skip.ui.alive.notificationbar import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.android.skip.R +import com.android.skip.util.DataStoreUtils +import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -10,5 +17,13 @@ class NotificationBarViewModel @Inject constructor( ) : ViewModel() { val enable = notificationBarRepository.enable - fun changeEnable(enable: Boolean) = notificationBarRepository.changeEnable(enable) + fun changeEnable(enable: Boolean) { + notificationBarRepository.changeEnable(enable) + + viewModelScope.launch { + withContext(Dispatchers.IO) { + DataStoreUtils.putSyncData(getString(R.string.store_resident_notification_bar), enable) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/components/notification/NotificationDialog.kt b/app/src/main/java/com/android/skip/ui/components/notification/NotificationDialog.kt index 1c7cf380..9c63d6cd 100644 --- a/app/src/main/java/com/android/skip/ui/components/notification/NotificationDialog.kt +++ b/app/src/main/java/com/android/skip/ui/components/notification/NotificationDialog.kt @@ -3,6 +3,7 @@ package com.android.skip.ui.components.notification import android.content.Intent import android.provider.Settings import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -31,7 +32,7 @@ fun NotificationDialog( }, onDismissRequest = onDismiss, confirmButton = { - TextButton( + Button( onClick = { val intent = Intent().apply { action = Settings.ACTION_APP_NOTIFICATION_SETTINGS diff --git a/app/src/main/java/com/android/skip/ui/settings/recent/RecentViewModel.kt b/app/src/main/java/com/android/skip/ui/settings/recent/RecentViewModel.kt index 689e24dc..f0c72e33 100644 --- a/app/src/main/java/com/android/skip/ui/settings/recent/RecentViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/settings/recent/RecentViewModel.kt @@ -8,7 +8,9 @@ import com.android.skip.R import com.android.skip.util.DataStoreUtils import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -25,7 +27,9 @@ class RecentViewModel @Inject constructor() : ViewModel() { _excludeFromRecent.postValue(excludeFromRecent) viewModelScope.launch { - DataStoreUtils.putData(getString(R.string.store_exclude_from_recent), excludeFromRecent) + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.store_exclude_from_recent), excludeFromRecent) + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/settings/strict/StrictViewModel.kt b/app/src/main/java/com/android/skip/ui/settings/strict/StrictViewModel.kt index f3655d00..321ba59b 100644 --- a/app/src/main/java/com/android/skip/ui/settings/strict/StrictViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/settings/strict/StrictViewModel.kt @@ -6,7 +6,9 @@ import com.android.skip.R import com.android.skip.util.DataStoreUtils import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -19,7 +21,9 @@ class StrictViewModel @Inject constructor( strictRepository.changeEnable(enable) viewModelScope.launch { - DataStoreUtils.putData(getString(R.string.store_strict_mode), enable) + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.store_strict_mode), enable) + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeButton.kt b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeButton.kt index 5d9ebc2f..c31c242b 100644 --- a/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeButton.kt +++ b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeButton.kt @@ -4,6 +4,7 @@ import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -27,60 +28,54 @@ fun SwitchThemeButton(switchThemeViewModel: SwitchThemeViewModel) { icon = { currentTheme.value?.themeIcon?.let { ResourceIcon(iconResource = it) } } ) }, menuItems = { - DropdownMenuItem( - leadingIcon = { ResourceIcon(iconResource = R.drawable.theme_light) }, - text = { - Text( - text = stringResource(id = R.string.settings_theme_light), - color = if (currentTheme.value?.themeMode == ThemeMode.UI_LIGHT) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground - ) - }, - onClick = { - expandedState.value = false - switchThemeViewModel.changeCurrentTheme( - SwitchThemeCarrier( - themeMode = ThemeMode.UI_LIGHT, - themeName = R.string.settings_theme_light, - themeIcon = R.drawable.theme_light - ) - ) - }) - DropdownMenuItem( - leadingIcon = { ResourceIcon(iconResource = R.drawable.theme_dark) }, - text = { - Text( - text = stringResource(id = R.string.settings_theme_dark), - color = if (currentTheme.value?.themeMode == ThemeMode.UI_DARK) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground - ) - }, - onClick = { - expandedState.value = false - switchThemeViewModel.changeCurrentTheme( - SwitchThemeCarrier( - themeMode = ThemeMode.UI_DARK, - themeName = R.string.settings_theme_dark, - themeIcon = R.drawable.theme_dark - ) - ) - }) - DropdownMenuItem( - leadingIcon = { ResourceIcon(iconResource = R.drawable.theme_auto) }, - text = { - Text( - text = stringResource(id = R.string.settings_theme_auto), - color = if (currentTheme.value?.themeMode == ThemeMode.UI_AUTO) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground - ) - }, - onClick = { - expandedState.value = false + ThemeDropdownMenuItem( + iconRes = R.drawable.theme_light, + textRes = R.string.settings_theme_light, + currentTheme = currentTheme, + themeMode = ThemeMode.UI_LIGHT + ) { + expandedState.value = false + switchThemeViewModel.changeCurrentTheme(ThemeMode.UI_LIGHT.name) + } - switchThemeViewModel.changeCurrentTheme( - SwitchThemeCarrier( - themeMode = ThemeMode.UI_AUTO, - themeName = R.string.settings_theme_auto, - themeIcon = R.drawable.theme_auto - ) - ) - }) + ThemeDropdownMenuItem( + iconRes = R.drawable.theme_dark, + textRes = R.string.settings_theme_dark, + currentTheme = currentTheme, + themeMode = ThemeMode.UI_DARK + ) { + expandedState.value = false + switchThemeViewModel.changeCurrentTheme(ThemeMode.UI_DARK.name) + } + + ThemeDropdownMenuItem( + iconRes = R.drawable.theme_auto, + textRes = R.string.settings_theme_auto, + currentTheme = currentTheme, + themeMode = ThemeMode.UI_AUTO + ) { + expandedState.value = false + switchThemeViewModel.changeCurrentTheme(ThemeMode.UI_AUTO.name) + } }, expanded = expandedState) -} \ No newline at end of file +} + +@Composable +private fun ThemeDropdownMenuItem( + iconRes: Int, + textRes: Int, + currentTheme: State, + themeMode: ThemeMode, + onClick: () -> Unit +) { + DropdownMenuItem( + leadingIcon = { ResourceIcon(iconResource = iconRes) }, + text = { + Text( + text = stringResource(id = textRes), + color = if (currentTheme.value?.themeMode == themeMode) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground + ) + }, + onClick = onClick + ) +} diff --git a/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeRepository.kt b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeRepository.kt new file mode 100644 index 00000000..1c110eb4 --- /dev/null +++ b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeRepository.kt @@ -0,0 +1,50 @@ +package com.android.skip.ui.settings.theme + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.android.skip.R +import com.android.skip.dataclass.SwitchThemeCarrier +import com.android.skip.dataclass.ThemeMode +import com.android.skip.util.DataStoreUtils +import com.blankj.utilcode.util.StringUtils.getString +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SwitchThemeRepository @Inject constructor() { + private val _currentTheme = MutableLiveData( + getThemeCarrier( + DataStoreUtils.getSyncData( + getString(R.string.store_current_theme), + ThemeMode.UI_AUTO.toString() + ) + ) + ) + val currentTheme: LiveData = _currentTheme + + fun changeCurrentTheme(currentTheme: String) { + _currentTheme.postValue(getThemeCarrier(currentTheme)) + } + + private fun getThemeCarrier(theme: String): SwitchThemeCarrier { + return when (theme) { + ThemeMode.UI_LIGHT.toString() -> SwitchThemeCarrier( + themeMode = ThemeMode.UI_LIGHT, + themeName = R.string.settings_theme_light, + themeIcon = R.drawable.theme_light + ) + + ThemeMode.UI_DARK.toString() -> SwitchThemeCarrier( + themeMode = ThemeMode.UI_DARK, + themeName = R.string.settings_theme_dark, + themeIcon = R.drawable.theme_dark + ) + + else -> SwitchThemeCarrier( + themeMode = ThemeMode.UI_AUTO, + themeName = R.string.settings_theme_auto, + themeIcon = R.drawable.theme_auto + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeViewModel.kt b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeViewModel.kt index a7a01fde..9d2dda52 100644 --- a/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/settings/theme/SwitchThemeViewModel.kt @@ -1,26 +1,31 @@ package com.android.skip.ui.settings.theme import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.android.skip.R import com.android.skip.dataclass.SwitchThemeCarrier -import com.android.skip.dataclass.ThemeMode +import com.android.skip.util.DataStoreUtils +import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel -class SwitchThemeViewModel @Inject constructor() : ViewModel() { - private val _currentTheme = MutableLiveData( - SwitchThemeCarrier( - themeMode = ThemeMode.UI_AUTO, - themeName = R.string.settings_theme_auto, - themeIcon = R.drawable.theme_auto - ) - ) - val currentTheme: LiveData = _currentTheme +class SwitchThemeViewModel @Inject constructor( + private val switchThemeRepository: SwitchThemeRepository +) : ViewModel() { + val currentTheme: LiveData = switchThemeRepository.currentTheme - fun changeCurrentTheme(currentTheme: SwitchThemeCarrier) { - _currentTheme.postValue(currentTheme) + fun changeCurrentTheme(currentTheme: String) { + switchThemeRepository.changeCurrentTheme(currentTheme) + + viewModelScope.launch { + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.store_current_theme), currentTheme) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/settings/tip/TipViewModel.kt b/app/src/main/java/com/android/skip/ui/settings/tip/TipViewModel.kt index b7427dbe..e803a2a0 100644 --- a/app/src/main/java/com/android/skip/ui/settings/tip/TipViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/settings/tip/TipViewModel.kt @@ -6,7 +6,9 @@ import com.android.skip.R import com.android.skip.util.DataStoreUtils import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -18,7 +20,9 @@ class TipViewModel @Inject constructor( tipRepository.changeEnable(enable) viewModelScope.launch { - DataStoreUtils.putData(getString(R.string.store_skip_tip), enable) + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.store_skip_tip), enable) + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/settings/update/AutoUpdateViewModel.kt b/app/src/main/java/com/android/skip/ui/settings/update/AutoUpdateViewModel.kt index d869e519..2c540333 100644 --- a/app/src/main/java/com/android/skip/ui/settings/update/AutoUpdateViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/settings/update/AutoUpdateViewModel.kt @@ -8,7 +8,9 @@ import com.android.skip.R import com.android.skip.util.DataStoreUtils import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -21,7 +23,9 @@ class AutoUpdateViewModel @Inject constructor() : ViewModel() { _autoUpdate.postValue(autoUpdate) viewModelScope.launch { - DataStoreUtils.putData(getString(R.string.store_auto_update), autoUpdate) + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.store_auto_update), autoUpdate) + } } } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2bb870c2..aab4b29a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -89,6 +89,11 @@ 编辑自定义配置 通知权限请求 请开启「允许通知」以便获取通知访问权限 + 立即更新 + 暂不更新 + 新版本已发布 + 更新版本: v%1$s 至 v%2$s + 下载中: %1$s%% CUSTOM_CONFIG https://skip.guoxicheng.top/skip_config_v3.yaml