add item menus to the detail screens and now playing

Album, artist and playlist detail screens get a more button plus long-press on their song
and album rows; now playing gets a more button for the current song. Song menus can reach
the album and artist and star; the now-playing song is read from Room so its star state is
current.
This commit is contained in:
austinried
2026-10-04 00:29:59 +00:00
parent fb9e985680
commit d9e9a6b865
12 changed files with 208 additions and 16 deletions
@@ -611,6 +611,12 @@ interface LibraryDao {
artistId: String,
): Flow<Artist?>
@Query("SELECT * FROM songs WHERE sourceId = :sourceId AND id = :songId")
fun song(
sourceId: Long,
songId: String,
): Flow<Song?>
@Query("SELECT * FROM albums WHERE sourceId = :sourceId AND artistId = :artistId ORDER BY year DESC, name COLLATE NOCASE, id")
fun albumsForArtist(
sourceId: Long,
@@ -211,6 +211,11 @@ class LibraryRepository(
artistId: String,
): Flow<Artist?> = db.libraryDao().artist(sourceId, artistId)
fun song(
sourceId: Long,
songId: String,
): Flow<Song?> = db.libraryDao().song(sourceId, songId)
fun artistAlbums(
sourceId: Long,
artistId: String,
@@ -50,7 +50,7 @@ fun appModule(
viewModel { SettingsViewModel(get(), get()) }
viewModel { AddSourceViewModel(get(), get()) }
viewModel { params -> AlbumDetailViewModel(get(), get(), get(), params.get()) }
viewModel { params -> ArtistDetailViewModel(get(), get(), params.get()) }
viewModel { params -> ArtistDetailViewModel(get(), get(), get(), params.get()) }
viewModel { params -> PlaylistDetailViewModel(get(), get(), get(), params.get()) }
viewModel { QueueViewModel(get(), get()) }
}
@@ -250,6 +250,7 @@ private fun MainNavigation() {
.orEmpty()
.ifEmpty { null },
onBack = { navController.popBackStack() },
onViewArtist = { artistId -> navController.navigate(Routes.artist(artistId)) },
)
}
composable(
@@ -272,6 +273,7 @@ private fun MainNavigation() {
.ifEmpty { null },
onBack = { navController.popBackStack() },
onAlbumClick = { album -> navController.navigate(Routes.album(album.id, album.coverArt)) },
onViewAlbum = { albumId -> navController.navigate(Routes.album(albumId)) },
)
}
composable(
@@ -281,6 +283,8 @@ private fun MainNavigation() {
PlaylistDetailRoute(
playlistId = entry.arguments?.getString("playlistId").orEmpty(),
onBack = { navController.popBackStack() },
onViewAlbum = { albumId -> navController.navigate(Routes.album(albumId)) },
onViewArtist = { artistId -> navController.navigate(Routes.artist(artistId)) },
)
}
composable(Routes.ADD_SERVER) {
@@ -343,6 +347,14 @@ private fun MainNavigation() {
NowPlayingRoute(
onBack = { settleNowPlaying(false) },
onQueue = { showingQueue = true },
onViewAlbum = { albumId ->
settleNowPlaying(false)
navController.navigate(Routes.album(albumId))
},
onViewArtist = { artistId ->
settleNowPlaying(false)
navController.navigate(Routes.artist(artistId))
},
modifier = Modifier.fillMaxSize(),
)
}
@@ -64,14 +64,14 @@ sealed interface MenuTarget {
}
class ItemActions(
val playSong: (SongModel) -> Unit = {},
val playSong: ((SongModel) -> Unit)? = null,
val playAlbum: (AlbumModel) -> Unit = {},
val shuffleAlbum: (AlbumModel) -> Unit = {},
val playPlaylist: (PlaylistModel) -> Unit = {},
val shufflePlaylist: (PlaylistModel) -> Unit = {},
val setStar: (StarType, String, Boolean) -> Unit = { _, _, _ -> },
val viewAlbum: (String) -> Unit = {},
val viewArtist: (String) -> Unit = {},
val viewAlbum: ((String) -> Unit)? = null,
val viewArtist: ((String) -> Unit)? = null,
)
@OptIn(ExperimentalMaterial3Api::class)
@@ -89,15 +89,21 @@ fun ItemContextMenu(
MenuHeader(target)
when (target) {
is MenuTarget.Song -> {
MenuItem(Icons.Rounded.PlayArrow, "Play") { dismissThen { actions.playSong(target.song) } }
actions.playSong?.let { play ->
MenuItem(Icons.Rounded.PlayArrow, "Play") { dismissThen { play(target.song) } }
}
MenuItem(starIcon(target.song.starred), starLabel(target.song.starred)) {
dismissThen { actions.setStar(StarType.Song, target.song.id, target.song.starred == null) }
}
target.song.albumId?.let { albumId ->
MenuItem(Icons.Rounded.Album, "View album") { dismissThen { actions.viewAlbum(albumId) } }
actions.viewAlbum?.let { view ->
MenuItem(Icons.Rounded.Album, "View album") { dismissThen { view(albumId) } }
}
}
target.song.artistId?.let { artistId ->
MenuItem(Icons.Rounded.Person, "View artist") { dismissThen { actions.viewArtist(artistId) } }
actions.viewArtist?.let { view ->
MenuItem(Icons.Rounded.Person, "View artist") { dismissThen { view(artistId) } }
}
}
}
@@ -108,7 +114,9 @@ fun ItemContextMenu(
dismissThen { actions.setStar(StarType.Album, target.album.id, target.album.starred == null) }
}
target.album.artistId?.let { artistId ->
MenuItem(Icons.Rounded.Person, "View artist") { dismissThen { actions.viewArtist(artistId) } }
actions.viewArtist?.let { view ->
MenuItem(Icons.Rounded.Person, "View artist") { dismissThen { view(artistId) } }
}
}
}
@@ -1,6 +1,6 @@
package com.subtracks.ui.library
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
@@ -13,7 +13,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
@@ -28,6 +30,9 @@ import com.subtracks.data.model.Song
import com.subtracks.playback.PlaybackController
import com.subtracks.ui.components.HeroDetailScaffold
import com.subtracks.ui.components.HeroHeader
import com.subtracks.ui.components.ItemActions
import com.subtracks.ui.components.ItemContextMenu
import com.subtracks.ui.components.MenuTarget
import com.subtracks.ui.theme.ArtworkColors
import com.subtracks.ui.theme.rememberArtworkColors
import org.koin.compose.koinInject
@@ -42,6 +47,7 @@ fun AlbumDetailRoute(
albumId: String,
coverArtId: String?,
onBack: () -> Unit,
onViewArtist: (String) -> Unit,
viewModel: AlbumDetailViewModel = koinViewModel(key = albumId) { parametersOf(albumId) },
playbackController: PlaybackController = koinInject(),
) {
@@ -51,6 +57,15 @@ fun AlbumDetailRoute(
val playback by playbackController.state.collectAsStateWithLifecycle()
val context = playback.context
val shortcutArt = remember(coverArtId) { coverArtId?.let { viewModel.coverArt(it, true) } }
var menuTarget by remember { mutableStateOf<MenuTarget?>(null) }
val actions =
ItemActions(
playSong = { song -> songs.indexOfFirst { it.id == song.id }.takeIf { it >= 0 }?.let(viewModel::play) },
playAlbum = { viewModel.playAll() },
shuffleAlbum = { viewModel.shuffle() },
setStar = viewModel::setStar,
viewArtist = onViewArtist,
)
AlbumDetailScreen(
album = album,
songs = songs,
@@ -59,10 +74,15 @@ fun AlbumDetailRoute(
artwork = rememberArtworkColors(shortcutArt ?: viewModel.coverArt(album?.coverArt, true), THEME_TRANSITION_MS),
onBack = onBack,
onSongClick = viewModel::play,
onSongLongClick = { menuTarget = it },
onShuffle = viewModel::shuffle,
onPlay = viewModel::playAll,
onMore = { album?.let { menuTarget = MenuTarget.Album(it) } },
playingSongId = playback.item?.id.takeIf { context?.kind == QueueKind.Album && context.refId == albumId },
)
menuTarget?.let { target ->
ItemContextMenu(target = target, actions = actions, onDismiss = { menuTarget = null })
}
}
@Composable
@@ -74,6 +94,7 @@ fun AlbumDetailScreen(
artwork: ArtworkColors?,
onBack: () -> Unit,
onSongClick: (Int) -> Unit,
onSongLongClick: (MenuTarget) -> Unit = {},
onShuffle: () -> Unit = {},
onPlay: () -> Unit = { onSongClick(0) },
onDownload: () -> Unit = {},
@@ -137,7 +158,11 @@ fun AlbumDetailScreen(
song = song,
isPlaying = song.id == playingSongId,
trackNumber = song.track,
modifier = rowModifier.clickable { onSongClick(index) },
modifier =
rowModifier.combinedClickable(
onClick = { onSongClick(index) },
onLongClick = { onSongLongClick(MenuTarget.Song(song)) },
),
)
}
}
@@ -8,6 +8,7 @@ import com.subtracks.data.model.Disc
import com.subtracks.data.model.Song
import com.subtracks.data.repo.LibraryRepository
import com.subtracks.data.repo.SourceRepository
import com.subtracks.data.source.StarType
import com.subtracks.playback.PlaybackController
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -53,4 +54,12 @@ class AlbumDetailViewModel(
playbackController.shuffleAlbum(sourceId.first(), albumId)
}
}
fun setStar(
type: StarType,
id: String,
starred: Boolean,
) {
viewModelScope.launch { libraryRepository.setStar(type, id, starred) }
}
}
@@ -4,6 +4,7 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -27,6 +28,7 @@ import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.rounded.MoreHoriz
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -39,7 +41,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -58,6 +62,9 @@ import com.subtracks.data.model.Album
import com.subtracks.data.model.Artist
import com.subtracks.data.model.CoverArtRef
import com.subtracks.ui.components.CoverArt
import com.subtracks.ui.components.ItemActions
import com.subtracks.ui.components.ItemContextMenu
import com.subtracks.ui.components.MenuTarget
import com.subtracks.ui.components.rememberViewportFill
import com.subtracks.ui.theme.ArtworkColors
import com.subtracks.ui.theme.ArtworkTheme
@@ -83,6 +90,7 @@ fun ArtistDetailRoute(
coverArtId: String?,
onBack: () -> Unit,
onAlbumClick: (Album) -> Unit,
onViewAlbum: (String) -> Unit,
viewModel: ArtistDetailViewModel = koinViewModel(key = artistId) { parametersOf(artistId) },
) {
val artist by viewModel.artist.collectAsStateWithLifecycle(initialValue = null)
@@ -90,6 +98,14 @@ fun ArtistDetailRoute(
val art by viewModel.art.collectAsStateWithLifecycle()
val artThumbnail by viewModel.artThumbnail.collectAsStateWithLifecycle()
val shortcutArt = remember(coverArtId) { coverArtId?.let { viewModel.coverArt(it, true) } }
var menuTarget by remember { mutableStateOf<MenuTarget?>(null) }
val actions =
ItemActions(
playAlbum = { viewModel.playAlbum(it.id) },
shuffleAlbum = { viewModel.shuffleAlbum(it.id) },
setStar = viewModel::setStar,
viewAlbum = onViewAlbum,
)
ArtistDetailScreen(
artist = artist,
albums = albums,
@@ -99,7 +115,12 @@ fun ArtistDetailRoute(
coverArt = viewModel::coverArt,
onBack = onBack,
onAlbumClick = onAlbumClick,
onAlbumLongClick = { menuTarget = it },
onMore = { artist?.let { menuTarget = MenuTarget.Artist(it) } },
)
menuTarget?.let { target ->
ItemContextMenu(target = target, actions = actions, onDismiss = { menuTarget = null })
}
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -113,6 +134,8 @@ fun ArtistDetailScreen(
coverArt: (String?, Boolean) -> CoverArtRef?,
onBack: () -> Unit,
onAlbumClick: (Album) -> Unit,
onAlbumLongClick: (MenuTarget) -> Unit = {},
onMore: () -> Unit = {},
modifier: Modifier = Modifier,
) {
val listState = rememberLazyGridState()
@@ -213,7 +236,10 @@ fun ArtistDetailScreen(
.padding(
start = if (index % 2 == 0) 16.dp else 0.dp,
end = if (index % 2 == 1) 16.dp else 0.dp,
).clickable { onAlbumClick(album) },
).combinedClickable(
onClick = { onAlbumClick(album) },
onLongClick = { onAlbumLongClick(MenuTarget.Album(album)) },
),
) {
CoverArt(
ref = coverArt(album.coverArt, false),
@@ -267,6 +293,11 @@ fun ArtistDetailScreen(
Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = "Back")
}
},
actions = {
IconButton(onClick = onMore, modifier = Modifier.graphicsLayer { alpha = barFraction }) {
Icon(Icons.Rounded.MoreHoriz, contentDescription = "More options")
}
},
colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
modifier =
Modifier
@@ -7,6 +7,8 @@ import com.subtracks.data.model.Artist
import com.subtracks.data.model.CoverArtRef
import com.subtracks.data.repo.LibraryRepository
import com.subtracks.data.repo.SourceRepository
import com.subtracks.data.source.StarType
import com.subtracks.playback.PlaybackController
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -14,13 +16,15 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class)
class ArtistDetailViewModel(
libraryRepository: LibraryRepository,
private val libraryRepository: LibraryRepository,
private val sourceRepository: SourceRepository,
private val playbackController: PlaybackController,
private val artistId: String,
) : ViewModel() {
private val sourceId = libraryRepository.activeSourceId.filterNotNull()
@@ -63,4 +67,24 @@ class ArtistDetailViewModel(
coverArt: String?,
thumbnail: Boolean,
): CoverArtRef? = sourceRepository.coverArt(coverArt, thumbnail)
fun setStar(
type: StarType,
id: String,
starred: Boolean,
) {
viewModelScope.launch { libraryRepository.setStar(type, id, starred) }
}
fun playAlbum(albumId: String) {
viewModelScope.launch {
playbackController.playAlbum(sourceId.first(), albumId, 0)
}
}
fun shuffleAlbum(albumId: String) {
viewModelScope.launch {
playbackController.shuffleAlbum(sourceId.first(), albumId)
}
}
}
@@ -1,8 +1,11 @@
package com.subtracks.ui.library
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.paging.compose.LazyPagingItems
@@ -15,6 +18,9 @@ import com.subtracks.data.model.SongListItem
import com.subtracks.playback.PlaybackController
import com.subtracks.ui.components.HeroDetailScaffold
import com.subtracks.ui.components.HeroHeader
import com.subtracks.ui.components.ItemActions
import com.subtracks.ui.components.ItemContextMenu
import com.subtracks.ui.components.MenuTarget
import com.subtracks.ui.theme.ArtworkColors
import com.subtracks.ui.theme.rememberArtworkColors
import org.koin.compose.koinInject
@@ -28,12 +34,23 @@ private const val THEME_TRANSITION_MS = 100
fun PlaylistDetailRoute(
playlistId: String,
onBack: () -> Unit,
onViewAlbum: (String) -> Unit,
onViewArtist: (String) -> Unit,
viewModel: PlaylistDetailViewModel = koinViewModel(key = playlistId) { parametersOf(playlistId) },
playbackController: PlaybackController = koinInject(),
) {
val playlist by viewModel.playlist.collectAsStateWithLifecycle(initialValue = null)
val playback by playbackController.state.collectAsStateWithLifecycle()
val context = playback.context
var menuTarget by remember { mutableStateOf<MenuTarget?>(null) }
val actions =
ItemActions(
playPlaylist = { viewModel.playAll() },
shufflePlaylist = { viewModel.shuffle() },
setStar = viewModel::setStar,
viewAlbum = onViewAlbum,
viewArtist = onViewArtist,
)
PlaylistDetailScreen(
playlist = playlist,
songs = viewModel.songs.collectAsLazyPagingItems(),
@@ -41,10 +58,15 @@ fun PlaylistDetailRoute(
artwork = rememberArtworkColors(viewModel.coverArt(playlist?.coverArt, true), THEME_TRANSITION_MS),
onBack = onBack,
onSongClick = viewModel::play,
onSongLongClick = { menuTarget = it },
onShuffle = viewModel::shuffle,
onPlay = viewModel::playAll,
onMore = { playlist?.let { menuTarget = MenuTarget.Playlist(it) } },
playingSongId = playback.item?.id.takeIf { context?.kind == QueueKind.Playlist && context.refId == playlistId },
)
menuTarget?.let { target ->
ItemContextMenu(target = target, actions = actions, onDismiss = { menuTarget = null })
}
}
@Composable
@@ -55,8 +77,10 @@ fun PlaylistDetailScreen(
artwork: ArtworkColors?,
onBack: () -> Unit,
onSongClick: (Int) -> Unit,
onSongLongClick: (MenuTarget) -> Unit = {},
onShuffle: () -> Unit = {},
onPlay: () -> Unit = { onSongClick(0) },
onMore: () -> Unit = {},
playingSongId: String? = null,
modifier: Modifier = Modifier,
) {
@@ -75,7 +99,7 @@ fun PlaylistDetailScreen(
onPlay = onPlay,
onShuffle = onShuffle,
onDownload = {},
onMore = {},
onMore = onMore,
topInset = topInset,
controlsModifier = controlsModifier,
)
@@ -89,7 +113,11 @@ fun PlaylistDetailScreen(
coverArtId = item.coverArt,
coverArt = coverArt,
isPlaying = item.song.id == playingSongId,
modifier = rowModifier.clickable { onSongClick(index) },
modifier =
rowModifier.combinedClickable(
onClick = { onSongClick(index) },
onLongClick = { onSongLongClick(MenuTarget.Song(item.song)) },
),
)
}
}
@@ -9,6 +9,7 @@ import com.subtracks.data.model.Playlist
import com.subtracks.data.model.SongListItem
import com.subtracks.data.repo.LibraryRepository
import com.subtracks.data.repo.SourceRepository
import com.subtracks.data.source.StarType
import com.subtracks.playback.PlaybackController
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -55,4 +56,12 @@ class PlaylistDetailViewModel(
playbackController.shufflePlaylist(sourceId.first(), playlistId)
}
}
fun setStar(
type: StarType,
id: String,
starred: Boolean,
) {
viewModelScope.launch { libraryRepository.setStar(type, id, starred) }
}
}
@@ -43,7 +43,9 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -62,26 +64,45 @@ import coil3.request.CachePolicy
import coil3.request.ImageRequest
import com.subtracks.data.model.CoverArtRef
import com.subtracks.data.model.QueueKind
import com.subtracks.data.model.Song
import com.subtracks.data.repo.LibraryRepository
import com.subtracks.playback.PlaybackController
import com.subtracks.playback.PlaybackState
import com.subtracks.playback.RepeatMode
import com.subtracks.ui.components.CoverArt
import com.subtracks.ui.components.ItemActions
import com.subtracks.ui.components.ItemContextMenu
import com.subtracks.ui.components.MenuTarget
import com.subtracks.ui.theme.ArtworkColors
import com.subtracks.ui.theme.ArtworkSeedCache
import com.subtracks.ui.theme.ArtworkTheme
import com.subtracks.ui.theme.HeroGradient
import com.subtracks.ui.theme.rememberArtworkColors
import kotlinx.coroutines.launch
import org.koin.compose.koinInject
@Composable
fun NowPlayingRoute(
onBack: () -> Unit,
onQueue: () -> Unit,
onViewAlbum: (String) -> Unit,
onViewArtist: (String) -> Unit,
modifier: Modifier = Modifier,
controller: PlaybackController = koinInject(),
libraryRepository: LibraryRepository = koinInject(),
) {
val state by controller.state.collectAsStateWithLifecycle()
val positionMs by controller.positionMs.collectAsStateWithLifecycle()
val sourceId = state.context?.sourceId
val songId = state.item?.id
val song by
produceState<Song?>(null, sourceId, songId) {
if (sourceId != null && songId != null) {
libraryRepository.song(sourceId, songId).collect { value = it }
}
}
var menuTarget by remember { mutableStateOf<MenuTarget?>(null) }
val scope = rememberCoroutineScope()
val context = LocalPlatformContext.current
val art = controller.coverArt(state.item)
val thumbnail = controller.coverArt(state.item, thumbnail = true)
@@ -117,9 +138,22 @@ fun NowPlayingRoute(
onPrevious = controller::previous,
onShuffle = controller::toggleShuffle,
onRepeat = controller::cycleRepeat,
onMore = { song?.let { menuTarget = MenuTarget.Song(it) } },
onSeek = controller::seekTo,
modifier = modifier,
)
menuTarget?.let { target ->
ItemContextMenu(
target = target,
actions =
ItemActions(
setStar = { type, id, starred -> scope.launch { libraryRepository.setStar(type, id, starred) } },
viewAlbum = onViewAlbum,
viewArtist = onViewArtist,
),
onDismiss = { menuTarget = null },
)
}
}
internal fun prefetchImage(
@@ -159,6 +193,7 @@ fun NowPlayingScreen(
onPrevious: () -> Unit,
onShuffle: () -> Unit = {},
onRepeat: () -> Unit = {},
onMore: () -> Unit = {},
onSeek: (Long) -> Unit,
thumbnailRef: CoverArtRef? = null,
modifier: Modifier = Modifier,
@@ -395,7 +430,7 @@ fun NowPlayingScreen(
modifier = Modifier.size(30.dp),
)
}
IconButton(onClick = {}, modifier = Modifier.size(40.dp)) {
IconButton(onClick = onMore, modifier = Modifier.size(40.dp)) {
Icon(
imageVector = Icons.Rounded.MoreHoriz,
contentDescription = "More",