Feat(About): Add about page
Add about page, add libraries page framework. Add page switching animation and navigation bar animation.
This commit is contained in:
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,13 @@ fun OxygenNavHost(
|
||||
searchScreen(
|
||||
onBackClick = navController::popBackStack
|
||||
)
|
||||
aboutScreen(
|
||||
onBackClick = navController::popBackStack,
|
||||
onNavigateToLibraries = navController::navigateToLibraries
|
||||
)
|
||||
librariesScreen(
|
||||
onBackClick = navController::popBackStack
|
||||
)
|
||||
toolsScreen(
|
||||
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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 = {})
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,20 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.star
|
||||
|
||||
class StarScreen
|
||||
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
|
||||
) {
|
||||
|
||||
}
|
||||
@@ -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<String, Boolean>()) }
|
||||
|
||||
Box(
|
||||
modifier.fillMaxSize()
|
||||
) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">OxygenToolbox</string>
|
||||
<string name="no_connect">⚠️ 无法连接至互联网</string>
|
||||
<string name="app_name">氧工具</string>
|
||||
<string name="app_full_name">氧工具</string>
|
||||
<string name="app_description">All in One</string>
|
||||
<string name="core_ok">完成</string>
|
||||
<string name="core_back">返回</string>
|
||||
<string name="core_no_connect">⚠️ 无法连接至互联网</string>
|
||||
<string name="feature_tools_title">工具</string>
|
||||
<string name="feature_star_title">收藏</string>
|
||||
<string name="feature_settings_title">设置</string>
|
||||
@@ -21,7 +25,9 @@
|
||||
<string name="feature_settings_dynamic_color">动态颜色</string>
|
||||
<string name="feature_settings_dynamic_color_enable">启用</string>
|
||||
<string name="feature_settings_dynamic_color_disable">禁用</string>
|
||||
<string name="feature_settings_more">更多</string>
|
||||
<string name="feature_settings_open_source_license">开源许可</string>
|
||||
<string name="feature_settings_more_about">关于</string>
|
||||
<string name="feature_settings_top_app_bar_action_icon_description">更多</string>
|
||||
<string name="feature_settings_top_app_bar_navigation_icon_description">搜索</string>
|
||||
<string name="feature_settings_dismiss_dialog_button_text">完成</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,10 @@
|
||||
<resources>
|
||||
<string name="app_name">OxygenToolbox</string>
|
||||
<string name="no_connect">⚠️ Unable to connect to the internet</string>
|
||||
<string name="app_name">Oxygen</string>
|
||||
<string name="app_full_name">Oxygen Toolbox</string>
|
||||
<string name="app_description">All in One</string>
|
||||
<string name="core_ok">OK</string>
|
||||
<string name="core_back">Back</string>
|
||||
<string name="core_no_connect">⚠️ Unable to connect to the internet</string>
|
||||
<string name="feature_tools_title">Tools</string>
|
||||
<string name="feature_star_title">Star</string>
|
||||
<string name="feature_settings_title">Settings</string>
|
||||
@@ -22,7 +26,9 @@
|
||||
<string name="feature_settings_dynamic_color">Dynamic Color</string>
|
||||
<string name="feature_settings_dynamic_color_enable">Enable</string>
|
||||
<string name="feature_settings_dynamic_color_disable">Disable</string>
|
||||
<string name="feature_settings_more">More</string>
|
||||
<string name="feature_settings_open_source_license">Open Source License</string>
|
||||
<string name="feature_settings_more_about">About</string>
|
||||
<string name="feature_settings_top_app_bar_action_icon_description">More</string>
|
||||
<string name="feature_settings_top_app_bar_navigation_icon_description">Search</string>
|
||||
<string name="feature_settings_dismiss_dialog_button_text">OK</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user