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