Tweak settings UI

This commit is contained in:
vfsfitvnm 2022-07-27 22:35:55 +02:00
parent c21a4eddb5
commit 9e8066b588
5 changed files with 75 additions and 125 deletions

View file

@ -15,7 +15,6 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.geometry.center import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.*
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import it.vfsfitvnm.route.* import it.vfsfitvnm.route.*
import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.R
@ -372,50 +371,6 @@ fun SettingsEntry(
} }
} }
@Composable
@NonRestartableComposable
fun DisabledSettingsEntry(
title: String,
text: String,
modifier: Modifier = Modifier,
) {
BaseSettingsEntry(
title = title,
text = text,
modifier = modifier,
titleTextStyle = { disabled },
textStyle = { disabled },
)
}
@Composable
fun BaseSettingsEntry(
title: String,
text: String,
modifier: Modifier = Modifier,
titleTextStyle: @Composable TextStyle.() -> TextStyle = { this },
textStyle: @Composable TextStyle.() -> TextStyle = { this },
) {
val (_, typography) = LocalAppearance.current
Column(
modifier = modifier
.padding(start = 24.dp)
.padding(horizontal = 32.dp, vertical = 16.dp)
.fillMaxWidth()
) {
BasicText(
text = title,
style = typography.xs.semiBold.run { titleTextStyle() },
)
BasicText(
text = text,
style = typography.xs.semiBold.secondary.run { textStyle() }
)
}
}
@Composable @Composable
fun SettingsTitle( fun SettingsTitle(
text: String, text: String,
@ -431,6 +386,39 @@ fun SettingsTitle(
.padding(all = 16.dp) .padding(all = 16.dp)
) )
} }
@Composable
fun SettingsDescription(
text: String,
modifier: Modifier = Modifier,
) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.secondary,
modifier = modifier
.padding(start = 56.dp, end = 24.dp)
.padding(bottom = 16.dp)
)
}
@Composable
fun SettingsGroupDescription(
text: String,
modifier: Modifier = Modifier,
) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.secondary,
modifier = modifier
.padding(start = 56.dp, end = 24.dp)
.padding(vertical = 8.dp)
)
}
@Composable @Composable
fun SettingsEntryGroupText( fun SettingsEntryGroupText(
title: String, title: String,

View file

@ -21,7 +21,7 @@ import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.BuildConfig import it.vfsfitvnm.vimusic.BuildConfig
import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.screens.DisabledSettingsEntry import it.vfsfitvnm.vimusic.ui.screens.SettingsDescription
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle
@ -64,13 +64,20 @@ fun AboutScreen() {
SettingsTitle(text = "About") SettingsTitle(text = "About")
SettingsEntryGroupText(title = "INFO") SettingsDescription(text = "v${BuildConfig.VERSION_NAME}\nby vfsfitvnm")
DisabledSettingsEntry( SettingsEntryGroupText(title = "SOCIAL")
title = "ViMusic",
text = "v${BuildConfig.VERSION_NAME}", SettingsEntry(
title = "GitHub",
text = "View the source code",
onClick = {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic")
}
) )
SettingsEntryGroupText(title = "TROUBLESHOOTING")
SettingsEntry( SettingsEntry(
title = "Report an issue", title = "Report an issue",
text = "You will be redirected to GitHub", text = "You will be redirected to GitHub",
@ -86,16 +93,6 @@ fun AboutScreen() {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic/issues/new?assignees=&labels=enhancement&template=feature_request.yaml") uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic/issues/new?assignees=&labels=enhancement&template=feature_request.yaml")
} }
) )
SettingsEntryGroupText(title = "SOCIAL")
SettingsEntry(
title = "GitHub",
text = "View the source code",
onClick = {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic")
}
)
} }
} }
} }

View file

@ -8,7 +8,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -35,9 +34,9 @@ import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.service.PlayerService import it.vfsfitvnm.vimusic.service.PlayerService
import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
import it.vfsfitvnm.vimusic.ui.screens.SettingsGroupDescription
import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -144,6 +143,8 @@ fun BackupAndRestoreScreen() {
SettingsEntryGroupText(title = "BACKUP") SettingsEntryGroupText(title = "BACKUP")
SettingsGroupDescription(text = "Exports the application database to the external storage.\nThis means playlists, song history, favorites songs will exported.\nThis operation excludes personal preferences (i.e. the theme mode) and the cache.")
SettingsEntry( SettingsEntry(
title = "Backup", title = "Backup",
text = "Export the database to the external storage", text = "Export the database to the external storage",
@ -156,6 +157,8 @@ fun BackupAndRestoreScreen() {
SettingsEntryGroupText(title = "RESTORE") SettingsEntryGroupText(title = "RESTORE")
SettingsGroupDescription(text = "Replaces the existing application database with the selected 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.")
SettingsEntry( SettingsEntry(
title = "Restore", title = "Restore",
text = "Import the database from the external storage", text = "Import the database from the external storage",
@ -163,21 +166,6 @@ fun BackupAndRestoreScreen() {
isShowingRestoreDialog = true isShowingRestoreDialog = true
} }
) )
TextCard(
icon = R.drawable.alert_circle,
) {
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)
)
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.")
}
} }
} }
} }

View file

@ -32,11 +32,11 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.CoilDiskCacheMaxSize import it.vfsfitvnm.vimusic.enums.CoilDiskCacheMaxSize
import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize
import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
import it.vfsfitvnm.vimusic.ui.screens.DisabledSettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.EnumValueSelectorSettingsEntry import it.vfsfitvnm.vimusic.ui.screens.EnumValueSelectorSettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.SettingsDescription
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
import it.vfsfitvnm.vimusic.ui.screens.SettingsGroupDescription
import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle import it.vfsfitvnm.vimusic.ui.screens.SettingsTitle
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -96,6 +96,8 @@ fun CacheSettingsScreen() {
SettingsTitle(text = "Cache") SettingsTitle(text = "Cache")
SettingsDescription(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 ones.")
Coil.imageLoader(context).diskCache?.let { diskCache -> Coil.imageLoader(context).diskCache?.let { diskCache ->
var diskCacheSize by remember(diskCache) { var diskCacheSize by remember(diskCache) {
mutableStateOf(diskCache.size) mutableStateOf(diskCache.size)
@ -103,6 +105,8 @@ fun CacheSettingsScreen() {
SettingsEntryGroupText(title = "IMAGE CACHE") SettingsEntryGroupText(title = "IMAGE CACHE")
SettingsGroupDescription(text = "${Formatter.formatShortFileSize(context, diskCacheSize)} used (${diskCacheSize * 100 / coilDiskCacheMaxSize.bytes.coerceAtLeast(1)}%)")
EnumValueSelectorSettingsEntry( EnumValueSelectorSettingsEntry(
title = "Max size", title = "Max size",
selectedValue = coilDiskCacheMaxSize, selectedValue = coilDiskCacheMaxSize,
@ -111,18 +115,6 @@ fun CacheSettingsScreen() {
} }
) )
DisabledSettingsEntry(
title = "Space used",
text = "${
Formatter.formatShortFileSize(
context,
diskCacheSize
)
} (${
diskCacheSize * 100 / coilDiskCacheMaxSize.bytes.coerceAtLeast(1)
}%)",
)
SettingsEntry( SettingsEntry(
title = "Clear space", title = "Clear space",
text = "Wipe every cached image", text = "Wipe every cached image",
@ -144,6 +136,17 @@ fun CacheSettingsScreen() {
SettingsEntryGroupText(title = "SONG CACHE") SettingsEntryGroupText(title = "SONG CACHE")
SettingsGroupDescription(
text = buildString {
append(Formatter.formatShortFileSize(context, diskCacheSize))
append(" used")
when (val size = exoPlayerDiskCacheMaxSize) {
ExoPlayerDiskCacheMaxSize.Unlimited -> {}
else -> append(" (${diskCacheSize * 100 / size.bytes}%)")
}
}
)
EnumValueSelectorSettingsEntry( EnumValueSelectorSettingsEntry(
title = "Max size", title = "Max size",
selectedValue = exoPlayerDiskCacheMaxSize, selectedValue = exoPlayerDiskCacheMaxSize,
@ -151,23 +154,6 @@ fun CacheSettingsScreen() {
exoPlayerDiskCacheMaxSize = it exoPlayerDiskCacheMaxSize = it
} }
) )
DisabledSettingsEntry(
title = "Space used",
text = buildString {
append(Formatter.formatShortFileSize(context, diskCacheSize))
when (val size = exoPlayerDiskCacheMaxSize) {
ExoPlayerDiskCacheMaxSize.Unlimited -> {}
else -> append("(${diskCacheSize * 100 / size.bytes}%)")
}
}
)
}
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.")
} }
} }
} }

View file

@ -13,7 +13,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -34,9 +33,10 @@ import androidx.compose.ui.unit.dp
import it.vfsfitvnm.route.RouteHandler import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.screens.SettingsDescription
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
import it.vfsfitvnm.vimusic.ui.screens.SettingsGroupDescription
import it.vfsfitvnm.vimusic.ui.screens.SwitchSettingEntry import it.vfsfitvnm.vimusic.ui.screens.SwitchSettingEntry
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -101,6 +101,12 @@ fun OtherSettingsScreen() {
SettingsEntryGroupText(title = "SERVICE LIFETIME") SettingsEntryGroupText(title = "SERVICE LIFETIME")
SettingsGroupDescription(text = "Some device manufacturers may have an aggressive policy against stopped foreground services - the media notification can disappear suddenly when paused.\nThe gentle approach consists in disabling battery optimizations - this is enough for some devices and ROMs.\nHowever, if it's not, you can make the service \"invincible\" - which should keep the service alive.")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
SettingsDescription(text = "Since Android 12, the invincible service works ONLY if battery optimizations are disabled for this application.")
}
SettingsEntry( SettingsEntry(
title = "Ignore battery optimizations", title = "Ignore battery optimizations",
isEnabled = !isIgnoringBatteryOptimizations, isEnabled = !isIgnoringBatteryOptimizations,
@ -145,21 +151,6 @@ fun OtherSettingsScreen() {
isInvincibilityEnabled = it isInvincibilityEnabled = it
} }
) )
TextCard(icon = R.drawable.alert_circle) {
Title(text = "Service lifetime")
Text(text = "Some device manufacturers may have an aggressive policy against stopped foreground services - the media notification can disappear suddenly when paused.\nThe gentle approach consists in disabling battery optimizations - this is enough for some devices and ROMs.\nHowever, if it's not, you can make the service \"invincible\" - which should keep the service alive.")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Spacer(
modifier = Modifier
.height(32.dp)
)
Title(text = "Invincible service")
Text(text = "Since Android 12, this option works ONLY if battery optimizations are disabled for this application.")
}
}
} }
} }
} }