diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/AboutNavigation.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/AboutNavigation.kt new file mode 100644 index 0000000..ebc527d --- /dev/null +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/AboutNavigation.kt @@ -0,0 +1,40 @@ +package top.fatweb.oxygen.toolbox.navigation + +import androidx.compose.animation.scaleIn +import androidx.compose.animation.slideOutVertically +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import top.fatweb.oxygen.toolbox.ui.about.AboutRoute + +const val ABOUT_ROUTE = "about_route" + +fun NavController.navigateToAbout(navOptions: NavOptions? = null) = + navigate(ABOUT_ROUTE, navOptions) + +fun NavGraphBuilder.aboutScreen( + onBackClick: () -> Unit, + onNavigateToLibraries: () -> Unit +) { + composable( + route = ABOUT_ROUTE, + enterTransition = { + scaleIn() + }, + exitTransition = { + slideOutVertically { it } + }, + popEnterTransition = { + scaleIn() + }, + popExitTransition = { + slideOutVertically { it } + } + ) { + AboutRoute( + onBackClick = onBackClick, + onNavigateToLibraries = onNavigateToLibraries + ) + } +} diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/LibrariesNavigation.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/LibrariesNavigation.kt new file mode 100644 index 0000000..f05aaf2 --- /dev/null +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/LibrariesNavigation.kt @@ -0,0 +1,36 @@ +package top.fatweb.oxygen.toolbox.navigation + +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import top.fatweb.oxygen.toolbox.ui.about.LibrariesRoute + +const val LIBRARIES_ROUTE = "libraries_route" + +fun NavController.navigateToLibraries(navOptions: NavOptions? = null) = + navigate(LIBRARIES_ROUTE, navOptions) + +fun NavGraphBuilder.librariesScreen( + onBackClick: () -> Unit +) { + composable( + route = LIBRARIES_ROUTE, + enterTransition = { + scaleIn() + }, + exitTransition = { + scaleOut() + }, + popEnterTransition = { + scaleIn() + }, + popExitTransition = { + scaleOut() + } + ) { + LibrariesRoute(onBackClick = onBackClick) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/OxygenNavHost.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/OxygenNavHost.kt index 044ed27..70e39f4 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/OxygenNavHost.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/OxygenNavHost.kt @@ -21,6 +21,13 @@ fun OxygenNavHost( searchScreen( onBackClick = navController::popBackStack ) + aboutScreen( + onBackClick = navController::popBackStack, + onNavigateToLibraries = navController::navigateToLibraries + ) + librariesScreen( + onBackClick = navController::popBackStack + ) toolsScreen( ) diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/StarNavigation.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/StarNavigation.kt index ce8c316..017a7b1 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/StarNavigation.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/navigation/StarNavigation.kt @@ -4,6 +4,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import top.fatweb.oxygen.toolbox.ui.star.StarRoute const val STAR_ROUTE = "star_route" @@ -13,6 +14,6 @@ fun NavGraphBuilder.starScreen() { composable( route = STAR_ROUTE ) { - + StarRoute() } } \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenApp.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenApp.kt index 4d36491..3eee50c 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenApp.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenApp.kt @@ -1,5 +1,7 @@ package top.fatweb.oxygen.toolbox.ui +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.slideInVertically import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets @@ -74,7 +76,7 @@ fun OxygenApp(appState: OxygenAppState) { val isOffline by appState.isOffline.collectAsStateWithLifecycle() - val noConnectMessage = stringResource(R.string.no_connect) + val noConnectMessage = stringResource(R.string.core_no_connect) val topAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val bottomAppBarScrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior() @@ -90,7 +92,9 @@ fun OxygenApp(appState: OxygenAppState) { if (showSettingsDialog) { SettingsDialog( - onDismiss = { showSettingsDialog = false } + onDismiss = { showSettingsDialog = false }, + onNavigateToLibraries = appState::navigateToLibraries, + onNavigateToAbout = appState::navigateToAbout ) } @@ -103,7 +107,9 @@ fun OxygenApp(appState: OxygenAppState) { contentWindowInsets = WindowInsets(0, 0, 0, 0), snackbarHost = { SnackbarHost(snackbarHostState) }, bottomBar = { - if (appState.shouldShowBottomBar && destination != null) { + AnimatedVisibility( + visible = appState.shouldShowBottomBar && destination != null, + enter = slideInVertically { it }) { BottomAppBar( scrollBehavior = bottomAppBarScrollBehavior ) { @@ -127,7 +133,7 @@ fun OxygenApp(appState: OxygenAppState) { ) ) ) { - if (appState.shouldShowNavRail && destination != null) { + AnimatedVisibility(appState.shouldShowNavRail && destination != null) { OxygenNavRail( modifier = Modifier.safeDrawingPadding(), destinations = appState.topLevelDestinations, diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenAppState.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenAppState.kt index a664a04..9fb564f 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenAppState.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/OxygenAppState.kt @@ -23,6 +23,8 @@ import top.fatweb.oxygen.toolbox.monitor.TimeZoneMonitor import top.fatweb.oxygen.toolbox.navigation.STAR_ROUTE import top.fatweb.oxygen.toolbox.navigation.TOOLS_ROUTE import top.fatweb.oxygen.toolbox.navigation.TopLevelDestination +import top.fatweb.oxygen.toolbox.navigation.navigateToAbout +import top.fatweb.oxygen.toolbox.navigation.navigateToLibraries import top.fatweb.oxygen.toolbox.navigation.navigateToSearch import top.fatweb.oxygen.toolbox.navigation.navigateToStar import top.fatweb.oxygen.toolbox.navigation.navigateToTools @@ -56,7 +58,7 @@ fun rememberOxygenAppState( @Stable class OxygenAppState( - val windowSizeClass: WindowSizeClass, + private val windowSizeClass: WindowSizeClass, networkMonitor: NetworkMonitor, timeZoneMonitor: TimeZoneMonitor, coroutineScope: CoroutineScope, @@ -114,4 +116,8 @@ class OxygenAppState( } fun navigateToSearch() = navController.navigateToSearch() + + fun navigateToLibraries() = navController.navigateToLibraries() + + fun navigateToAbout() = navController.navigateToAbout() } \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/AboutScreen.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/AboutScreen.kt new file mode 100644 index 0000000..fe7c2d0 --- /dev/null +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/AboutScreen.kt @@ -0,0 +1,162 @@ +package top.fatweb.oxygen.toolbox.ui.about + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import top.fatweb.oxygen.toolbox.R +import top.fatweb.oxygen.toolbox.icon.OxygenIcons +import top.fatweb.oxygen.toolbox.ui.component.ApiLevelPreviews +import top.fatweb.oxygen.toolbox.ui.component.OxygenPreviews +import top.fatweb.oxygen.toolbox.ui.component.ThemePreviews +import top.fatweb.oxygen.toolbox.ui.theme.OxygenTheme +import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils + +@Composable +internal fun AboutRoute( + modifier: Modifier = Modifier, onBackClick: () -> Unit, onNavigateToLibraries: () -> Unit +) { + AboutScreen( + modifier = modifier, + onBackClick = onBackClick, + onNavigateToLibraries = onNavigateToLibraries + ) +} + +@Composable +internal fun AboutScreen( + modifier: Modifier = Modifier, onBackClick: () -> Unit, onNavigateToLibraries: () -> Unit +) { + Column( + modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally + ) { + AboutToolBar( + onBackClick = onBackClick + ) + Spacer( + modifier = Modifier.height(64.dp) + ) + AboutAppInfo() + Spacer( + modifier = Modifier.weight(1f) + ) + AboutFooter( + onNavigateToLibraries = onNavigateToLibraries + ) + } +} + +@Composable +private fun AboutToolBar( + modifier: Modifier = Modifier, onBackClick: () -> Unit +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = onBackClick) { + Icon( + imageVector = OxygenIcons.ArrowBack, + contentDescription = stringResource(R.string.core_back) + ) + } + } +} + +@Composable +private fun AboutAppInfo( + modifier: Modifier = Modifier +) { + Column( + modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + imageVector = ImageVector.vectorResource(R.drawable.ic_oxygen), + contentDescription = stringResource(R.string.app_full_name) + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + text = stringResource(R.string.app_name) + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.outline, + text = stringResource(R.string.app_description) + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.outline, + text = "${ResourcesUtils.getAppVersionName(LocalContext.current)}(${ + ResourcesUtils.getAppVersionCode( + LocalContext.current + ) + })" + ) + } +} + +@Composable +private fun AboutFooter( + modifier: Modifier = Modifier, onNavigateToLibraries: () -> Unit +) { + Row( + modifier = modifier.padding(32.dp) + ) { + TextButton( + onClick = onNavigateToLibraries + ) { + Text( + color = MaterialTheme.colorScheme.primary, + text = stringResource(R.string.feature_settings_open_source_license) + ) + } + } +} + +@ThemePreviews +@Composable +fun AboutToolBarPreview() { + OxygenTheme { + AboutToolBar(onBackClick = {}) + } +} + +@ApiLevelPreviews +@Composable +fun AboutAppInfoPreview() { + OxygenTheme { + AboutAppInfo() + } +} + +@OxygenPreviews +@Composable +fun AboutScreenPreview() { + OxygenTheme { + AboutScreen(onBackClick = {}, onNavigateToLibraries = {}) + } +} diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/LibrariesScreen.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/LibrariesScreen.kt new file mode 100644 index 0000000..36cc567 --- /dev/null +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/about/LibrariesScreen.kt @@ -0,0 +1,61 @@ +package top.fatweb.oxygen.toolbox.ui.about + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import top.fatweb.oxygen.toolbox.R +import top.fatweb.oxygen.toolbox.icon.OxygenIcons + +@Composable +internal fun LibrariesRoute( + modifier: Modifier = Modifier, + onBackClick: () -> Unit +) { + LibrariesScreen( + modifier = modifier, + onBackClick = onBackClick + ) +} + +@Composable +internal fun LibrariesScreen( + modifier: Modifier = Modifier, + onBackClick: () -> Unit +) { + Column( + modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally + ) { + LibrariesToolBar( + onBackClick = onBackClick + ) + Spacer(modifier = Modifier.weight(1f)) + } +} + +@Composable +private fun LibrariesToolBar( + modifier: Modifier = Modifier, onBackClick: () -> Unit +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = onBackClick) { + Icon( + imageVector = OxygenIcons.ArrowBack, + contentDescription = stringResource(R.string.core_back) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/component/Background.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/component/Background.kt index 96d6c30..df25470 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/component/Background.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/component/Background.kt @@ -92,10 +92,20 @@ fun OxygenGradientBackground( } } -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, name = "Light theme") -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, name = "Dark theme") + +@Preview(name = "Light theme", group = "ThemePreviews", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark theme", group = "ThemePreviews", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview(name = "Api 21", group = "ApiLevelPreviews", apiLevel = 21) +annotation class OxygenPreviews + +@Preview(name = "Light theme", group = "ThemePreviews", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark theme", group = "ThemePreviews", uiMode = Configuration.UI_MODE_NIGHT_YES) annotation class ThemePreviews +@Preview(name = "Api 21", group = "ApiLevelPreviews", apiLevel = 21) +@Preview(name = "Api Default", group = "ApiLevelPreviews") +annotation class ApiLevelPreviews + @ThemePreviews @Composable fun BackgroundDefault() { diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/settings/SettingsDialog.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/settings/SettingsDialog.kt index 92c9f54..b84a45b 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/settings/SettingsDialog.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/settings/SettingsDialog.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.selection.selectableGroup import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text @@ -24,6 +25,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role @@ -31,6 +33,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import top.fatweb.oxygen.toolbox.R +import top.fatweb.oxygen.toolbox.icon.OxygenIcons import top.fatweb.oxygen.toolbox.model.userdata.DarkThemeConfig import top.fatweb.oxygen.toolbox.model.userdata.LanguageConfig import top.fatweb.oxygen.toolbox.model.userdata.LaunchPageConfig @@ -43,8 +46,10 @@ import top.fatweb.oxygen.toolbox.ui.theme.supportsDynamicTheming @Composable fun SettingsDialog( modifier: Modifier = Modifier, + viewModel: SettingsViewModel = hiltViewModel(), onDismiss: () -> Unit, - viewModel: SettingsViewModel = hiltViewModel() + onNavigateToLibraries: () -> Unit, + onNavigateToAbout: () -> Unit ) { val settingsUiState by viewModel.settingsUiState.collectAsStateWithLifecycle() SettingsDialog( @@ -55,7 +60,9 @@ fun SettingsDialog( onChangeLaunchPageConfig = viewModel::updateLaunchPageConfig, onchangeThemeBrandConfig = viewModel::updateThemeBrandConfig, onChangeDarkThemeConfig = viewModel::updateDarkThemeConfig, - onchangeUseDynamicColor = viewModel::updateUseDynamicColor + onchangeUseDynamicColor = viewModel::updateUseDynamicColor, + onNavigateToLibraries = onNavigateToLibraries, + onNavigateToAbout = onNavigateToAbout ) } @@ -69,7 +76,9 @@ fun SettingsDialog( onChangeLaunchPageConfig: (launchPageConfig: LaunchPageConfig) -> Unit, onchangeThemeBrandConfig: (themeBrandConfig: ThemeBrandConfig) -> Unit, onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit, - onchangeUseDynamicColor: (useDynamicColor: Boolean) -> Unit + onchangeUseDynamicColor: (useDynamicColor: Boolean) -> Unit, + onNavigateToLibraries: () -> Unit, + onNavigateToAbout: () -> Unit ) { val configuration = LocalConfiguration.current @@ -101,11 +110,14 @@ fun SettingsDialog( SettingsPanel( settings = settingsUiState.settings, supportDynamicColor = supportDynamicColor, + onDismiss = onDismiss, onChangeLanguageConfig = onChangeLanguageConfig, onChangeLaunchPageConfig = onChangeLaunchPageConfig, onchangeThemeBrandConfig = onchangeThemeBrandConfig, onChangeDarkThemeConfig = onChangeDarkThemeConfig, - onchangeUseDynamicColor = onchangeUseDynamicColor + onchangeUseDynamicColor = onchangeUseDynamicColor, + onNavigateToLibraries = onNavigateToLibraries, + onNavigateToAbout = onNavigateToAbout ) } } @@ -117,7 +129,7 @@ fun SettingsDialog( modifier = Modifier .padding(horizontal = 8.dp) .clickable { onDismiss() }, - text = stringResource(R.string.feature_settings_dismiss_dialog_button_text), + text = stringResource(R.string.core_ok), style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.primary ) @@ -129,27 +141,30 @@ fun SettingsDialog( private fun ColumnScope.SettingsPanel( settings: UserData, supportDynamicColor: Boolean, + onDismiss: () -> Unit, onChangeLanguageConfig: (languageConfig: LanguageConfig) -> Unit, onChangeLaunchPageConfig: (launchPageConfig: LaunchPageConfig) -> Unit, onchangeThemeBrandConfig: (themeBrandConfig: ThemeBrandConfig) -> Unit, onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit, - onchangeUseDynamicColor: (useDynamicColor: Boolean) -> Unit + onchangeUseDynamicColor: (useDynamicColor: Boolean) -> Unit, + onNavigateToLibraries: () -> Unit, + onNavigateToAbout: () -> Unit ) { SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_language)) Column( modifier = Modifier.selectableGroup() ) { - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_language_system_default), selected = settings.languageConfig == LanguageConfig.FOLLOW_SYSTEM, onClick = { onChangeLanguageConfig(LanguageConfig.FOLLOW_SYSTEM) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_language_chinese), selected = settings.languageConfig == LanguageConfig.CHINESE, onClick = { onChangeLanguageConfig(LanguageConfig.CHINESE) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_language_english), selected = settings.languageConfig == LanguageConfig.ENGLISH, onClick = { onChangeLanguageConfig(LanguageConfig.ENGLISH) } @@ -159,12 +174,12 @@ private fun ColumnScope.SettingsPanel( Column( modifier = Modifier.selectableGroup() ) { - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_launch_page_tools), selected = settings.launchPageConfig == LaunchPageConfig.TOOLS, onClick = { onChangeLaunchPageConfig(LaunchPageConfig.TOOLS) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_launch_page_star), selected = settings.launchPageConfig == LaunchPageConfig.STAR, onClick = { onChangeLaunchPageConfig(LaunchPageConfig.STAR) } @@ -174,12 +189,12 @@ private fun ColumnScope.SettingsPanel( Column( modifier = Modifier.selectableGroup() ) { - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_theme_brand_default), selected = settings.themeBrandConfig == ThemeBrandConfig.DEFAULT, onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.DEFAULT) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_theme_brand_android), selected = settings.themeBrandConfig == ThemeBrandConfig.ANDROID, onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.ANDROID) } @@ -190,12 +205,12 @@ private fun ColumnScope.SettingsPanel( modifier = Modifier.selectableGroup() ) { SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_dynamic_color)) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_dynamic_color_enable), selected = settings.useDynamicColor, onClick = { onchangeUseDynamicColor(true) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_dynamic_color_disable), selected = !settings.useDynamicColor, onClick = { onchangeUseDynamicColor(false) } @@ -206,22 +221,43 @@ private fun ColumnScope.SettingsPanel( Column( modifier = Modifier.selectableGroup() ) { - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_dark_mode_system_default), selected = settings.darkThemeConfig == DarkThemeConfig.FOLLOW_SYSTEM, onClick = { onChangeDarkThemeConfig(DarkThemeConfig.FOLLOW_SYSTEM) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_dark_mode_light), selected = settings.darkThemeConfig == DarkThemeConfig.LIGHT, onClick = { onChangeDarkThemeConfig(DarkThemeConfig.LIGHT) } ) - SettingsDialogThemeChooserRow( + SettingsDialogChooserRow( text = stringResource(R.string.feature_settings_dark_mode_dark), selected = settings.darkThemeConfig == DarkThemeConfig.DARK, onClick = { onChangeDarkThemeConfig(DarkThemeConfig.DARK) } ) } + SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_more)) + Column( + modifier = Modifier.selectableGroup() + ) { + SettingsDialogClickerRow( + icon = OxygenIcons.Code, + text = stringResource(R.string.feature_settings_open_source_license), + onClick = { + onNavigateToLibraries() + onDismiss() + } + ) + SettingsDialogClickerRow( + icon = OxygenIcons.Info, + text = stringResource(R.string.feature_settings_more_about), + onClick = { + onNavigateToAbout() + onDismiss() + } + ) + } } @Composable @@ -234,7 +270,7 @@ private fun SettingsDialogSectionTitle(text: String) { } @Composable -private fun SettingsDialogThemeChooserRow( +private fun SettingsDialogChooserRow( text: String, selected: Boolean, onClick: () -> Unit @@ -259,6 +295,27 @@ private fun SettingsDialogThemeChooserRow( } } +@Composable +private fun SettingsDialogClickerRow( + icon: ImageVector? = null, + text: String, + onClick: () -> Unit +) { + Row( + modifier = Modifier + .fillMaxSize() + .clickable( + onClick = onClick + ) + .padding(12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(imageVector = icon ?: OxygenIcons.Reorder, contentDescription = null) + Spacer(modifier = Modifier.width(8.dp)) + Text(text) + } +} + @ThemePreviews @Composable private fun SettingsDialogLoadingPreview() { @@ -270,7 +327,9 @@ private fun SettingsDialogLoadingPreview() { onChangeLaunchPageConfig = {}, onchangeThemeBrandConfig = {}, onChangeDarkThemeConfig = {}, - onchangeUseDynamicColor = {} + onchangeUseDynamicColor = {}, + onNavigateToLibraries = {}, + onNavigateToAbout = {} ) } } @@ -294,7 +353,9 @@ private fun SettingDialogPreview() { onChangeLaunchPageConfig = {}, onchangeThemeBrandConfig = {}, onChangeDarkThemeConfig = {}, - onchangeUseDynamicColor = {} + onchangeUseDynamicColor = {}, + onNavigateToLibraries = {}, + onNavigateToAbout = {} ) } } \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/star/StarScreen.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/star/StarScreen.kt index 7d220a8..e422ab6 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/star/StarScreen.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/star/StarScreen.kt @@ -1,3 +1,20 @@ package top.fatweb.oxygen.toolbox.ui.star -class StarScreen \ No newline at end of file +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +internal fun StarRoute( + modifier: Modifier = Modifier +) { + StarScreen( + modifier = modifier + ) +} + +@Composable +internal fun StarScreen( + modifier: Modifier = Modifier +) { + +} \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/tool/ToolsScreen.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/tool/ToolsScreen.kt index bb8005f..f2657d0 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/tool/ToolsScreen.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/tool/ToolsScreen.kt @@ -22,9 +22,6 @@ import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridS import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -41,7 +38,7 @@ import top.fatweb.oxygen.toolbox.ui.component.scrollbar.rememberDraggableScrolle import top.fatweb.oxygen.toolbox.ui.component.scrollbar.scrollbarState @Composable -fun ToolsRoute( +internal fun ToolsRoute( modifier: Modifier = Modifier, viewModel: ToolsScreenViewModel = hiltViewModel() ) { @@ -54,7 +51,7 @@ fun ToolsRoute( } @Composable -fun ToolsScreen( +internal fun ToolsScreen( modifier: Modifier = Modifier, toolsScreenUiState: ToolsScreenUiState ) { @@ -67,8 +64,6 @@ fun ToolsScreen( val state = rememberLazyStaggeredGridState() val scrollbarState = state.scrollbarState(itemsAvailable = itemsAvailable) - var isExpanded by remember { mutableStateOf(mapOf()) } - Box( modifier.fillMaxSize() ) { diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/util/ResourcesUtils.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/util/ResourcesUtils.kt index ec589fb..a1da58d 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/util/ResourcesUtils.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/ui/util/ResourcesUtils.kt @@ -23,7 +23,7 @@ object ResourcesUtils { fun getAppVersionName(context: Context): String = try { - context.packageManager.getPackageInfo(context.packageName, 0).versionName + context.packageManager.getPackageInfo(context.packageName, 0)?.versionName ?: "Unknown" } catch (e: PackageManager.NameNotFoundException) { "Unknown" } @@ -32,8 +32,8 @@ object ResourcesUtils { fun getAppVersionCode(context: Context): Long = try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) - context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode - else context.packageManager.getPackageInfo(context.packageName, 0).versionCode.toLong() + context.packageManager.getPackageInfo(context.packageName, 0)?.longVersionCode ?: -1 + else context.packageManager.getPackageInfo(context.packageName, 0)?.versionCode?.toLong() ?: -1 } catch (e: PackageManager.NameNotFoundException) { -1 } diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index c8fc2e8..593d709 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1,7 +1,11 @@ - OxygenToolbox - ⚠️ 无法连接至互联网 + 氧工具 + 氧工具 + All in One + 完成 + 返回 + ⚠️ 无法连接至互联网 工具 收藏 设置 @@ -21,7 +25,9 @@ 动态颜色 启用 禁用 + 更多 + 开源许可 + 关于 更多 搜索 - 完成 \ 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 a0822b7..93bc787 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,10 @@ - OxygenToolbox - ⚠️ Unable to connect to the internet + Oxygen + Oxygen Toolbox + All in One + OK + Back + ⚠️ Unable to connect to the internet Tools Star Settings @@ -22,7 +26,9 @@ Dynamic Color Enable Disable + More + Open Source License + About More Search - OK \ No newline at end of file