From e8096c888ff2c189ac724cb5a96b415ac07196b4 Mon Sep 17 00:00:00 2001 From: rushii <33725716+DiamondMiner88@users.noreply.github.com> Date: Sat, 5 Nov 2022 13:07:32 -0700 Subject: [PATCH] fix: error highlight on invalid pkg name (#30) --- .../com/aliucord/manager/MainActivity.kt | 2 +- .../component/settings/SettingsTextField.kt | 2 ++ .../aliucord/manager/ui/screen/HomeScreen.kt | 4 +++ .../manager/ui/screen/SettingsScreen.kt | 3 +- .../manager/ui/viewmodel/HomeViewModel.kt | 6 ++++ .../manager/ui/viewmodel/SettingsViewModel.kt | 30 ++++++++++++++++++- .../com/aliucord/manager/util/Throttling.kt | 25 ++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 8 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 app/src/main/kotlin/com/aliucord/manager/util/Throttling.kt diff --git a/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt b/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt index 12e41ee..9eb8bab 100644 --- a/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt +++ b/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt @@ -64,7 +64,7 @@ class MainActivity : ComponentActivity() { is BaseScreenDestination -> BaseScreen( currentNavItem = dest, bottomNavItems = listOf(AppDestination.Home, AppDestination.Plugins, AppDestination.Settings), - onNavChanged = { navController.navigate(it) } + onNavChanged = { navController.replaceLast(it) } ) { when (dest) { is AppDestination.Home -> HomeScreen( diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/component/settings/SettingsTextField.kt b/app/src/main/kotlin/com/aliucord/manager/ui/component/settings/SettingsTextField.kt index 4a10d4d..a10f1d9 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/component/settings/SettingsTextField.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/component/settings/SettingsTextField.kt @@ -12,6 +12,7 @@ fun SettingsTextField( label: String, disabled: Boolean = false, pref: String, + error: Boolean = false, onPrefChange: (String) -> Unit, ) { Box(modifier = Modifier.padding(horizontal = 18.dp, vertical = 10.dp)) { @@ -21,6 +22,7 @@ fun SettingsTextField( onValueChange = onPrefChange, enabled = !disabled, label = { Text(label) }, + isError = error, singleLine = true ) } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screen/HomeScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screen/HomeScreen.kt index fd15832..eb2121e 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screen/HomeScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screen/HomeScreen.kt @@ -23,6 +23,10 @@ fun HomeScreen( ) { var showInstallerDialog by remember { mutableStateOf(false) } + LaunchedEffect(viewModel.preferences.packageName) { + viewModel.fetchInstalledVersion() + } + if (showInstallerDialog) { InstallerDialog( onDismiss = { showInstallerDialog = false }, diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screen/SettingsScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screen/SettingsScreen.kt index ff3a66e..cdcb7fe 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screen/SettingsScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screen/SettingsScreen.kt @@ -100,7 +100,8 @@ fun SettingsScreen( SettingsTextField( label = stringResource(R.string.setting_package_name), pref = preferences.packageName, - onPrefChange = viewModel::setPackageName + onPrefChange = viewModel::setPackageName, + error = viewModel.packageNameError ) SettingsTextField( diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/HomeViewModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/HomeViewModel.kt index 59d774d..f145fba 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/HomeViewModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/HomeViewModel.kt @@ -102,6 +102,12 @@ class HomeViewModel( } } + fun fetchInstalledVersion() { + viewModelScope.launch(Dispatchers.IO) { + _fetchInstalledVersion() + } + } + fun fetchSupportedVersion() { viewModelScope.launch(Dispatchers.IO) { _fetchSupportedVersion() diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/SettingsViewModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/SettingsViewModel.kt index accb3ca..379f289 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/SettingsViewModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/SettingsViewModel.kt @@ -3,16 +3,27 @@ package com.aliucord.manager.ui.viewmodel import android.app.Application import androidx.compose.runtime.* import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.aliucord.manager.R import com.aliucord.manager.domain.manager.PreferencesManager import com.aliucord.manager.ui.theme.Theme +import com.aliucord.manager.util.showToast +import com.aliucord.manager.util.throttle class SettingsViewModel( private val application: Application, val preferences: PreferencesManager ) : ViewModel() { + private val checkPackageNameThrottled = throttle(50L, viewModelScope) { + packageNameError = !PACKAGE_REGEX.matches(preferences.packageName) + } + var showThemeDialog by mutableStateOf(false) private set + var packageNameError by mutableStateOf(false) + private set + fun showThemeDialog() { showThemeDialog = true } @@ -22,7 +33,8 @@ class SettingsViewModel( } fun setPackageName(packageName: String) { - if (packageName.isNotBlank()) preferences.packageName = packageName + preferences.packageName = packageName + checkPackageNameThrottled() } fun setAppName(appName: String) { @@ -40,4 +52,20 @@ class SettingsViewModel( fun clearCacheDir() { application.cacheDir.deleteRecursively() } + + init { + checkPackageNameThrottled() + } + + override fun onCleared() { + if (!PACKAGE_REGEX.matches(preferences.packageName)) { + preferences.packageName = "com.aliucord" + application.showToast(R.string.settings_invalid_package_name) + } + } + + companion object { + private val PACKAGE_REGEX = "^[a-z]\\w*(\\.[a-z]\\w*)+\$" + .toRegex(RegexOption.IGNORE_CASE) + } } diff --git a/app/src/main/kotlin/com/aliucord/manager/util/Throttling.kt b/app/src/main/kotlin/com/aliucord/manager/util/Throttling.kt new file mode 100644 index 0000000..a7dabb7 --- /dev/null +++ b/app/src/main/kotlin/com/aliucord/manager/util/Throttling.kt @@ -0,0 +1,25 @@ +package com.aliucord.manager.util + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +/** + * Constructs a function that executes [destinationFunction] only once per [skipMs]. + */ +inline fun throttle( + skipMs: Long, + coroutineScope: CoroutineScope, + crossinline destinationFunction: suspend () -> Unit +): () -> Unit { + var throttleJob: Job? = null + return { + if (throttleJob?.isCompleted != false) { + throttleJob = coroutineScope.launch { + destinationFunction() + delay(skipMs) + } + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aaa93e7..ce809b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -51,6 +51,7 @@ Package Name Download Version Dynamic color + Invalid package name, reset to com.aliucord System Dark