From fd41e786255f3108e35f21e86c7a7ce5626eb05f Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Wed, 29 Jun 2022 21:33:35 +0200 Subject: [PATCH] Add TextCard component --- .../vimusic/ui/components/themed/TextCard.kt | 110 ++++++++++++++++++ .../vimusic/ui/screens/ArtistScreen.kt | 67 +++-------- .../settings/BackupAndRestoreScreen.kt | 48 ++------ .../screens/settings/OtherSettingsScreen.kt | 6 + 4 files changed, 137 insertions(+), 94 deletions(-) create mode 100644 app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/TextCard.kt diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/TextCard.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/TextCard.kt new file mode 100644 index 0000000..5097910 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/TextCard.kt @@ -0,0 +1,110 @@ +package it.vfsfitvnm.vimusic.ui.components.themed + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.BasicText +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette +import it.vfsfitvnm.vimusic.ui.styling.LocalTypography +import it.vfsfitvnm.vimusic.utils.align +import it.vfsfitvnm.vimusic.utils.secondary +import it.vfsfitvnm.vimusic.utils.semiBold + + +@Composable +fun TextCard( + modifier: Modifier = Modifier, + @DrawableRes icon: Int? = null, + iconColor: ColorFilter? = null, + onClick: (() -> Unit)? = null, + content: @Composable TextCardScope.() -> Unit, +) { + val colorPalette = LocalColorPalette.current + + Column( + modifier = modifier + .padding(horizontal = 16.dp, vertical = 16.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = true), + enabled = onClick != null, + onClick = onClick ?: {} + ) + .background(colorPalette.lightBackground) + .padding(horizontal = 16.dp, vertical = 16.dp) + ) { + icon?.let { + Image( + painter = painterResource(icon), + contentDescription = null, + colorFilter = iconColor ?: ColorFilter.tint(colorPalette.red), + modifier = Modifier + .padding(bottom = 16.dp) + .size(24.dp) + ) + } + + (icon?.let { IconTextCardScopeImpl } ?: TextCardScopeImpl).content() + } +} + +interface TextCardScope { + @Composable + fun Title(text: String) + + @Composable + fun Text(text: String) +} + +private object TextCardScopeImpl : TextCardScope { + @Composable + override fun Title(text: String) { + BasicText( + text = text, + style = LocalTypography.current.xxs.semiBold, + ) + } + + @Composable + override fun Text(text: String) { + BasicText( + text = text, + style = LocalTypography.current.xxs.secondary.align(TextAlign.Justify), + ) + } +} + +private object IconTextCardScopeImpl : TextCardScope { + @Composable + override fun Title(text: String) { + BasicText( + text = text, + style = LocalTypography.current.xxs.semiBold, + modifier = Modifier + .padding(horizontal = 16.dp) + ) + } + + @Composable + override fun Text(text: String) { + BasicText( + text = text, + style = LocalTypography.current.xxs.secondary, + modifier = Modifier + .padding(horizontal = 16.dp) + ) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/ArtistScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/ArtistScreen.kt index c782bac..966b1d0 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/ArtistScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/ArtistScreen.kt @@ -4,14 +4,12 @@ import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.BasicText -import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -24,7 +22,6 @@ import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import coil.compose.AsyncImage @@ -38,6 +35,7 @@ import it.vfsfitvnm.vimusic.models.DetailedSong import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu +import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.ui.styling.LocalTypography @@ -154,7 +152,11 @@ fun ArtistScreen( .clickable { query { runBlocking { - Database.artist(browseId).first()?.copy(shufflePlaylistId = null)?.let(Database::update) + Database + .artist(browseId) + .first() + ?.copy(shufflePlaylistId = null) + ?.let(Database::update) } } } @@ -292,22 +294,9 @@ fun ArtistScreen( artistResult?.getOrNull()?.info?.let { description -> item { - Column( - modifier = Modifier - .padding(top = 32.dp) - .padding(horizontal = 16.dp, vertical = 16.dp) - .background(colorPalette.lightBackground) - .padding(horizontal = 16.dp, vertical = 16.dp) - ) { - BasicText( - text = "Information", - style = typography.xxs.semiBold - ) - - BasicText( - text = description, - style = typography.xxs.secondary.align(TextAlign.Justify) - ) + TextCard { + Title(text = "Information") + Text(text = description) } } } @@ -321,7 +310,6 @@ private fun LoadingOrError( errorMessage: String? = null, onRetry: (() -> Unit)? = null ) { - val typography = LocalTypography.current val colorPalette = LocalColorPalette.current Box { @@ -353,41 +341,14 @@ private fun LoadingOrError( } errorMessage?.let { - Column( + TextCard( + icon = R.drawable.alert_circle, + onClick = onRetry, modifier = Modifier .align(Alignment.Center) - .padding(horizontal = 16.dp, vertical = 16.dp) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = true), - enabled = onRetry != null, - onClick = onRetry ?: {} - ) - .background(colorPalette.lightBackground) - .padding(horizontal = 16.dp, vertical = 16.dp) ) { - Image( - painter = painterResource(R.drawable.alert_circle), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.red), - modifier = Modifier - .padding(bottom = 16.dp) - .size(24.dp) - ) - - BasicText( - text = onRetry?.let { "Tap to retry" } ?: "Error", - style = typography.xxs.semiBold, - modifier = Modifier - .padding(horizontal = 16.dp) - ) - - BasicText( - text = "An error has occurred:\n$errorMessage", - style = typography.xxs.secondary, - modifier = Modifier - .padding(horizontal = 16.dp) - ) + Title(text = onRetry?.let { "Tap to retry" } ?: "Error") + Text(text = "An error has occurred:\n$errorMessage") } } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/BackupAndRestoreScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/BackupAndRestoreScreen.kt index de18682..8ceeeb4 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/BackupAndRestoreScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/BackupAndRestoreScreen.kt @@ -25,6 +25,7 @@ import it.vfsfitvnm.vimusic.* import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog +import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen import it.vfsfitvnm.vimusic.ui.screens.PlaylistOrAlbumScreen import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute @@ -194,7 +195,6 @@ fun BackupAndRestoreScreen() { ) } - Column( verticalArrangement = Arrangement.spacedBy(8.dp), horizontalAlignment = Alignment.CenterHorizontally, @@ -231,53 +231,19 @@ fun BackupAndRestoreScreen() { } } - Column( - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 16.dp) - .background(colorPalette.lightBackground) - .padding(horizontal = 16.dp, vertical = 16.dp) + TextCard( + icon = R.drawable.alert_circle, ) { - Image( - painter = painterResource(R.drawable.alert_circle), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.red), - modifier = Modifier - .padding(bottom = 16.dp) - .size(24.dp) - ) -// - BasicText( - text = "Backup", - style = typography.xxs.semiBold, - modifier = Modifier - .padding(horizontal = 16.dp) - ) - - BasicText( - text = "The backup consists in exporting the application database to your device storage.\nThis means playlists, song history, favorites songs will exported.\nThis operation excludes personal preferences such as the theme mode and everything you can set in the Settings page.", - style = typography.xxs.secondary, - modifier = Modifier - .padding(horizontal = 16.dp) - ) + Title(text = "Backup") + Text(text = "The backup consists in exporting the application database to your device storage.\nThis means playlists, song history, favorites songs will exported.\nThis operation excludes personal preferences such as the theme mode and everything you can set in the Settings page.") Spacer( modifier = Modifier .height(32.dp) ) - BasicText( - text = "Restore", - style = typography.xxs.semiBold, - modifier = Modifier - .padding(horizontal = 16.dp) - ) - - BasicText( - text = "The restore replaces the existing application database with the selected - previously exported - one.\nThis means every currently existing data will be wiped: THE TWO DATABASES WON'T BE MERGED.\nIt is recommended to restore the database immediately after the application is installed on a new device.", - style = typography.xxs.secondary, - modifier = Modifier - .padding(horizontal = 16.dp) - ) + Title(text = "Restore") + Text(text = "The restore replaces the existing application database with the selected - previously exported - one.\nThis means every currently existing data will be wiped: THE TWO DATABASES WON'T BE MERGED.\nIt is recommended to restore the database immediately after the application is installed on a new device.") } } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherSettingsScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherSettingsScreen.kt index 73cdc63..57fd3b5 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherSettingsScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherSettingsScreen.kt @@ -19,6 +19,7 @@ import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.ui.components.SeekBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar +import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.screens.* import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.ui.styling.LocalTypography @@ -224,6 +225,11 @@ fun OtherSettingsScreen() { text = "${Formatter.formatShortFileSize(context, diskCacheSize)} (${diskCacheSize * 100 / preferences.exoPlayerDiskCacheMaxSizeBytes.coerceAtLeast(1)}%)", ) } + + TextCard(icon = R.drawable.alert_circle) { + Title(text = "Cache strategy") + Text(text = "The cache follows the LRU (Least Recently Used) strategy: when it runs out of space, the resources that haven't been accessed for the longest time are cleared to accommodate the new resource.") + } } } }