mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
More button & queue management
This commit is contained in:
parent
11e28a605c
commit
b48eb9898c
6 changed files with 265 additions and 116 deletions
|
|
@ -15,6 +15,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
|
|||
import com.github.damontecres.wholphin.services.hilt.AuthOkHttpClient
|
||||
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||
import com.github.damontecres.wholphin.ui.toServerString
|
||||
import com.github.damontecres.wholphin.util.BlockingList
|
||||
import com.github.damontecres.wholphin.util.profile.Codec
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -75,6 +76,33 @@ class MusicService
|
|||
setQueue(items, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the queue with the given list and starting playing the song as startIndex as soon as its ready
|
||||
*
|
||||
* Fetches each item in a blocking way and adds to the queue
|
||||
*/
|
||||
suspend fun setQueue(
|
||||
items: BlockingList<BaseItem?>,
|
||||
startIndex: Int,
|
||||
shuffled: Boolean,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
Timber.d("setQueue: %s items, startIndex=%s, shuffled=%s", items.size, startIndex, shuffled)
|
||||
withContext(Dispatchers.Main) {
|
||||
player.setMediaItems(emptyList())
|
||||
player.shuffleModeEnabled = shuffled
|
||||
player.play()
|
||||
}
|
||||
(startIndex..items.lastIndex).forEach {
|
||||
val item = items.getBlocking(it)
|
||||
if (item != null && item.type == BaseItemKind.AUDIO) {
|
||||
val mediaItem = convert(item)
|
||||
withContext(Dispatchers.Main) {
|
||||
player.addMediaItem(mediaItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setQueue(
|
||||
items: List<BaseItem>,
|
||||
shuffled: Boolean,
|
||||
|
|
@ -136,6 +164,8 @@ data class MusicServiceState(
|
|||
companion object {
|
||||
val EMPTY = MusicServiceState(emptyList(), 0, false)
|
||||
}
|
||||
|
||||
val currentItemId: UUID? get() = if (isPlaying) queue.getOrNull(currentIndex)?.id else null
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,35 +1,30 @@
|
|||
package com.github.damontecres.wholphin.ui.detail.music
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.focusGroup
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.FocusState
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.focusRestorer
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
|
@ -52,9 +47,9 @@ import com.github.damontecres.wholphin.services.MusicService
|
|||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.services.UserPreferencesService
|
||||
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||
import com.github.damontecres.wholphin.ui.components.ExpandableFaButton
|
||||
import com.github.damontecres.wholphin.ui.components.ExpandablePlayButton
|
||||
import com.github.damontecres.wholphin.ui.components.GenreText
|
||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||
import com.github.damontecres.wholphin.ui.components.OverviewText
|
||||
|
|
@ -85,7 +80,6 @@ import org.jellyfin.sdk.model.api.ItemSortBy
|
|||
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import kotlin.time.Duration
|
||||
|
||||
@HiltViewModel(assistedFactory = AlbumViewModel.Factory::class)
|
||||
class AlbumViewModel
|
||||
|
|
@ -93,7 +87,7 @@ class AlbumViewModel
|
|||
constructor(
|
||||
private val api: ApiClient,
|
||||
@param:ApplicationContext private val context: Context,
|
||||
private val navigationManager: NavigationManager,
|
||||
val navigationManager: NavigationManager,
|
||||
val serverRepository: ServerRepository,
|
||||
val mediaReportService: MediaReportService,
|
||||
private val favoriteWatchManager: FavoriteWatchManager,
|
||||
|
|
@ -111,6 +105,8 @@ class AlbumViewModel
|
|||
private val _state = MutableStateFlow(AlbumState.EMPTY)
|
||||
val state: StateFlow<AlbumState> = _state
|
||||
|
||||
val currentMusic = musicService.state
|
||||
|
||||
init {
|
||||
viewModelScope.launchIO {
|
||||
try {
|
||||
|
|
@ -169,16 +165,18 @@ class AlbumViewModel
|
|||
}
|
||||
}
|
||||
|
||||
fun setFavorite(favorite: Boolean) =
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
val album =
|
||||
api.userLibraryApi
|
||||
.getItem(itemId = itemId)
|
||||
.content
|
||||
.let { BaseItem(it, false) }
|
||||
_state.update { it.copy(album = album) }
|
||||
}
|
||||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
val album =
|
||||
api.userLibraryApi
|
||||
.getItem(itemId = itemId)
|
||||
.content
|
||||
.let { BaseItem(it, false) }
|
||||
_state.update { it.copy(album = album) }
|
||||
}
|
||||
|
||||
fun play(
|
||||
shuffled: Boolean,
|
||||
|
|
@ -187,12 +185,27 @@ class AlbumViewModel
|
|||
viewModelScope.launchIO {
|
||||
Timber.v("Playing album %s from %s", itemId, startIndex)
|
||||
val songs = state.value.songs as ApiRequestPager<*>
|
||||
val songsToAdd =
|
||||
(startIndex..songs.lastIndex)
|
||||
.mapNotNull { idx ->
|
||||
songs.getBlocking(idx)
|
||||
musicService.setQueue(songs, startIndex, shuffled)
|
||||
}
|
||||
}
|
||||
|
||||
fun addToQueue(
|
||||
itemId: UUID,
|
||||
index: Int,
|
||||
) {
|
||||
viewModelScope.launchIO {
|
||||
val songs = state.value.songs as ApiRequestPager<*>
|
||||
if (itemId == this@AlbumViewModel.itemId) {
|
||||
songs.indices.forEach {
|
||||
songs.getBlocking(it)?.let {
|
||||
musicService.addToQueue(it)
|
||||
}
|
||||
musicService.setQueue(songsToAdd, shuffled)
|
||||
}
|
||||
} else {
|
||||
songs.getBlocking(index)?.let {
|
||||
musicService.addToQueue(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,8 +238,22 @@ fun AlbumDetailsPage(
|
|||
creationCallback = { it.create(itemId) },
|
||||
),
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val state by viewModel.state.collectAsState()
|
||||
val currentMusic by viewModel.currentMusic.collectAsState()
|
||||
|
||||
var moreDialog by remember { mutableStateOf<DialogParams?>(null) }
|
||||
val moreDialogActions =
|
||||
remember {
|
||||
MusicMoreDialogActions(
|
||||
onNavigate = { viewModel.navigationManager.navigateTo(it) },
|
||||
onClickPlay = { index, _ -> viewModel.play(false, index) },
|
||||
onClickAddToQueue = { index, itemId -> viewModel.addToQueue(itemId, index) },
|
||||
onClickFavorite = { itemId, favorite -> viewModel.setFavorite(itemId, favorite) },
|
||||
onClickAddPlaylist = {},
|
||||
)
|
||||
}
|
||||
|
||||
when (val loading = state.loading) {
|
||||
is LoadingState.Error -> {
|
||||
|
|
@ -271,9 +298,25 @@ fun AlbumDetailsPage(
|
|||
MusicButtonActions(
|
||||
onClickPlay = { viewModel.play(it, 0) },
|
||||
onClickInstantMix = viewModel::startInstantMix,
|
||||
onClickFavorite = { viewModel.setFavorite(!album.favorite) },
|
||||
onClickFavorite = {
|
||||
viewModel.setFavorite(
|
||||
album.id,
|
||||
!album.favorite,
|
||||
)
|
||||
},
|
||||
onClickMore = {
|
||||
// TODO
|
||||
moreDialog =
|
||||
DialogParams(
|
||||
fromLongClick = false,
|
||||
title = album.name + " (${album.data.productionYear ?: ""})",
|
||||
items =
|
||||
buildMoreDialogForMusic(
|
||||
context = context,
|
||||
actions = moreDialogActions,
|
||||
item = album,
|
||||
index = 0,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
|
|
@ -295,16 +338,41 @@ fun AlbumDetailsPage(
|
|||
SongListItem(
|
||||
song = song,
|
||||
onClick = { viewModel.play(false, index) },
|
||||
onClickAddToQueue = {},
|
||||
onClickAddToPlaylist = {},
|
||||
onLongClick = {
|
||||
if (song != null) {
|
||||
moreDialog =
|
||||
DialogParams(
|
||||
fromLongClick = true,
|
||||
title = song.name ?: "",
|
||||
items =
|
||||
buildMoreDialogForMusic(
|
||||
context = context,
|
||||
actions = moreDialogActions,
|
||||
item = song,
|
||||
index = index,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
showArtist = false,
|
||||
isPlaying = song != null && currentMusic.currentItemId == song.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
moreDialog?.let { params ->
|
||||
DialogPopup(
|
||||
showDialog = true,
|
||||
title = params.title,
|
||||
dialogItems = params.items,
|
||||
onDismissRequest = { moreDialog = null },
|
||||
dismissOnClick = true,
|
||||
waitToLoad = params.fromLongClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -388,57 +456,3 @@ fun AlbumHeader(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AlbumButtons(
|
||||
onClickPlay: (Boolean) -> Unit,
|
||||
onClickAddToPlaylist: () -> Unit,
|
||||
onClickGoToArtist: () -> Unit,
|
||||
onClickMore: () -> Unit,
|
||||
buttonOnFocusChanged: (FocusState) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val firstFocus = remember { FocusRequester() }
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
modifier =
|
||||
modifier
|
||||
.focusGroup()
|
||||
.focusRestorer(firstFocus),
|
||||
) {
|
||||
item {
|
||||
ExpandablePlayButton(
|
||||
title = R.string.play,
|
||||
resume = Duration.ZERO,
|
||||
icon = Icons.Default.PlayArrow,
|
||||
onClick = { onClickPlay.invoke(false) },
|
||||
modifier =
|
||||
Modifier
|
||||
.onFocusChanged(buttonOnFocusChanged)
|
||||
.focusRequester(firstFocus),
|
||||
)
|
||||
}
|
||||
item {
|
||||
ExpandableFaButton(
|
||||
title = R.string.shuffle,
|
||||
iconStringRes = R.string.fa_shuffle,
|
||||
onClick = { onClickPlay.invoke(true) },
|
||||
modifier =
|
||||
Modifier
|
||||
.onFocusChanged(buttonOnFocusChanged),
|
||||
)
|
||||
}
|
||||
item {
|
||||
ExpandablePlayButton(
|
||||
title = R.string.go_to_artist,
|
||||
resume = Duration.ZERO,
|
||||
icon = Icons.Default.AccountCircle,
|
||||
onClick = { onClickGoToArtist.invoke() },
|
||||
modifier =
|
||||
Modifier
|
||||
.onFocusChanged(buttonOnFocusChanged),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,8 +113,7 @@ fun NowPlayingPage(
|
|||
onClick = {
|
||||
player.seekTo(index, 0L)
|
||||
},
|
||||
onClickAddToQueue = {},
|
||||
onClickAddToPlaylist = {},
|
||||
onLongClick = {},
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
package com.github.damontecres.wholphin.ui.detail.music
|
||||
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.Button
|
||||
import androidx.tv.material3.ButtonDefaults
|
||||
import androidx.tv.material3.Icon
|
||||
import androidx.tv.material3.ListItem
|
||||
import androidx.tv.material3.ListItemDefaults
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||
import com.github.damontecres.wholphin.ui.enableMarquee
|
||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.wholphin.ui.letNotEmpty
|
||||
import com.github.damontecres.wholphin.ui.roundMinutes
|
||||
|
|
@ -31,8 +36,7 @@ fun SongListDisplay(
|
|||
songs: List<BaseItem?>,
|
||||
showArtist: Boolean,
|
||||
onClick: (Int, BaseItem) -> Unit,
|
||||
onClickAddToQueue: (Int, BaseItem) -> Unit,
|
||||
onClickAddToPlaylist: (Int, BaseItem) -> Unit,
|
||||
onLongClick: (Int, BaseItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyColumn(
|
||||
|
|
@ -43,8 +47,7 @@ fun SongListDisplay(
|
|||
SongListItem(
|
||||
song = song,
|
||||
onClick = { song?.let { onClick.invoke(index, song) } },
|
||||
onClickAddToQueue = { song?.let { onClick.invoke(index, song) } },
|
||||
onClickAddToPlaylist = { song?.let { onClick.invoke(index, song) } },
|
||||
onLongClick = { song?.let { onLongClick.invoke(index, song) } },
|
||||
showArtist = showArtist,
|
||||
modifier = Modifier,
|
||||
)
|
||||
|
|
@ -56,10 +59,10 @@ fun SongListDisplay(
|
|||
fun SongListItem(
|
||||
song: BaseItem?,
|
||||
onClick: () -> Unit,
|
||||
onClickAddToQueue: () -> Unit,
|
||||
onClickAddToPlaylist: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
showArtist: Boolean = false,
|
||||
isPlaying: Boolean = false,
|
||||
) = SongListItem(
|
||||
title = song?.title,
|
||||
artist = if (showArtist) song?.data?.albumArtist else null,
|
||||
|
|
@ -71,10 +74,10 @@ fun SongListItem(
|
|||
?.ticks
|
||||
?.roundMinutes,
|
||||
onClick = onClick,
|
||||
onClickAddToQueue = onClickAddToQueue,
|
||||
onClickAddToPlaylist = onClickAddToPlaylist,
|
||||
onLongClick = onLongClick,
|
||||
modifier = modifier,
|
||||
showArtist = showArtist,
|
||||
isPlaying = isPlaying,
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
@ -84,27 +87,42 @@ fun SongListItem(
|
|||
indexNumber: Int?,
|
||||
runtime: Duration?,
|
||||
onClick: () -> Unit,
|
||||
onClickAddToQueue: () -> Unit,
|
||||
onClickAddToPlaylist: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
showArtist: Boolean = false,
|
||||
isPlaying: Boolean = false,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier,
|
||||
) {
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
ListItem(
|
||||
selected = isPlaying,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
interactionSource = interactionSource,
|
||||
leadingContent = {
|
||||
Text(
|
||||
text = indexNumber?.toString() ?: "",
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = indexNumber?.toString() ?: "",
|
||||
)
|
||||
if (isPlaying) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.PlayArrow,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = title ?: "",
|
||||
maxLines = 1,
|
||||
modifier = Modifier.enableMarquee(focused),
|
||||
)
|
||||
},
|
||||
supportingContent =
|
||||
|
|
@ -125,14 +143,6 @@ fun SongListItem(
|
|||
scale = ListItemDefaults.scale(1f, 1f, .95f),
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Button(
|
||||
onClick = onClickAddToQueue,
|
||||
shape = ButtonDefaults.shape(shape = RoundedCornerShape(8.dp)),
|
||||
) {
|
||||
Text(
|
||||
text = "Add to queue",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,21 +159,20 @@ fun SongListItemPreview() {
|
|||
indexNumber = 1,
|
||||
runtime = 2.minutes + 30.seconds,
|
||||
onClick = {},
|
||||
onClickAddToQueue = { },
|
||||
onClickAddToPlaylist = {},
|
||||
onLongClick = { },
|
||||
modifier = Modifier,
|
||||
showArtist = false,
|
||||
)
|
||||
SongListItem(
|
||||
title = "Song title",
|
||||
artist = "Artists",
|
||||
indexNumber = 1,
|
||||
indexNumber = 2,
|
||||
runtime = 2.minutes + 30.seconds,
|
||||
onClick = {},
|
||||
onClickAddToQueue = { },
|
||||
onClickAddToPlaylist = {},
|
||||
onLongClick = { },
|
||||
modifier = Modifier,
|
||||
showArtist = true,
|
||||
isPlaying = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
package com.github.damontecres.wholphin.ui.detail.music
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowForward
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.github.damontecres.wholphin.R
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.ui.components.DialogItem
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import org.jellyfin.sdk.model.UUID
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
|
||||
data class MusicMoreDialogActions(
|
||||
val onNavigate: (Destination) -> Unit,
|
||||
val onClickPlay: (Int, UUID) -> Unit,
|
||||
val onClickAddToQueue: (Int, UUID) -> Unit,
|
||||
val onClickFavorite: (UUID, Boolean) -> Unit,
|
||||
val onClickAddPlaylist: (UUID) -> Unit,
|
||||
val onClickGoToAlbum: (UUID) -> Unit = {
|
||||
onNavigate.invoke(Destination.MediaItem(itemId = it, type = BaseItemKind.MUSIC_ALBUM))
|
||||
},
|
||||
val onClickGoToArtist: (UUID) -> Unit = {
|
||||
onNavigate.invoke(Destination.MediaItem(itemId = it, type = BaseItemKind.MUSIC_ARTIST))
|
||||
},
|
||||
)
|
||||
|
||||
fun buildMoreDialogForMusic(
|
||||
context: Context,
|
||||
actions: MusicMoreDialogActions,
|
||||
item: BaseItem,
|
||||
index: Int,
|
||||
): List<DialogItem> =
|
||||
buildList {
|
||||
add(
|
||||
DialogItem(
|
||||
context.getString(R.string.play),
|
||||
Icons.Default.PlayArrow,
|
||||
iconColor = Color.Green.copy(alpha = .8f),
|
||||
) {
|
||||
actions.onClickPlay(index, item.id)
|
||||
},
|
||||
)
|
||||
add(
|
||||
DialogItem(
|
||||
context.getString(R.string.add_to_queue),
|
||||
Icons.Default.Add,
|
||||
) {
|
||||
actions.onClickAddToQueue(index, item.id)
|
||||
},
|
||||
)
|
||||
add(
|
||||
DialogItem(
|
||||
text = R.string.add_to_playlist,
|
||||
iconStringRes = R.string.fa_list_ul,
|
||||
) {
|
||||
actions.onClickAddPlaylist.invoke(item.id)
|
||||
},
|
||||
)
|
||||
add(
|
||||
DialogItem(
|
||||
text = if (item.favorite) R.string.remove_favorite else R.string.add_favorite,
|
||||
iconStringRes = R.string.fa_heart,
|
||||
iconColor = if (item.favorite) Color.Red else Color.Unspecified,
|
||||
) {
|
||||
actions.onClickFavorite.invoke(item.id, !item.favorite)
|
||||
},
|
||||
)
|
||||
if (item.type == BaseItemKind.AUDIO && item.data.albumId != null) {
|
||||
add(
|
||||
DialogItem(
|
||||
context.getString(R.string.go_to_album),
|
||||
Icons.Default.ArrowForward,
|
||||
) {
|
||||
actions.onClickGoToAlbum.invoke(item.data.albumId!!)
|
||||
},
|
||||
)
|
||||
}
|
||||
if ((item.type == BaseItemKind.AUDIO || item.type == BaseItemKind.MUSIC_ALBUM) && item.data.artistItems?.isNotEmpty() == true) {
|
||||
add(
|
||||
DialogItem(
|
||||
context.getString(R.string.go_to_artist),
|
||||
Icons.Default.ArrowForward,
|
||||
) {
|
||||
actions.onClickGoToArtist.invoke(
|
||||
item.data.artistItems!!
|
||||
.first()
|
||||
.id,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -498,6 +498,8 @@
|
|||
<string name="go_to_artist">Go to artist</string>
|
||||
<string name="now_playing">Now playing</string>
|
||||
<string name="instant_mix">Instant mix</string>
|
||||
<string name="go_to_album">Go to album</string>
|
||||
<string name="add_to_queue">Add to queue</string>
|
||||
|
||||
<string-array name="theme_song_volume">
|
||||
<item>Disabled</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue