diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/SettingsScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/SettingsScreen.kt index 227d2df..08995fb 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/SettingsScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/SettingsScreen.kt @@ -1,25 +1,35 @@ package it.vfsfitvnm.vimusic.ui.screens +import androidx.annotation.DrawableRes +import androidx.compose.animation.AnimatedContentScope import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.with import androidx.compose.foundation.* import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.BasicText import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import it.vfsfitvnm.route.Route0 import it.vfsfitvnm.route.RouteHandler +import it.vfsfitvnm.route.fastFade import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.themed.EnumValueSelectorDialog +import it.vfsfitvnm.vimusic.ui.screens.settings.AppearanceScreen +import it.vfsfitvnm.vimusic.ui.screens.settings.BackupAndRestoreScreen +import it.vfsfitvnm.vimusic.ui.screens.settings.rememberAppearanceRoute +import it.vfsfitvnm.vimusic.ui.screens.settings.rememberBackupAndRestoreRoute import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.ui.styling.LocalTypography -import it.vfsfitvnm.vimusic.utils.LocalPreferences +import it.vfsfitvnm.vimusic.utils.medium import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.vimusic.utils.semiBold @@ -28,10 +38,26 @@ import it.vfsfitvnm.vimusic.utils.semiBold fun SettingsScreen() { val albumRoute = rememberPlaylistOrAlbumRoute() val artistRoute = rememberArtistRoute() + val appearanceRoute = rememberAppearanceRoute() val scrollState = rememberScrollState() - RouteHandler(listenToGlobalEmitter = true) { + RouteHandler( + listenToGlobalEmitter = true, + transitionSpec = { + when (targetState.route) { + appearanceRoute -> + slideIntoContainer(AnimatedContentScope.SlideDirection.Left) with + slideOutOfContainer(AnimatedContentScope.SlideDirection.Left) + else -> when (initialState.route) { + appearanceRoute -> + slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with + slideOutOfContainer(AnimatedContentScope.SlideDirection.Right) + else -> fastFade + } + } + } + ) { albumRoute { browseId -> PlaylistOrAlbumScreen( browseId = browseId ?: error("browseId cannot be null") @@ -44,17 +70,20 @@ fun SettingsScreen() { ) } + appearanceRoute { + AppearanceScreen() + } + host { val colorPalette = LocalColorPalette.current val typography = LocalTypography.current - val preferences = LocalPreferences.current Column( modifier = Modifier - .padding(bottom = 72.dp) .background(colorPalette.background) .fillMaxSize() .verticalScroll(scrollState) + .padding(bottom = 72.dp) ) { TopAppBar( modifier = Modifier @@ -82,43 +111,66 @@ fun SettingsScreen() { ) } - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .background( - color = colorPalette.lightBackground, - shape = RoundedCornerShape(8.dp) - ) - .padding(vertical = 8.dp) - .fillMaxWidth() + @Composable + fun Entry( + @DrawableRes icon: Int, + color: Color, + title: String, + description: String, + route: Route0 ) { - Image( - painter = painterResource(R.drawable.contrast), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.text), + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .size(20.dp) - ) + .clickable( + indication = rememberRipple(bounded = true), + interactionSource = remember { MutableInteractionSource() }, + onClick = { + route() + } + ) + .padding(horizontal = 16.dp, vertical = 12.dp) + .fillMaxWidth() + ) { + Box( + modifier = Modifier + .background(color = color, shape = CircleShape) + .size(36.dp) + ) { + Image( + painter = painterResource(icon), + contentDescription = null, + colorFilter = ColorFilter.tint(colorPalette.background), + modifier = Modifier + .align(Alignment.Center) + .size(18.dp) + ) + } - BasicText( - text = "Appearance", - style = typography.m.semiBold, - modifier = Modifier - ) + Column { + BasicText( + text = title, + style = typography.s.semiBold, + modifier = Modifier + ) + + BasicText( + text = description, + style = typography.xs.secondary.medium, + maxLines = 1, + modifier = Modifier + ) + } + } } - EnumValueSelectorEntry( - title = "Theme mode", - selectedValue = preferences.colorPaletteMode, - onValueSelected = preferences.onColorPaletteModeChange - ) - - EnumValueSelectorEntry( - title = "Thumbnail roundness", - selectedValue = preferences.thumbnailRoundness, - onValueSelected = preferences.onThumbnailRoundnessChange + Entry( + color = colorPalette.blue, + icon = R.drawable.color_palette, + title = "Appearance", + description = "Change the colors and shapes of the app", + route = appearanceRoute, ) } } @@ -126,7 +178,7 @@ fun SettingsScreen() { } @Composable -private inline fun >EnumValueSelectorEntry( +inline fun >EnumValueSelectorEntry( title: String, selectedValue: T, crossinline onValueSelected: (T) -> Unit, @@ -158,7 +210,8 @@ private inline fun >EnumValueSelectorEntry( interactionSource = remember { MutableInteractionSource() }, onClick = { isShowingDialog = true } ) - .padding(horizontal = 32.dp, vertical = 8.dp) + .padding(start = 24.dp) + .padding(horizontal = 32.dp, vertical = 16.dp) .fillMaxWidth() ) { BasicText( diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceScreen.kt new file mode 100644 index 0000000..efab4f9 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceScreen.kt @@ -0,0 +1,94 @@ +package it.vfsfitvnm.vimusic.ui.screens.settings + +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.foundation.* +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.BasicText +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import it.vfsfitvnm.route.RouteHandler +import it.vfsfitvnm.vimusic.R +import it.vfsfitvnm.vimusic.ui.components.TopAppBar +import it.vfsfitvnm.vimusic.ui.screens.* +import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette +import it.vfsfitvnm.vimusic.ui.styling.LocalTypography +import it.vfsfitvnm.vimusic.utils.LocalPreferences +import it.vfsfitvnm.vimusic.utils.semiBold + +@ExperimentalAnimationApi +@Composable +fun AppearanceScreen() { + val albumRoute = rememberPlaylistOrAlbumRoute() + val artistRoute = rememberArtistRoute() + + val scrollState = rememberScrollState() + + RouteHandler(listenToGlobalEmitter = true) { + albumRoute { browseId -> + PlaylistOrAlbumScreen( + browseId = browseId ?: error("browseId cannot be null") + ) + } + + artistRoute { browseId -> + ArtistScreen( + browseId = browseId ?: error("browseId cannot be null") + ) + } + + host { + val colorPalette = LocalColorPalette.current + val typography = LocalTypography.current + val preferences = LocalPreferences.current + + Column( + modifier = Modifier + .background(colorPalette.background) + .fillMaxSize() + .verticalScroll(scrollState) + .padding(bottom = 72.dp) + ) { + TopAppBar( + modifier = Modifier + .height(52.dp) + ) { + Image( + painter = painterResource(R.drawable.chevron_back), + contentDescription = null, + colorFilter = ColorFilter.tint(colorPalette.text), + modifier = Modifier + .clickable(onClick = pop) + .padding(horizontal = 16.dp, vertical = 8.dp) + .size(24.dp) + ) + + BasicText( + text = "Appearance", + style = typography.m.semiBold + ) + + Spacer( + modifier = Modifier + .padding(horizontal = 16.dp, vertical = 8.dp) + .size(24.dp) + ) + } + + EnumValueSelectorEntry( + title = "Theme mode", + selectedValue = preferences.colorPaletteMode, + onValueSelected = preferences.onColorPaletteModeChange + ) + + EnumValueSelectorEntry( + title = "Thumbnail roundness", + selectedValue = preferences.thumbnailRoundness, + onValueSelected = preferences.onThumbnailRoundnessChange + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/routes.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/routes.kt new file mode 100644 index 0000000..d43e8d7 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/routes.kt @@ -0,0 +1,12 @@ +package it.vfsfitvnm.vimusic.ui.screens.settings + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import it.vfsfitvnm.route.Route0 + +@Composable +fun rememberAppearanceRoute(): Route0 { + return remember { + Route0("AppearanceRoute") + } +} diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/styling/ColorPalette.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/styling/ColorPalette.kt index 2031198..990238c 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/styling/ColorPalette.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/styling/ColorPalette.kt @@ -35,10 +35,10 @@ val DarkColorPalette = ColorPalette( lightGray = Color(0xfff8f8f8), gray = Color(0xFFE5E5E5), darkGray = Color(0xFF838383), - blue = Color(0xff4046bf), + blue = Color(0xff507fdd), red = Color(0xffbf4040), green = Color(0xff7fbf40), - orange = Color(0xffe8820e), + orange = Color(0xffe9a033), primaryContainer = Color(0xff4046bf), onPrimaryContainer = Color.White, diff --git a/app/src/main/res/drawable/color_palette.xml b/app/src/main/res/drawable/color_palette.xml new file mode 100644 index 0000000..445a693 --- /dev/null +++ b/app/src/main/res/drawable/color_palette.xml @@ -0,0 +1,9 @@ + + +