From 90132ec674d8ce494ac648d2088bf0c5d6760610 Mon Sep 17 00:00:00 2001 From: knighthat Date: Mon, 25 Nov 2024 12:30:22 -0600 Subject: [PATCH 1/2] fixed #4623 --- .../kotlin/it/fast4x/rimusic/Database.kt | 353 +++++++----------- .../kotlin/it/fast4x/rimusic/models/Song.kt | 3 + .../modern/MediaLibrarySessionCallback.kt | 6 +- .../rimusic/ui/screens/home/HomeSongs.kt | 4 +- .../localplaylist/LocalPlaylistSongs.kt | 6 +- 5 files changed, 156 insertions(+), 216 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt index 37d7a853b..1c9256025 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt @@ -59,6 +59,7 @@ import it.fast4x.rimusic.models.SongWithContentLength import it.fast4x.rimusic.models.SortedSongPlaylistMap import it.fast4x.rimusic.service.LOCAL_KEY_PREFIX import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map import me.knighthat.appContext @@ -933,225 +934,161 @@ interface Database { "INNER JOIN Playlist P ON P.id=SM.playlistId WHERE P.name LIKE '${MONTHLY_PREFIX}' || '%'") fun songsInAllMonthlyPlaylists(): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.artistsText COLLATE NOCASE ASC") - fun songsPlaylistByArtistAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.artistsText COLLATE NOCASE DESC") - fun songsPlaylistByArtistDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.title COLLATE NOCASE ASC") - fun songsPlaylistByTitleAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.title COLLATE NOCASE DESC") - fun songsPlaylistByTitleDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY SP.position") - fun songsPlaylistByPositionAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY SP.position DESC") - fun songsPlaylistByPositionDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.totalPlayTimeMs") - fun songsPlaylistByPlayTimeAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.totalPlayTimeMs DESC") - fun songsPlaylistByPlayTimeDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN Event E ON E.songId=S.id " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY E.timestamp") - fun songsPlaylistByDatePlayedAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN Event E ON E.songId=S.id " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY E.timestamp DESC") - fun songsPlaylistByDatePlayedDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY CAST(A.year AS INTEGER) DESC") - fun songsPlaylistByAlbumYearDesc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY CAST(A.year AS INTEGER)") - fun songsPlaylistByAlbumYearAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.durationText") - fun songsPlaylistByDurationAsc(id: Long): Flow> - - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.durationText DESC") - fun songsPlaylistByDurationDesc(id: Long): Flow> + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY S.artistsText COLLATE NOCASE + """) + fun sortSongsFromPlaylistByArtist( id: Long ): Flow> + + /** + * Fetch all records from data that have playlist id matches [id] + * and sort them by their titles. + * + * [EXPLICIT_PREFIX] is removed during the sort process to make + * this sorting more accurate + */ + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY + CASE + WHEN S.title LIKE "$EXPLICIT_PREFIX%" THEN SUBSTR(S.title, LENGTH('$EXPLICIT_PREFIX') + 1) + ELSE S.title + END + COLLATE NOCASE + """) + fun sortSongsFromPlaylistByTitle( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY S.artistsText COLLATE NOCASE ASC, A.title COLLATE NOCASE ASC") - fun songsPlaylistByArtistAndAlbumAsc(id: Long): Flow> + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY SP.position + """) + fun sortSongsPlaylistByPosition( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY S.artistsText COLLATE NOCASE DESC, A.title COLLATE NOCASE DESC") - fun songsPlaylistByArtistAndAlbumDesc(id: Long): Flow> + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY S.totalPlayTimeMs + """) + fun sortSongsFromPlaylistByPlaytime( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY A.title COLLATE NOCASE ASC") - fun songsPlaylistByAlbumAsc(id: Long): Flow> + @Query(""" + SELECT DISTINCT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN Event E ON E.songId=S.id + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY E.timestamp + """) + fun sortSongsFromPlaylistByDatePlayed( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT DISTINCT S.*, A.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN songalbummap SA ON SA.songId=SP.songId " + - "LEFT JOIN Album A ON A.Id=SA.albumId " + - "WHERE SP.playlistId=:id " + - "ORDER BY A.title COLLATE NOCASE DESC") - fun songsPlaylistByAlbumDesc(id: Long): Flow> + @Query(""" + SELECT DISTINCT S.*, A.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN songalbummap SA ON SA.songId=SP.songId + LEFT JOIN Album A ON A.Id=SA.albumId + WHERE SP.playlistId=:id + ORDER BY CAST(A.year AS INTEGER) + """) + fun sortSongsFromPlaylistByYear( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.ROWID") - fun songsPlaylistByRowIdAsc(id: Long): Flow> + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY S.durationText + """) + fun sortSongsFromPlaylistByDuration( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.ROWID DESC") - fun songsPlaylistByRowIdDesc(id: Long): Flow> + @Query(""" + SELECT DISTINCT S.*, A.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN songalbummap SA ON SA.songId=SP.songId + LEFT JOIN Album A ON A.Id=SA.albumId + WHERE SP.playlistId=:id + ORDER BY S.artistsText COLLATE NOCASE, A.title COLLATE NOCASE + """) + fun sortSongsFromPlaylistByArtistAndAlbum( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.LikedAt COLLATE NOCASE ASC") - fun songsPlaylistByDateLikedAsc(id: Long): Flow> + @Query(""" + SELECT DISTINCT S.*, A.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN songalbummap SA ON SA.songId=SP.songId + LEFT JOIN Album A ON A.Id=SA.albumId + WHERE SP.playlistId=:id + ORDER BY A.title COLLATE NOCASE + """) + fun sortSongsFromPlaylistByAlbum( id: Long ): Flow> - @SuppressWarnings(RoomWarnings.QUERY_MISMATCH) - @Transaction - @Query("SELECT S.*, Album.title as albumTitle FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId " + - "LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId " + - "WHERE SP.playlistId=:id ORDER BY S.LikedAt COLLATE NOCASE DESC") - fun songsPlaylistByDateLikedDesc(id: Long): Flow> + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY S.ROWID + """) + fun sortSongsFromPlaylistByRowId( id: Long ): Flow> - fun songsPlaylist(id: Long, sortBy: PlaylistSongSortBy, sortOrder: SortOrder): Flow> { - return when (sortBy) { - PlaylistSongSortBy.PlayTime -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByPlayTimeAsc(id) - SortOrder.Descending -> songsPlaylistByPlayTimeDesc(id) - } - PlaylistSongSortBy.Title -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByTitleAsc(id) - SortOrder.Descending -> songsPlaylistByTitleDesc(id) - } - PlaylistSongSortBy.Artist -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByArtistAsc(id) - SortOrder.Descending -> songsPlaylistByArtistDesc(id) - } - PlaylistSongSortBy.Position -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByPositionAsc(id) - SortOrder.Descending -> songsPlaylistByPositionDesc(id) - } - PlaylistSongSortBy.DateLiked -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByDateLikedAsc(id) - SortOrder.Descending -> songsPlaylistByDateLikedDesc(id) - } - PlaylistSongSortBy.DatePlayed -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByDatePlayedAsc(id) - SortOrder.Descending -> songsPlaylistByDatePlayedDesc(id) - } - PlaylistSongSortBy.AlbumYear -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByAlbumYearAsc(id) - SortOrder.Descending -> songsPlaylistByAlbumYearDesc(id) - } - PlaylistSongSortBy.Duration -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByDurationAsc(id) - SortOrder.Descending -> songsPlaylistByDurationDesc(id) - } - PlaylistSongSortBy.ArtistAndAlbum -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByArtistAndAlbumAsc(id) - SortOrder.Descending -> songsPlaylistByArtistAndAlbumDesc(id) - } - PlaylistSongSortBy.Album -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByAlbumAsc(id) - SortOrder.Descending -> songsPlaylistByAlbumDesc(id) - } - PlaylistSongSortBy.DateAdded -> when (sortOrder) { - SortOrder.Ascending -> songsPlaylistByRowIdAsc(id) - SortOrder.Descending -> songsPlaylistByRowIdDesc(id) + @Query(""" + SELECT S.*, Album.title as albumTitle + FROM Song S + INNER JOIN songplaylistmap SP ON S.id=SP.songId + LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id + LEFT JOIN Album ON Album.id = SongAlbumMap.albumId + WHERE SP.playlistId=:id + ORDER BY S.LikedAt COLLATE NOCASE + """) + fun sortSongsFromPlaylistByLikedAt( id: Long ): Flow> + + fun songsPlaylist(id: Long, sortBy: PlaylistSongSortBy, sortOrder: SortOrder): Flow> = + when( sortBy ) { + PlaylistSongSortBy.Album -> sortSongsFromPlaylistByAlbum( id ) + PlaylistSongSortBy.AlbumYear -> sortSongsFromPlaylistByYear( id ) + PlaylistSongSortBy.Artist -> sortSongsFromPlaylistByArtist( id ) + PlaylistSongSortBy.ArtistAndAlbum -> sortSongsFromPlaylistByArtistAndAlbum( id ) + PlaylistSongSortBy.DatePlayed -> sortSongsFromPlaylistByDatePlayed( id ) + PlaylistSongSortBy.PlayTime -> sortSongsFromPlaylistByPlaytime( id ) + PlaylistSongSortBy.Position -> sortSongsPlaylistByPosition( id ) + PlaylistSongSortBy.Title -> sortSongsFromPlaylistByTitle( id ) + PlaylistSongSortBy.Duration -> sortSongsFromPlaylistByDuration( id ) + PlaylistSongSortBy.DateLiked -> sortSongsFromPlaylistByLikedAt( id ) + PlaylistSongSortBy.DateAdded -> sortSongsFromPlaylistByRowId( id ) + }.map { + it.run { + if( sortOrder == SortOrder.Descending ) + reversed() + else + this } - } - } @Transaction @Query("SELECT S.* FROM Song S INNER JOIN songplaylistmap SP ON S.id=SP.songId WHERE SP.playlistId=:id ORDER BY SP.position LIMIT 4") diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Song.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Song.kt index b5c60a0de..ea125f9f5 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Song.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Song.kt @@ -3,6 +3,7 @@ package it.fast4x.rimusic.models import androidx.compose.runtime.Immutable import androidx.room.Entity import androidx.room.PrimaryKey +import it.fast4x.rimusic.cleanPrefix import it.fast4x.rimusic.utils.setLikeState import kotlinx.serialization.Serializable @@ -37,4 +38,6 @@ data class Song( likedAt = setLikeState(likedAt) ) } + + fun cleanTitle() = cleanPrefix( this.title ) } diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/service/modern/MediaLibrarySessionCallback.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/service/modern/MediaLibrarySessionCallback.kt index 7c1fe8e95..7298e36c5 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/service/modern/MediaLibrarySessionCallback.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/service/modern/MediaLibrarySessionCallback.kt @@ -33,7 +33,6 @@ import it.fast4x.rimusic.R import it.fast4x.rimusic.cleanPrefix import it.fast4x.rimusic.enums.MaxTopPlaylistItems import it.fast4x.rimusic.models.Song -import it.fast4x.rimusic.query import it.fast4x.rimusic.service.MyDownloadHelper import it.fast4x.rimusic.service.modern.MediaSessionConstants.ID_CACHED import it.fast4x.rimusic.service.modern.MediaSessionConstants.ID_DOWNLOADED @@ -52,7 +51,6 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.guava.future -import kotlinx.coroutines.launch import kotlinx.coroutines.plus import kotlinx.coroutines.runBlocking import javax.inject.Inject @@ -337,7 +335,7 @@ class MediaLibrarySessionCallback @Inject constructor( } } - else -> database.songsPlaylistByRowIdAsc(playlistId.toLong()) + else -> database.sortSongsFromPlaylistByRowId( playlistId.toLong() ) .map { list -> list.map { it.song } } @@ -456,7 +454,7 @@ class MediaLibrarySessionCallback @Inject constructor( } } - else -> database.songsPlaylistByRowIdAsc(playlistId.toLong()) + else -> database.sortSongsFromPlaylistByRowId( playlistId.toLong() ) .map { list -> list.map { it } } diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/home/HomeSongs.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/home/HomeSongs.kt index 38078643c..d00570b68 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/home/HomeSongs.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/home/HomeSongs.kt @@ -471,7 +471,9 @@ fun HomeSongs( itemsOnDisplay = withContext( Dispatchers.Default ) { items.filter( naturalFilter ) .filter { - val containsTitle = it.song.title.contains(search.input, true) + // Without cleaning, user can search explicit songs with "e:" + // I kinda want this to be a feature, but it seems unnecessary + val containsTitle = it.song.cleanTitle().contains(search.input, true) val containsArtist = it.song.artistsText?.contains(search.input, true) ?: false val containsAlbum = it.albumTitle?.contains(search.input, true) ?: false val isExplicit = parentalControlEnabled && it.song.title.startsWith(EXPLICIT_PREFIX) diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt index 35793f045..38205271f 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt @@ -6,7 +6,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -60,7 +59,6 @@ import com.github.doyaaaaaken.kotlincsv.client.KotlinCsvExperimental import it.fast4x.compose.persist.persist import it.fast4x.compose.persist.persistList import it.fast4x.compose.reordering.draggedItem -import it.fast4x.compose.reordering.localAnimateItemPlacement import it.fast4x.compose.reordering.rememberReorderingState import it.fast4x.compose.reordering.reorder import it.fast4x.innertube.Innertube @@ -409,7 +407,9 @@ fun LocalPlaylistSongs( else true }.filter { - val containsName = it.song.title.contains(search.input, true) + // Without cleaning, user can search explicit songs with "e:" + // I kinda want this to be a feature, but it seems unnecessary + val containsName = it.song.cleanTitle().contains(search.input, true) val containsArtist = it.song.artistsText?.contains(search.input, true) ?: false val containsAlbum = it.albumTitle?.contains(search.input, true) ?: false From 0f2035276d3a01fe0f8b7d3839267b8d4a4c55fe Mon Sep 17 00:00:00 2001 From: knighthat Date: Tue, 26 Nov 2024 19:59:13 -0600 Subject: [PATCH 2/2] join Format to get contentLength --- .../kotlin/it/fast4x/rimusic/Database.kt | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt index 1c9256025..662bc0d04 100644 --- a/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt +++ b/composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Database.kt @@ -935,12 +935,13 @@ interface Database { fun songsInAllMonthlyPlaylists(): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.artistsText COLLATE NOCASE """) fun sortSongsFromPlaylistByArtist( id: Long ): Flow> @@ -953,12 +954,13 @@ interface Database { * this sorting more accurate */ @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY CASE WHEN S.title LIKE "$EXPLICIT_PREFIX%" THEN SUBSTR(S.title, LENGTH('$EXPLICIT_PREFIX') + 1) @@ -969,101 +971,110 @@ interface Database { fun sortSongsFromPlaylistByTitle( id: Long ): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY SP.position """) fun sortSongsPlaylistByPosition( id: Long ): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.totalPlayTimeMs """) fun sortSongsFromPlaylistByPlaytime( id: Long ): Flow> @Query(""" - SELECT DISTINCT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN Event E ON E.songId=S.id LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY E.timestamp """) fun sortSongsFromPlaylistByDatePlayed( id: Long ): Flow> @Query(""" - SELECT DISTINCT S.*, A.title as albumTitle + SELECT DISTINCT S.*, A.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN songalbummap SA ON SA.songId=SP.songId LEFT JOIN Album A ON A.Id=SA.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY CAST(A.year AS INTEGER) """) fun sortSongsFromPlaylistByYear( id: Long ): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.durationText """) fun sortSongsFromPlaylistByDuration( id: Long ): Flow> @Query(""" - SELECT DISTINCT S.*, A.title as albumTitle + SELECT DISTINCT S.*, A.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN songalbummap SA ON SA.songId=SP.songId LEFT JOIN Album A ON A.Id=SA.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.artistsText COLLATE NOCASE, A.title COLLATE NOCASE """) fun sortSongsFromPlaylistByArtistAndAlbum( id: Long ): Flow> @Query(""" - SELECT DISTINCT S.*, A.title as albumTitle + SELECT DISTINCT S.*, A.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN songalbummap SA ON SA.songId=SP.songId LEFT JOIN Album A ON A.Id=SA.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY A.title COLLATE NOCASE """) fun sortSongsFromPlaylistByAlbum( id: Long ): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT DISTINCT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.ROWID """) fun sortSongsFromPlaylistByRowId( id: Long ): Flow> @Query(""" - SELECT S.*, Album.title as albumTitle + SELECT S.*, Album.title as albumTitle, Format.contentLength as contentLength FROM Song S - INNER JOIN songplaylistmap SP ON S.id=SP.songId + INNER JOIN songplaylistmap SP ON S.id = SP.songId LEFT JOIN SongAlbumMap ON SongAlbumMap.songId = S.id LEFT JOIN Album ON Album.id = SongAlbumMap.albumId - WHERE SP.playlistId=:id + LEFT JOIN Format ON Format.songId = S.id + WHERE SP.playlistId = :id ORDER BY S.LikedAt COLLATE NOCASE """) fun sortSongsFromPlaylistByLikedAt( id: Long ): Flow>