Skip to content

Commit

Permalink
Implemented shuffle songs from followeed artists #3640
Browse files Browse the repository at this point in the history
  • Loading branch information
fast4x committed Sep 12, 2024
1 parent b25bb73 commit b1e04fd
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 24 deletions.
5 changes: 5 additions & 0 deletions app/src/main/kotlin/it/fast4x/rimusic/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,11 @@ interface Database {
)
fun playlistSongs(id: Long): Flow<List<Song>?>

@Transaction
@Query("SELECT DISTINCT S.* FROM Song S INNER JOIN SongArtistMap SM ON S.id=SM.songId " +
"INNER JOIN Artist A ON A.id=SM.artistId WHERE A.bookmarkedAt IS NOT NULL")
fun songsInAllFollowedArtists(): Flow<List<Song>?>

@Transaction
@Query("SELECT DISTINCT S.* FROM Song S INNER JOIN songplaylistmap SM ON S.id=SM.songId")
fun songsInAllPlaylists(): Flow<List<Song>?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
Expand All @@ -66,11 +67,13 @@ import androidx.media3.common.util.UnstableApi
import it.fast4x.compose.persist.persistList
import it.fast4x.rimusic.Database
import it.fast4x.rimusic.LocalPlayerAwareWindowInsets
import it.fast4x.rimusic.LocalPlayerServiceBinder
import it.fast4x.rimusic.R
import it.fast4x.rimusic.enums.AlbumSortBy
import it.fast4x.rimusic.enums.ArtistSortBy
import it.fast4x.rimusic.enums.LibraryItemSize
import it.fast4x.rimusic.enums.NavigationBarPosition
import it.fast4x.rimusic.enums.PlaylistsType
import it.fast4x.rimusic.enums.SortOrder
import it.fast4x.rimusic.enums.ThumbnailRoundness
import it.fast4x.rimusic.enums.UiType
Expand All @@ -85,13 +88,15 @@ import it.fast4x.rimusic.ui.components.themed.IconButton
import it.fast4x.rimusic.ui.components.themed.Menu
import it.fast4x.rimusic.ui.components.themed.MenuEntry
import it.fast4x.rimusic.ui.components.themed.MultiFloatingActionsContainer
import it.fast4x.rimusic.ui.components.themed.SmartMessage
import it.fast4x.rimusic.ui.components.themed.SortMenu
import it.fast4x.rimusic.ui.components.themed.TitleSection
import it.fast4x.rimusic.ui.items.ArtistItem
import it.fast4x.rimusic.ui.styling.Dimensions
import it.fast4x.rimusic.ui.styling.LocalAppearance
import it.fast4x.rimusic.ui.styling.favoritesIcon
import it.fast4x.rimusic.ui.styling.px
import it.fast4x.rimusic.utils.PlayShuffledSongs
import it.fast4x.rimusic.utils.UiTypeKey
import it.fast4x.rimusic.utils.albumsItemSizeKey
import it.fast4x.rimusic.utils.artistSortByKey
Expand All @@ -105,6 +110,9 @@ import it.fast4x.rimusic.utils.semiBold
import it.fast4x.rimusic.utils.showFloatingIconKey
import it.fast4x.rimusic.utils.showSearchTabKey
import it.fast4x.rimusic.utils.thumbnailRoundnessKey
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.random.Random

@ExperimentalMaterial3Api
Expand Down Expand Up @@ -169,6 +177,9 @@ fun HomeArtistsModern(
thumbnailRoundnessKey,
ThumbnailRoundness.Heavy
)
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val binder = LocalPlayerServiceBinder.current

Box (
modifier = Modifier
Expand Down Expand Up @@ -282,6 +293,32 @@ fun HomeArtistsModern(
iconSize = 16.dp
)

HeaderIconButton(
icon = R.drawable.shuffle,
color = colorPalette.text,
iconSize = 24.dp,
onClick = {},
modifier = Modifier
.padding(horizontal = 4.dp)
.combinedClickable (
onClick = {
coroutineScope.launch {
withContext(Dispatchers.IO) {
Database.songsInAllFollowedArtists()
.collect { PlayShuffledSongs(songsList = it, binder = binder, context = context) }
}
}

},
onLongClick = {
SmartMessage(
context.resources.getString(R.string.shuffle),
context = context
)
}
)
)

HeaderIconButton(
onClick = {
menuState.display {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import it.fast4x.rimusic.utils.CheckMonthlyPlaylist
import it.fast4x.rimusic.utils.ImportPipedPlaylists
import it.fast4x.rimusic.utils.MONTHLY_PREFIX
import it.fast4x.rimusic.utils.MaxTopPlaylistItemsKey
import it.fast4x.rimusic.utils.PlayShuffledSongs
import it.fast4x.rimusic.utils.UiTypeKey
import it.fast4x.rimusic.utils.asMediaItem
import it.fast4x.rimusic.utils.autosyncKey
Expand Down Expand Up @@ -821,29 +822,5 @@ fun HomeLibraryModern(
*/


}
}

@OptIn(UnstableApi::class)
fun PlayShuffledSongs(songsList: List<Song>?, context: Context, binder: PlayerService.Binder?) {

if (songsList == null || binder == null) return

val maxSongsInQueue = context.preferences.getEnum(maxSongsInQueueKey, MaxSongs.`500`)

songsList.let { songs ->
if (songs.isNotEmpty() == true) {
val itemsLimited =
if (songs.size > maxSongsInQueue.number) songs.shuffled()
.take(maxSongsInQueue.number.toInt()) else songs

CoroutineScope(Dispatchers.Main).launch {
binder.stopRadio()
binder.player.forcePlayFromBeginning(
itemsLimited.shuffled()
.map(Song::asMediaItem)
)
}
}
}
}
35 changes: 35 additions & 0 deletions app/src/main/kotlin/it/fast4x/rimusic/utils/PlayShuffleSongs.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package it.fast4x.rimusic.utils

import android.content.Context
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
import it.fast4x.rimusic.enums.MaxSongs
import it.fast4x.rimusic.models.Song
import it.fast4x.rimusic.service.PlayerService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

@OptIn(UnstableApi::class)
fun PlayShuffledSongs(songsList: List<Song>?, context: Context, binder: PlayerService.Binder?) {

if (songsList == null || binder == null) return

val maxSongsInQueue = context.preferences.getEnum(maxSongsInQueueKey, MaxSongs.`500`)

songsList.let { songs ->
if (songs.isNotEmpty() == true) {
val itemsLimited =
if (songs.size > maxSongsInQueue.number) songs.shuffled()
.take(maxSongsInQueue.number.toInt()) else songs

CoroutineScope(Dispatchers.Main).launch {
binder.stopRadio()
binder.player.forcePlayFromBeginning(
itemsLimited.shuffled()
.map(Song::asMediaItem)
)
}
}
}
}

0 comments on commit b1e04fd

Please sign in to comment.