From 55e436208fc4fd1edfb86444eaf341566172c052 Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Tue, 19 Jul 2022 11:16:00 +0200 Subject: [PATCH] Improve sorting options for songs and playlists (#104) --- .../kotlin/it/vfsfitvnm/vimusic/Database.kt | 39 ++- .../vfsfitvnm/vimusic/enums/PlaylistSortBy.kt | 7 + .../it/vfsfitvnm/vimusic/enums/SongSortBy.kt | 1 + .../ui/components/themed/DropDownSection.kt | 99 ++++++++ .../ui/components/themed/MediaItemMenu.kt | 4 +- .../vimusic/ui/screens/ArtistScreen.kt | 2 +- .../vimusic/ui/screens/HomeScreen.kt | 227 ++++++++++-------- .../settings/AppearanceSettingsScreen.kt | 12 - .../it/vfsfitvnm/vimusic/utils/Preferences.kt | 4 +- 9 files changed, 272 insertions(+), 123 deletions(-) create mode 100644 app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/PlaylistSortBy.kt create mode 100644 app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/DropDownSection.kt diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt index aaab2d1..ef75e08 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt @@ -12,10 +12,12 @@ import androidx.room.migration.AutoMigrationSpec import androidx.room.migration.Migration import androidx.sqlite.db.SimpleSQLiteQuery import androidx.sqlite.db.SupportSQLiteDatabase +import it.vfsfitvnm.vimusic.enums.PlaylistSortBy import it.vfsfitvnm.vimusic.enums.SongSortBy import it.vfsfitvnm.vimusic.enums.SortOrder import it.vfsfitvnm.vimusic.models.* import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map @Dao @@ -30,6 +32,14 @@ interface Database { @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY ROWID DESC") fun songsByRowIdDesc(): Flow> + @Transaction + @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title ASC") + fun songsByTitleAsc(): Flow> + + @Transaction + @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title DESC") + fun songsByTitleDesc(): Flow> + @Transaction @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY totalPlayTimeMs ASC") fun songsByPlayTimeAsc(): Flow> @@ -44,6 +54,10 @@ interface Database { SortOrder.Ascending -> songsByPlayTimeAsc() SortOrder.Descending -> songsByPlayTimeDesc() } + SongSortBy.Title -> when (sortOrder) { + SortOrder.Ascending -> songsByTitleAsc() + SortOrder.Descending -> songsByTitleDesc() + } SongSortBy.DateAdded -> when (sortOrder) { SortOrder.Ascending -> songsByRowIdAsc() SortOrder.Descending -> songsByRowIdDesc() @@ -81,8 +95,29 @@ interface Database { fun playlistWithSongs(id: Long): Flow @Transaction - @Query("SELECT id, name, (SELECT COUNT(*) FROM SongPlaylistMap WHERE playlistId = id) as songCount FROM Playlist") - fun playlistPreviews(): Flow> + @Query("SELECT id, name, (SELECT COUNT(*) FROM SongPlaylistMap WHERE playlistId = id) as songCount FROM Playlist ORDER BY name ASC") + fun playlistPreviewsByName(): Flow> + + @Transaction + @Query("SELECT id, name, (SELECT COUNT(*) FROM SongPlaylistMap WHERE playlistId = id) as songCount FROM Playlist ORDER BY ROWID ASC") + fun playlistPreviewsByDateAdded(): Flow> + + @Transaction + @Query("SELECT id, name, (SELECT COUNT(*) FROM SongPlaylistMap WHERE playlistId = id) as songCount FROM Playlist ORDER BY songCount ASC") + fun playlistPreviewsByDateSongCount(): Flow> + + fun playlistPreviews(sortBy: PlaylistSortBy, sortOrder: SortOrder): Flow> { + return when (sortBy) { + PlaylistSortBy.Name -> playlistPreviewsByName() + PlaylistSortBy.DateAdded -> playlistPreviewsByDateAdded() + PlaylistSortBy.SongCount -> playlistPreviewsByDateSongCount() + }.map { + when (sortOrder) { + SortOrder.Ascending -> it + SortOrder.Descending -> it.reversed() + } + } + } @Query("SELECT thumbnailUrl FROM Song JOIN SongPlaylistMap ON id = songId WHERE playlistId = :id ORDER BY position LIMIT 4") fun playlistThumbnailUrls(id: Long): Flow> diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/PlaylistSortBy.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/PlaylistSortBy.kt new file mode 100644 index 0000000..52c62ea --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/PlaylistSortBy.kt @@ -0,0 +1,7 @@ +package it.vfsfitvnm.vimusic.enums + +enum class PlaylistSortBy { + Name, + DateAdded, + SongCount +} diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/SongSortBy.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/SongSortBy.kt index 2b6be5c..ff9889a 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/SongSortBy.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/SongSortBy.kt @@ -2,5 +2,6 @@ package it.vfsfitvnm.vimusic.enums enum class SongSortBy { PlayTime, + Title, DateAdded } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/DropDownSection.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/DropDownSection.kt new file mode 100644 index 0000000..510e6e1 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/DropDownSection.kt @@ -0,0 +1,99 @@ +package it.vfsfitvnm.vimusic.ui.components.themed + +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.shape.RoundedCornerShape +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.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance +import it.vfsfitvnm.vimusic.utils.medium + + +@Composable +fun DropDownSection(content: @Composable ColumnScope.() -> Unit) { + val (colorPalette) = LocalAppearance.current + Column( + modifier = Modifier + .shadow( + elevation = 2.dp, + shape = RoundedCornerShape(16.dp) + ) + .background(colorPalette.elevatedBackground) + .width(IntrinsicSize.Max), + content = content + ) +} + +@Composable +fun DropDownSectionSpacer() { + Spacer( + modifier = Modifier + .height(4.dp) + ) +} + +@Composable +fun DropDownTextItem( + text: String, + isSelected: Boolean, + onClick: () -> Unit +) { + val (colorPalette) = LocalAppearance.current + + DropDownTextItem( + text = text, + textColor = if (isSelected) { + colorPalette.onPrimaryContainer + } else { + colorPalette.textSecondary + }, + backgroundColor = if (isSelected) { + colorPalette.primaryContainer + } else { + colorPalette.elevatedBackground + }, + onClick = onClick + ) +} + +@Composable +fun DropDownTextItem( + text: String, + backgroundColor: Color? = null, + textColor: Color? = null, + onClick: () -> Unit +) { + val (colorPalette, typography) = LocalAppearance.current + + BasicText( + text = text, + style = typography.xxs.medium.copy( + color = textColor ?: colorPalette.text, + letterSpacing = 1.sp + ), + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .clickable( + indication = rememberRipple(bounded = true), + interactionSource = remember { MutableInteractionSource() }, + onClick = onClick + ) + .background(backgroundColor ?: colorPalette.elevatedBackground) + .fillMaxWidth() + .widthIn(min = 124.dp, max = 248.dp) + .padding( + horizontal = 16.dp, + vertical = 8.dp + ) + ) +} \ No newline at end of file diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/MediaItemMenu.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/MediaItemMenu.kt index d1f5282..9235db8 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/MediaItemMenu.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/MediaItemMenu.kt @@ -22,6 +22,8 @@ import it.vfsfitvnm.route.RouteHandler import it.vfsfitvnm.route.empty import it.vfsfitvnm.vimusic.* import it.vfsfitvnm.vimusic.R +import it.vfsfitvnm.vimusic.enums.PlaylistSortBy +import it.vfsfitvnm.vimusic.enums.SortOrder import it.vfsfitvnm.vimusic.models.DetailedSong import it.vfsfitvnm.vimusic.models.Playlist import it.vfsfitvnm.vimusic.models.SongPlaylistMap @@ -276,7 +278,7 @@ fun MediaItemMenu( onGlobalRouteEmitted: (() -> Unit)? = null, ) { val playlistPreviews by remember { - Database.playlistPreviews() + Database.playlistPreviews(PlaylistSortBy.DateAdded, SortOrder.Descending) }.collectAsState(initial = emptyList(), context = Dispatchers.IO) val viewPlaylistsRoute = rememberCreatePlaylistRoute() 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 ff42922..77cf3f4 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 @@ -49,7 +49,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking -@ExperimentalFoundationApi +@OptIn(ExperimentalFoundationApi::class) @ExperimentalAnimationApi @Composable fun ArtistScreen( diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/HomeScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/HomeScreen.kt index 116d1a6..e0be978 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/HomeScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/HomeScreen.kt @@ -12,18 +12,16 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicText import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.draw.shadow import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color @@ -32,25 +30,21 @@ import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.zIndex import it.vfsfitvnm.route.RouteHandler import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.R -import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist -import it.vfsfitvnm.vimusic.enums.SongSortBy -import it.vfsfitvnm.vimusic.enums.SortOrder -import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness +import it.vfsfitvnm.vimusic.enums.* import it.vfsfitvnm.vimusic.models.DetailedSong import it.vfsfitvnm.vimusic.models.Playlist import it.vfsfitvnm.vimusic.models.SearchQuery import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.ui.components.TopAppBar -import it.vfsfitvnm.vimusic.ui.components.themed.DropdownMenu -import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu -import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog -import it.vfsfitvnm.vimusic.ui.styling.* +import it.vfsfitvnm.vimusic.ui.components.themed.* +import it.vfsfitvnm.vimusic.ui.styling.Dimensions +import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance +import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.views.PlaylistPreviewItem import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.utils.* @@ -64,6 +58,7 @@ fun HomeScreen() { val (colorPalette, typography) = LocalAppearance.current val lazyListState = rememberLazyListState() + val lazyHorizontalGridState = rememberLazyGridState() val intentUriRoute = rememberIntentUriRoute() val settingsRoute = rememberSettingsRoute() @@ -74,8 +69,12 @@ fun HomeScreen() { val albumRoute = rememberAlbumRoute() val artistRoute = rememberArtistRoute() - val playlistPreviews by remember { - Database.playlistPreviews() + var playlistSortBy by rememberPreference(playlistSortByKey, PlaylistSortBy.DateAdded) + var playlistSortOrder by rememberPreference(playlistSortOrderKey, SortOrder.Descending) + var playlistGridExpanded by rememberPreference(playlistGridExpandedKey, false) + + val playlistPreviews by remember(playlistSortBy, playlistSortOrder) { + Database.playlistPreviews(playlistSortBy, playlistSortOrder) }.collectAsState(initial = emptyList(), context = Dispatchers.IO) var songSortBy by rememberPreference(songSortByKey, SongSortBy.DateAdded) @@ -151,14 +150,9 @@ fun HomeScreen() { val binder = LocalPlayerServiceBinder.current val isFirstLaunch by rememberPreference(isFirstLaunchKey, true) - val isCachedPlaylistShown by rememberPreference(isCachedPlaylistShownKey, false) val thumbnailSize = Dimensions.thumbnails.song.px - var isGridExpanded by remember { - mutableStateOf(false) - } - var isCreatingANewPlaylist by rememberSaveable { mutableStateOf(false) } @@ -262,28 +256,100 @@ fun HomeScreen() { .size(20.dp) ) - Image( - painter = painterResource(if (isGridExpanded) R.drawable.grid else R.drawable.grid_single), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.textSecondary), - modifier = Modifier - .clickable { - isGridExpanded = !isGridExpanded + Box { + var isSortMenuDisplayed by remember { + mutableStateOf(false) + } + + Image( + painter = painterResource(R.drawable.sort), + contentDescription = null, + colorFilter = ColorFilter.tint(colorPalette.text), + modifier = Modifier + .clickable { + isSortMenuDisplayed = true + } + .padding(horizontal = 8.dp, vertical = 8.dp) + .size(20.dp) + ) + + DropdownMenu( + isDisplayed = isSortMenuDisplayed, + onDismissRequest = { + isSortMenuDisplayed = false } - .padding(all = 10.dp) - .size(16.dp) - ) + ) { + DropDownSection { + DropDownTextItem( + text = "NAME", + isSelected = playlistSortBy == PlaylistSortBy.Name, + onClick = { + isSortMenuDisplayed = false + playlistSortBy = PlaylistSortBy.Name + } + ) + + DropDownTextItem( + text = "DATE ADDED", + isSelected = playlistSortBy == PlaylistSortBy.DateAdded, + onClick = { + isSortMenuDisplayed = false + playlistSortBy = PlaylistSortBy.DateAdded + } + ) + + DropDownTextItem( + text = "SONG COUNT", + isSelected = playlistSortBy == PlaylistSortBy.SongCount, + onClick = { + isSortMenuDisplayed = false + playlistSortBy = PlaylistSortBy.SongCount + } + ) + } + + DropDownSectionSpacer() + + DropDownSection { + DropDownTextItem( + text = when (playlistSortOrder) { + SortOrder.Ascending -> "ASCENDING" + SortOrder.Descending -> "DESCENDING" + }, + onClick = { + isSortMenuDisplayed = false + playlistSortOrder = !playlistSortOrder + } + ) + } + DropDownSectionSpacer() + + DropDownSection { + DropDownTextItem( + text = when (playlistGridExpanded) { + true -> "EXPAND" + false -> "COMPACT" + }, + onClick = { + isSortMenuDisplayed = false + playlistGridExpanded = !playlistGridExpanded + } + ) + } + } + } } } item { LazyHorizontalGrid( - rows = GridCells.Fixed(if (isGridExpanded) 3 else 1), + state = lazyHorizontalGridState, + rows = GridCells.Fixed(if (playlistGridExpanded) 3 else 1), contentPadding = PaddingValues(horizontal = 16.dp), modifier = Modifier .animateContentSize() .fillMaxWidth() - .height(124.dp * (if (isGridExpanded) 3 else 1)) + .height(124.dp * (if (playlistGridExpanded) 3 else 1)) ) { item { Box( @@ -321,7 +387,7 @@ fun HomeScreen() { } } - if (isCachedPlaylistShown) { + if (playlistGridExpanded) { item { Box( modifier = Modifier @@ -361,6 +427,7 @@ fun HomeScreen() { items( items = playlistPreviews, + key = { it.playlist.id }, contentType = { it } ) { playlistPreview -> PlaylistPreviewItem( @@ -370,10 +437,9 @@ fun HomeScreen() { .padding(all = 8.dp) .clickable( indication = rememberRipple(bounded = true), - interactionSource = remember { MutableInteractionSource() } - ) { - playlistRoute(playlistPreview.playlist.id) - } + interactionSource = remember { MutableInteractionSource() }, + onClick = { playlistRoute(playlistPreview.playlist.id) } + ) ) } } @@ -436,96 +502,45 @@ fun HomeScreen() { isSortMenuDisplayed = false } ) { - @Composable - fun Item( - text: String, - textColor: Color, - backgroundColor: Color, - onClick: () -> Unit - ) { - BasicText( - text = text, - style = typography.xxs.medium.copy(color = textColor, letterSpacing = 1.sp), - modifier = Modifier - .clip(RoundedCornerShape(16.dp)) - .clickable( - indication = rememberRipple(bounded = true), - interactionSource = remember { MutableInteractionSource() }, - onClick = { - isSortMenuDisplayed = false - onClick() - } - ) - .background(backgroundColor) - .fillMaxWidth() - .widthIn(min = 124.dp, max = 248.dp) - .padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - - @Composable - fun Item( - text: String, - isSelected: Boolean, - onClick: () -> Unit - ) { - Item( - text = text, - textColor = if (isSelected) { - colorPalette.onPrimaryContainer - } else { - colorPalette.textSecondary - }, - backgroundColor = if (isSelected) { - colorPalette.primaryContainer - } else { - colorPalette.elevatedBackground - }, - onClick = onClick - ) - } - - Column( - modifier = Modifier - .shadow(elevation = 2.dp, shape = RoundedCornerShape(16.dp)) - .background(colorPalette.elevatedBackground) - .width(IntrinsicSize.Max), - ) { - Item( + DropDownSection { + DropDownTextItem( text = "PLAY TIME", isSelected = songSortBy == SongSortBy.PlayTime, onClick = { + isSortMenuDisplayed = false songSortBy = SongSortBy.PlayTime } ) - Item( + + DropDownTextItem( + text = "TITLE", + isSelected = songSortBy == SongSortBy.Title, + onClick = { + isSortMenuDisplayed = false + songSortBy = SongSortBy.Title + } + ) + + DropDownTextItem( text = "DATE ADDED", isSelected = songSortBy == SongSortBy.DateAdded, onClick = { + isSortMenuDisplayed = false songSortBy = SongSortBy.DateAdded } ) } - Spacer( - modifier = Modifier - .height(4.dp) - ) + DropDownSectionSpacer() - Column( - modifier = Modifier - .shadow(elevation = 2.dp, shape = RoundedCornerShape(16.dp)) - .background(colorPalette.elevatedBackground) - .width(IntrinsicSize.Max), - ) { - Item( + DropDownSection { + DropDownTextItem( text = when (songSortOrder) { SortOrder.Ascending -> "ASCENDING" SortOrder.Descending -> "DESCENDING" }, - textColor = colorPalette.text, - backgroundColor = colorPalette.elevatedBackground, onClick = { + isSortMenuDisplayed = false songSortOrder = !songSortOrder } ) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceSettingsScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceSettingsScreen.kt index 1a91597..95e7a57 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceSettingsScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/AppearanceSettingsScreen.kt @@ -46,7 +46,6 @@ fun AppearanceSettingsScreen() { var colorPaletteMode by rememberPreference(colorPaletteModeKey, ColorPaletteMode.System) var thumbnailRoundness by rememberPreference(thumbnailRoundnessKey, ThumbnailRoundness.Light) - var isCachedPlaylistShown by rememberPreference(isCachedPlaylistShownKey, false) Column( modifier = Modifier @@ -100,17 +99,6 @@ fun AppearanceSettingsScreen() { thumbnailRoundness = it } ) - - SettingsEntryGroupText(title = "OTHER") - - SwitchSettingEntry( - title = "Cached playlist", - text = "Display a playlist whose songs can be played offline", - isChecked = isCachedPlaylistShown, - onCheckedChange = { - isCachedPlaylistShown = it - } - ) } } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt index 57d35aa..e57b80e 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt @@ -9,13 +9,15 @@ import androidx.core.content.edit const val colorPaletteModeKey = "colorPaletteMode" const val thumbnailRoundnessKey = "thumbnailRoundness" -const val isCachedPlaylistShownKey = "isCachedPlaylistShown" const val coilDiskCacheMaxSizeKey = "coilDiskCacheMaxSize" const val exoPlayerDiskCacheMaxSizeKey = "exoPlayerDiskCacheMaxSize" const val isInvincibilityEnabledKey = "isInvincibilityEnabled" const val isFirstLaunchKey = "isFirstLaunch" const val songSortOrderKey = "songSortOrder" const val songSortByKey = "songSortBy" +const val playlistSortOrderKey = "playlistSortOrder" +const val playlistSortByKey = "playlistSortBy" +const val playlistGridExpandedKey = "playlistGridExpanded" const val searchFilterKey = "searchFilter" const val repeatModeKey = "repeatMode" const val skipSilenceKey = "skipSilence"