diff --git a/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt b/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt index 6e78ccb..0aeafa4 100644 --- a/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt +++ b/app/src/main/kotlin/com/aliucord/manager/MainActivity.kt @@ -47,6 +47,7 @@ class MainActivity : ComponentActivity() { setContent { ManagerTheme( isDarkTheme = preferences.theme == Theme.DARK || preferences.theme == Theme.SYSTEM && isSystemInDarkTheme(), + isDynamicColor = preferences.dynamicColor ) { val navigator = rememberBackstackNavigator(AppDestination.Home) @@ -65,7 +66,6 @@ class MainActivity : ComponentActivity() { onClickAbout = { navigator.push(AppDestination.About) }, onClickSettings = { navigator.push(AppDestination.Settings) } ) - is AppDestination.Plugins -> PluginsScreen() is AppDestination.Install -> InstallerScreen( onClickBack = navigator::pop, ) diff --git a/app/src/main/kotlin/com/aliucord/manager/domain/manager/PreferencesManager.kt b/app/src/main/kotlin/com/aliucord/manager/domain/manager/PreferencesManager.kt index 1f3c492..deb32cb 100644 --- a/app/src/main/kotlin/com/aliucord/manager/domain/manager/PreferencesManager.kt +++ b/app/src/main/kotlin/com/aliucord/manager/domain/manager/PreferencesManager.kt @@ -7,6 +7,7 @@ import com.aliucord.manager.ui.theme.Theme class PreferencesManager(preferences: SharedPreferences) : BasePreferenceManager(preferences) { var theme by enumPreference("theme", Theme.SYSTEM) + var dynamicColor by booleanPreference("dynamic_color", true) var replaceBg by booleanPreference("replace_bg", true) var devMode by booleanPreference("dev_mode", false) var debuggable by booleanPreference("debuggable", false) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/navigation/AppDestination.kt b/app/src/main/kotlin/com/aliucord/manager/ui/navigation/AppDestination.kt index 0abe16d..6f74b2b 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/navigation/AppDestination.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/navigation/AppDestination.kt @@ -17,9 +17,6 @@ sealed interface AppDestination : Destination { @Parcelize object Home : AppDestination - @Parcelize - object Plugins : AppDestination - @Parcelize object Install : AppDestination 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 edeb9e9..78faa8f 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 @@ -165,7 +165,6 @@ fun HomeScreen( ) { Column( modifier = Modifier - .padding(16.dp) .weight(1f, true) .fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) @@ -173,6 +172,7 @@ fun HomeScreen( val lazyPagingItems = viewModel.commits.collectAsLazyPagingItems() Text( + modifier = Modifier.padding(16.dp, 16.dp, 16.dp), text = stringResource(R.string.commits), style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.primary diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screen/PluginsScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screen/PluginsScreen.kt index ad7115d..1aaedf0 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screen/PluginsScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screen/PluginsScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource @@ -134,7 +135,20 @@ fun PluginsScreen( } } } else { - Text(stringResource(R.string.no_plugins_installed)) + Box( + modifier = Modifier.fillMaxSize() + ) { + Column( + modifier = Modifier.align(Alignment.Center), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon( + imageVector = Icons.Default.Extension, + contentDescription = null + ) + Text(stringResource(R.string.no_plugins_installed)) + } + } } } } 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 b44c30a..84887c0 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 @@ -9,13 +9,15 @@ import androidx.compose.animation.* import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.NavigateBefore -import androidx.compose.material.icons.filled.Style +import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.aliucord.manager.R @@ -29,9 +31,14 @@ fun SettingsScreen( viewModel: SettingsViewModel = getViewModel(), onClickBack: () -> Unit ) { + val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior( + decayAnimationSpec = rememberSplineBasedDecay(), + state = rememberTopAppBarState() + ) Scaffold( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { - MediumTopAppBar( + LargeTopAppBar( title = { Text(stringResource(R.string.settings)) }, navigationIcon = { IconButton(onClick = onClickBack) { @@ -40,7 +47,8 @@ fun SettingsScreen( contentDescription = stringResource(R.string.back) ) } - } + }, + scrollBehavior = scrollBehavior ) } ) { paddingValues -> @@ -61,10 +69,13 @@ fun SettingsScreen( ) } + GroupHeader(stringResource(R.string.appearance)) + ListItem( modifier = Modifier.clickable(onClick = viewModel::showThemeDialog), headlineText = { Text(stringResource(R.string.theme)) }, supportingText = { Text(stringResource(R.string.theme_setting_description)) }, + leadingContent = { Icon(Icons.Default.Style, null) }, trailingContent = { FilledTonalButton(onClick = viewModel::showThemeDialog) { Text(preferences.theme.displayName) @@ -72,7 +83,21 @@ fun SettingsScreen( } ) - Divider() + SwitchSetting( + checked = preferences.dynamicColor, + title = { Text(stringResource(R.string.dynamic_color)) }, + onCheckedChange = { preferences.dynamicColor = it }, + icon = { Icon(Icons.Default.Palette, null) } + ) + + GroupHeader(stringResource(R.string.advanced)) + + SwitchSetting( + checked = preferences.replaceBg, + title = { Text(stringResource(R.string.replace_bg)) }, + onCheckedChange = { preferences.replaceBg = it }, + icon = { Icon(Icons.Default.AppShortcut, null) } + ) OutlinedTextField( modifier = Modifier @@ -85,16 +110,11 @@ fun SettingsScreen( singleLine = true ) - SwitchSetting( - checked = preferences.replaceBg, - title = { Text(stringResource(R.string.replace_bg)) }, - onCheckedChange = { preferences.replaceBg = it } - ) - SwitchSetting( checked = preferences.devMode, - title = { Text(stringResource(R.string.advanced_options)) }, - onCheckedChange = { preferences.devMode = it } + title = { Text(stringResource(R.string.developer_options)) }, + onCheckedChange = { preferences.devMode = it }, + icon = { Icon(Icons.Default.Code, null) } ) AnimatedVisibility( @@ -130,7 +150,8 @@ fun SettingsScreen( checked = preferences.debuggable, title = { Text(stringResource(R.string.debuggable)) }, description = { Text(stringResource(R.string.debuggable_description)) }, - onCheckedChange = { preferences.debuggable = it } + onCheckedChange = { preferences.debuggable = it }, + icon = { Icon(Icons.Default.BugReport, null) } ) } } @@ -153,11 +174,12 @@ fun SettingsScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable fun SwitchSetting( + enabled: Boolean = true, checked: Boolean, icon: @Composable (() -> Unit)? = null, title: @Composable () -> Unit, description: @Composable (() -> Unit)? = null, - onCheckedChange: (Boolean) -> Unit, + onCheckedChange: (Boolean) -> Unit ) { ListItem( modifier = Modifier.clickable { onCheckedChange(!checked) }, @@ -166,6 +188,7 @@ fun SwitchSetting( supportingText = description, trailingContent = { Switch( + enabled = enabled, checked = checked, onCheckedChange = onCheckedChange ) @@ -224,3 +247,23 @@ fun ThemeDialog( } ) } + +@Composable +fun GroupHeader( + title: String, + color: Color = MaterialTheme.colorScheme.primary +) { + Box( + Modifier + .padding(start = 12.dp) + .fillMaxWidth(), + contentAlignment = Alignment.CenterStart + ) { + Text( + text = title, + color = color, + fontSize = LocalTextStyle.current.fontSize.times(0.95f), + fontWeight = FontWeight.SemiBold + ) + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 40fe31e..c4c94c8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,7 +22,7 @@ Install Reinstall Update - Show advanced options + Developer options Debuggable Enable debuggable flag About @@ -48,4 +48,7 @@ Launch Uninstall Version + Dynamic color + Appearance + Advanced