From b1c2ca6de591addbe752da2ebd3355a22a5e9647 Mon Sep 17 00:00:00 2001 From: Malopieds Date: Wed, 26 Jun 2024 17:07:28 +0200 Subject: [PATCH] feat: implementation of update time in playlists closes #131 --- .../zionhuang/music/constants/PreferenceKeys.kt | 4 ++-- .../java/com/zionhuang/music/db/DatabaseDao.kt | 5 +++++ .../java/com/zionhuang/music/db/MusicDatabase.kt | 14 ++++++++++++-- .../zionhuang/music/db/entities/PlaylistEntity.kt | 3 +++ .../java/com/zionhuang/music/ui/menu/AlbumMenu.kt | 2 ++ .../java/com/zionhuang/music/ui/menu/PlayerMenu.kt | 2 ++ .../com/zionhuang/music/ui/menu/PlaylistMenu.kt | 3 ++- .../zionhuang/music/ui/menu/SelectionSongsMenu.kt | 3 +++ .../java/com/zionhuang/music/ui/menu/SongMenu.kt | 2 ++ .../zionhuang/music/ui/menu/YouTubeAlbumMenu.kt | 2 ++ .../zionhuang/music/ui/menu/YouTubePlaylistMenu.kt | 2 ++ .../com/zionhuang/music/ui/menu/YouTubeSongMenu.kt | 2 ++ .../java/com/zionhuang/music/ui/player/Player.kt | 10 ++++++---- .../music/ui/screens/library/LibraryMixScreen.kt | 9 +++++++++ .../ui/screens/library/LibraryPlaylistsScreen.kt | 1 + .../ui/screens/playlist/LocalPlaylistScreen.kt | 3 ++- app/src/main/res/values/strings.xml | 1 + 17 files changed, 58 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt index 8bd78addd..e07ceafcf 100644 --- a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt +++ b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt @@ -88,11 +88,11 @@ enum class AlbumSortType { } enum class PlaylistSortType { - CREATE_DATE, NAME, SONG_COUNT + CREATE_DATE, NAME, SONG_COUNT, LAST_UPDATED } enum class MixSortType { - CREATE_DATE, NAME + CREATE_DATE, NAME, LAST_UPDATED } enum class MyTopFilter { diff --git a/app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt b/app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt index 5950fef0a..f582844f7 100644 --- a/app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt +++ b/app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt @@ -556,6 +556,10 @@ interface DatabaseDao { @Query("SELECT *, (SELECT COUNT(*) FROM playlist_song_map WHERE playlistId = playlist.id) AS songCount FROM playlist ORDER BY rowId") fun playlistsByCreateDateAsc(): Flow> + @Transaction + @Query("SELECT *, (SELECT COUNT(*) FROM playlist_song_map WHERE playlistId = playlist.id) AS songCount FROM playlist ORDER BY lastUpdateTime") + fun playlistsByUpdatedDateAsc(): Flow> + @Transaction @Query("SELECT *, (SELECT COUNT(*) FROM playlist_song_map WHERE playlistId = playlist.id) AS songCount FROM playlist ORDER BY name") fun playlistsByNameAsc(): Flow> @@ -569,6 +573,7 @@ interface DatabaseDao { PlaylistSortType.CREATE_DATE -> playlistsByCreateDateAsc() PlaylistSortType.NAME -> playlistsByNameAsc() PlaylistSortType.SONG_COUNT -> playlistsBySongCountAsc() + PlaylistSortType.LAST_UPDATED -> playlistsByUpdatedDateAsc() }.map { it.reversed(descending) } @Transaction diff --git a/app/src/main/java/com/zionhuang/music/db/MusicDatabase.kt b/app/src/main/java/com/zionhuang/music/db/MusicDatabase.kt index 6993d1550..c77982447 100644 --- a/app/src/main/java/com/zionhuang/music/db/MusicDatabase.kt +++ b/app/src/main/java/com/zionhuang/music/db/MusicDatabase.kt @@ -1,5 +1,6 @@ package com.zionhuang.music.db +import android.annotation.SuppressLint import android.content.Context import android.database.sqlite.SQLiteDatabase import androidx.core.content.contentValuesOf @@ -59,7 +60,7 @@ class MusicDatabase( SortedSongAlbumMap::class, PlaylistSongMapPreview::class ], - version = 13, + version = 14, exportSchema = true, autoMigrations = [ AutoMigration(from = 2, to = 3), @@ -72,7 +73,8 @@ class MusicDatabase( AutoMigration(from = 9, to = 10, spec = Migration9To10::class), AutoMigration(from = 10, to = 11, spec = Migration10To11::class), AutoMigration(from = 11, to = 12, spec = Migration11To12::class), - AutoMigration(from = 12, to = 13, spec = Migration12To13::class) + AutoMigration(from = 12, to = 13, spec = Migration12To13::class), + AutoMigration(from = 13, to = 14, spec = Migration13To14::class), ] ) @TypeConverters(Converters::class) @@ -352,3 +354,11 @@ class Migration12To13 : AutoMigrationSpec { db.execSQL("UPDATE song SET liked = 1 WHERE inLibrary IS NOT NULL") } } + +class Migration13To14 : AutoMigrationSpec { + @SuppressLint("Range") + override fun onPostMigrate(db: SupportSQLiteDatabase) { + db.execSQL("UPDATE playlist SET createdAt = '${Converters().dateToTimestamp(LocalDateTime.now())}'") + db.execSQL("UPDATE playlist SET lastUpdateTime = '${Converters().dateToTimestamp(LocalDateTime.now())}'") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zionhuang/music/db/entities/PlaylistEntity.kt b/app/src/main/java/com/zionhuang/music/db/entities/PlaylistEntity.kt index b2bf56092..8974fc219 100644 --- a/app/src/main/java/com/zionhuang/music/db/entities/PlaylistEntity.kt +++ b/app/src/main/java/com/zionhuang/music/db/entities/PlaylistEntity.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable import androidx.room.Entity import androidx.room.PrimaryKey import org.apache.commons.lang3.RandomStringUtils +import java.time.LocalDateTime @Immutable @Entity(tableName = "playlist") @@ -11,6 +12,8 @@ data class PlaylistEntity( @PrimaryKey val id: String = generatePlaylistId(), val name: String, val browseId: String? = null, + val createdAt: LocalDateTime? = LocalDateTime.now(), + val lastUpdateTime: LocalDateTime? = LocalDateTime.now(), ) { companion object { const val LIKED_PLAYLIST_ID = "LP_LIKED" diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/AlbumMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/AlbumMenu.kt index a57b1598e..da1b9f156 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/AlbumMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/AlbumMenu.kt @@ -61,6 +61,7 @@ import com.zionhuang.music.ui.component.DownloadGridMenu import com.zionhuang.music.ui.component.GridMenu import com.zionhuang.music.ui.component.GridMenuItem import com.zionhuang.music.ui.component.ListDialog +import java.time.LocalDateTime @Composable fun AlbumMenu( @@ -127,6 +128,7 @@ fun AlbumMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } }, diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/PlayerMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/PlayerMenu.kt index 25d5c9eb4..51f1a145e 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/PlayerMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/PlayerMenu.kt @@ -63,6 +63,7 @@ import com.zionhuang.music.ui.component.DownloadGridMenu import com.zionhuang.music.ui.component.GridMenu import com.zionhuang.music.ui.component.GridMenuItem import com.zionhuang.music.ui.component.ListDialog +import java.time.LocalDateTime import kotlin.math.log2 import kotlin.math.pow import kotlin.math.round @@ -101,6 +102,7 @@ fun PlayerMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } }, onDismiss = { diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/PlaylistMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/PlaylistMenu.kt index cf884285a..f71154339 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/PlaylistMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/PlaylistMenu.kt @@ -55,6 +55,7 @@ import com.zionhuang.music.utils.makeTimeString import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import java.time.LocalDateTime @Composable fun PlaylistMenu( @@ -126,7 +127,7 @@ fun PlaylistMenu( onDone = { name -> onDismiss() database.query { - update(playlist.playlist.copy(name = name)) + update(playlist.playlist.copy(name = name, lastUpdateTime = LocalDateTime.now())) } } ) diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/SelectionSongsMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/SelectionSongsMenu.kt index ea5636457..a00800655 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/SelectionSongsMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/SelectionSongsMenu.kt @@ -38,6 +38,7 @@ import com.zionhuang.music.ui.component.DefaultDialog import com.zionhuang.music.ui.component.DownloadGridMenu import com.zionhuang.music.ui.component.GridMenu import com.zionhuang.music.ui.component.GridMenuItem +import java.time.LocalDateTime @Composable fun SelectionSongMenu( @@ -88,6 +89,7 @@ fun SelectionSongMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } }, @@ -294,6 +296,7 @@ fun SelectionMediaMetadataMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } }, diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/SongMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/SongMenu.kt index b8c9e8b7e..285df8f37 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/SongMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/SongMenu.kt @@ -62,6 +62,7 @@ import com.zionhuang.music.ui.component.GridMenuItem import com.zionhuang.music.ui.component.ListDialog import com.zionhuang.music.ui.component.SongListItem import com.zionhuang.music.ui.component.TextFieldDialog +import java.time.LocalDateTime @Composable fun SongMenu( @@ -111,6 +112,7 @@ fun SongMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } }, onDismiss = { showChoosePlaylistDialog = false } diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeAlbumMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeAlbumMenu.kt index d6b919d14..35490f76f 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeAlbumMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeAlbumMenu.kt @@ -55,6 +55,7 @@ import com.zionhuang.music.ui.component.GridMenuItem import com.zionhuang.music.ui.component.ListDialog import com.zionhuang.music.ui.component.YouTubeListItem import com.zionhuang.music.utils.reportException +import java.time.LocalDateTime @Composable fun YouTubeAlbumMenu( @@ -120,6 +121,7 @@ fun YouTubeAlbumMenu( position = position++ ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } }, diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubePlaylistMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubePlaylistMenu.kt index f0d09c749..90e2b6384 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubePlaylistMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubePlaylistMenu.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import java.time.LocalDateTime @Composable fun YouTubePlaylistMenu( @@ -68,6 +69,7 @@ fun YouTubePlaylistMenu( position = position++ ) ) + update(targetPlaylist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } } diff --git a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeSongMenu.kt b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeSongMenu.kt index b336708ef..06ea60ce9 100644 --- a/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeSongMenu.kt +++ b/app/src/main/java/com/zionhuang/music/ui/menu/YouTubeSongMenu.kt @@ -63,6 +63,7 @@ import com.zionhuang.music.ui.component.ListDialog import com.zionhuang.music.ui.component.ListItem import com.zionhuang.music.utils.joinByBullet import com.zionhuang.music.utils.makeTimeString +import java.time.LocalDateTime @Composable fun YouTubeSongMenu( @@ -99,6 +100,7 @@ fun YouTubeSongMenu( position = playlist.songCount ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } }, onDismiss = { showChoosePlaylistDialog = false } diff --git a/app/src/main/java/com/zionhuang/music/ui/player/Player.kt b/app/src/main/java/com/zionhuang/music/ui/player/Player.kt index 0fd05955b..9602a2b2c 100644 --- a/app/src/main/java/com/zionhuang/music/ui/player/Player.kt +++ b/app/src/main/java/com/zionhuang/music/ui/player/Player.kt @@ -103,6 +103,7 @@ import com.zionhuang.music.utils.makeTimeString import com.zionhuang.music.utils.rememberPreference import kotlinx.coroutines.delay import kotlinx.coroutines.isActive +import java.time.LocalDateTime import kotlin.math.roundToInt @OptIn(ExperimentalFoundationApi::class, ExperimentalAnimationApi::class) @@ -232,11 +233,12 @@ fun BottomSheetPlayer( insert(it) insert( PlaylistSongMap( - songId = it.id, - playlistId = playlist.id, - position = playlist.songCount - ) + songId = it.id, + playlistId = playlist.id, + position = playlist.songCount + ) ) + update(playlist.playlist.copy(lastUpdateTime = LocalDateTime.now())) } } }, diff --git a/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryMixScreen.kt b/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryMixScreen.kt index bd33c44e2..de9461b7a 100644 --- a/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryMixScreen.kt +++ b/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryMixScreen.kt @@ -111,6 +111,14 @@ fun LibraryMixScreen( MixSortType.CREATE_DATE -> when (item) { is Album -> item.album.bookmarkedAt is Artist -> item.artist.bookmarkedAt + is Playlist -> item.playlist.createdAt + else -> LocalDateTime.now() + } + + MixSortType.LAST_UPDATED -> when(item) { + is Album -> item.album.lastUpdateTime + is Artist -> item.artist.lastUpdateTime + is Playlist -> item.playlist.lastUpdateTime else -> LocalDateTime.now() } @@ -141,6 +149,7 @@ fun LibraryMixScreen( sortTypeText = { sortType -> when (sortType) { MixSortType.CREATE_DATE -> R.string.sort_by_create_date + MixSortType.LAST_UPDATED -> R.string.sort_by_last_updated MixSortType.NAME -> R.string.sort_by_name } } diff --git a/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryPlaylistsScreen.kt b/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryPlaylistsScreen.kt index 3a964418c..d8b5893b4 100644 --- a/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryPlaylistsScreen.kt +++ b/app/src/main/java/com/zionhuang/music/ui/screens/library/LibraryPlaylistsScreen.kt @@ -143,6 +143,7 @@ fun LibraryPlaylistsScreen( PlaylistSortType.CREATE_DATE -> R.string.sort_by_create_date PlaylistSortType.NAME -> R.string.sort_by_name PlaylistSortType.SONG_COUNT -> R.string.sort_by_song_count + PlaylistSortType.LAST_UPDATED -> R.string.sort_by_last_updated } } ) diff --git a/app/src/main/java/com/zionhuang/music/ui/screens/playlist/LocalPlaylistScreen.kt b/app/src/main/java/com/zionhuang/music/ui/screens/playlist/LocalPlaylistScreen.kt index f859728fd..37ec18205 100644 --- a/app/src/main/java/com/zionhuang/music/ui/screens/playlist/LocalPlaylistScreen.kt +++ b/app/src/main/java/com/zionhuang/music/ui/screens/playlist/LocalPlaylistScreen.kt @@ -117,6 +117,7 @@ import org.burnoutcrew.reorderable.ReorderableItem import org.burnoutcrew.reorderable.detectReorder import org.burnoutcrew.reorderable.rememberReorderableLazyListState import org.burnoutcrew.reorderable.reorderable +import java.time.LocalDateTime @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class) @Composable @@ -189,7 +190,7 @@ fun LocalPlaylistScreen( initialTextFieldValue = TextFieldValue(playlistEntity.name, TextRange(playlistEntity.name.length)), onDone = { name -> database.query { - update(playlistEntity.copy(name = name)) + update(playlistEntity.copy(name = name, lastUpdateTime = LocalDateTime.now())) } } ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bc5d66494..ba5719a83 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,6 +97,7 @@ Date added + Date updated Name Artist Year