mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Add long click queue operations
This commit is contained in:
parent
6471b198b2
commit
73b626facd
10 changed files with 176 additions and 22 deletions
|
|
@ -9,6 +9,7 @@ import kotlin.time.Duration
|
||||||
data class AudioItem(
|
data class AudioItem(
|
||||||
val id: UUID,
|
val id: UUID,
|
||||||
val albumId: UUID?,
|
val albumId: UUID?,
|
||||||
|
val artistId: UUID?,
|
||||||
val title: String?,
|
val title: String?,
|
||||||
val albumTitle: String?,
|
val albumTitle: String?,
|
||||||
val artistNames: String?,
|
val artistNames: String?,
|
||||||
|
|
@ -24,6 +25,10 @@ data class AudioItem(
|
||||||
AudioItem(
|
AudioItem(
|
||||||
id = item.id,
|
id = item.id,
|
||||||
albumId = item.data.albumId,
|
albumId = item.data.albumId,
|
||||||
|
artistId =
|
||||||
|
item.data.artistItems
|
||||||
|
?.firstOrNull()
|
||||||
|
?.id,
|
||||||
title = item.title,
|
title = item.title,
|
||||||
albumTitle = item.data.album,
|
albumTitle = item.data.album,
|
||||||
artistNames = item.data.albumArtist,
|
artistNames = item.data.albumArtist,
|
||||||
|
|
|
||||||
|
|
@ -244,12 +244,30 @@ class MusicService
|
||||||
updateQueueSize()
|
updateQueueSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun moveQueue(
|
||||||
|
index: Int,
|
||||||
|
newIndex: Int,
|
||||||
|
) = withContext(Dispatchers.Main) {
|
||||||
|
player.moveMediaItem(index, newIndex)
|
||||||
|
updateQueueSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun playIndex(index: Int) {
|
||||||
|
onMain { player.seekTo(index, 0L) }
|
||||||
|
// MusicPlayerListener will update state
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun playNext(song: BaseItem) {
|
suspend fun playNext(song: BaseItem) {
|
||||||
val mediaItem = convert(song)
|
val mediaItem = convert(song)
|
||||||
onMain { player.addMediaItem(state.value.currentIndex + 1, mediaItem) }
|
onMain { player.addMediaItem(state.value.currentIndex + 1, mediaItem) }
|
||||||
updateQueueSize()
|
updateQueueSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun removeFromQueue(index: Int) {
|
||||||
|
onMain { player.removeMediaItem(index) }
|
||||||
|
updateQueueSize()
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun <T> loading(block: suspend () -> T): T {
|
private suspend fun <T> loading(block: suspend () -> T): T {
|
||||||
_state.update { it.copy(loadingState = LoadingState.Loading) }
|
_state.update { it.copy(loadingState = LoadingState.Loading) }
|
||||||
val result = block.invoke()
|
val result = block.invoke()
|
||||||
|
|
@ -336,17 +354,6 @@ private class MusicPlayerListener(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PlayerMediaItemList(
|
|
||||||
private val player: Player,
|
|
||||||
) {
|
|
||||||
val size: Int get() = player.mediaItemCount
|
|
||||||
|
|
||||||
operator fun get(index: Int): AudioItem {
|
|
||||||
// Timber.v("get %s", index)
|
|
||||||
return player.getMediaItemAt(index).localConfiguration?.tag as AudioItem
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun rememberQueue(
|
fun rememberQueue(
|
||||||
player: Player,
|
player: Player,
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,7 @@ fun AlbumDetailsPage(
|
||||||
playlistViewModel.loadPlaylists(MediaType.AUDIO)
|
playlistViewModel.loadPlaylists(MediaType.AUDIO)
|
||||||
showPlaylistDialog.makePresent(itemId)
|
showPlaylistDialog.makePresent(itemId)
|
||||||
},
|
},
|
||||||
|
onClickRemoveFromQueue = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,6 +363,7 @@ fun AlbumDetailsPage(
|
||||||
actions = moreDialogActions,
|
actions = moreDialogActions,
|
||||||
item = album,
|
item = album,
|
||||||
index = 0,
|
index = 0,
|
||||||
|
canRemove = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -404,6 +406,7 @@ fun AlbumDetailsPage(
|
||||||
actions = moreDialogActions,
|
actions = moreDialogActions,
|
||||||
item = song,
|
item = song,
|
||||||
index = index,
|
index = index,
|
||||||
|
canRemove = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,7 @@ fun ArtistDetailsPage(
|
||||||
playlistViewModel.loadPlaylists(MediaType.AUDIO)
|
playlistViewModel.loadPlaylists(MediaType.AUDIO)
|
||||||
showPlaylistDialog.makePresent(itemId)
|
showPlaylistDialog.makePresent(itemId)
|
||||||
},
|
},
|
||||||
|
onClickRemoveFromQueue = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,6 +370,7 @@ fun ArtistDetailsPage(
|
||||||
actions = moreDialogActions,
|
actions = moreDialogActions,
|
||||||
item = artist,
|
item = artist,
|
||||||
index = 0,
|
index = 0,
|
||||||
|
canRemove = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -408,6 +410,7 @@ fun ArtistDetailsPage(
|
||||||
actions = moreDialogActions,
|
actions = moreDialogActions,
|
||||||
item = song,
|
item = song,
|
||||||
index = index,
|
index = index,
|
||||||
|
canRemove = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ fun NowPlayingOverlay(
|
||||||
current: AudioItem?,
|
current: AudioItem?,
|
||||||
queue: List<AudioItem>,
|
queue: List<AudioItem>,
|
||||||
controllerViewState: ControllerViewState,
|
controllerViewState: ControllerViewState,
|
||||||
|
onClickSong: (Int, AudioItem) -> Unit,
|
||||||
|
onLongClickSong: (Int, AudioItem) -> Unit,
|
||||||
onClickMore: () -> Unit,
|
onClickMore: () -> Unit,
|
||||||
onMoveQueue: (Int, MoveDirection) -> Unit,
|
onMoveQueue: (Int, MoveDirection) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -159,10 +161,8 @@ fun NowPlayingOverlay(
|
||||||
runtime = song.runtime?.roundSeconds,
|
runtime = song.runtime?.roundSeconds,
|
||||||
showArtist = true,
|
showArtist = true,
|
||||||
isPlaying = current?.id == song.id,
|
isPlaying = current?.id == song.id,
|
||||||
onClick = {
|
onClick = { onClickSong.invoke(index, song) },
|
||||||
player.seekTo(index, 0L)
|
onLongClick = { onLongClickSong.invoke(index, song) },
|
||||||
},
|
|
||||||
onLongClick = {},
|
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
@ -42,6 +43,8 @@ import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.services.rememberQueue
|
import com.github.damontecres.wholphin.services.rememberQueue
|
||||||
import com.github.damontecres.wholphin.ui.AppColors
|
import com.github.damontecres.wholphin.ui.AppColors
|
||||||
|
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||||
|
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
||||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||||
import com.github.damontecres.wholphin.ui.playback.BottomDialog
|
import com.github.damontecres.wholphin.ui.playback.BottomDialog
|
||||||
import com.github.damontecres.wholphin.ui.playback.BottomDialogItem
|
import com.github.damontecres.wholphin.ui.playback.BottomDialogItem
|
||||||
|
|
@ -59,6 +62,7 @@ fun NowPlayingPage(
|
||||||
creationCallback = { it.create() },
|
creationCallback = { it.create() },
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
val player = viewModel.player
|
val player = viewModel.player
|
||||||
val queue = rememberQueue(player, state.musicServiceState.queueSize)
|
val queue = rememberQueue(player, state.musicServiceState.queueSize)
|
||||||
|
|
@ -97,9 +101,20 @@ fun NowPlayingPage(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val actions =
|
||||||
|
remember {
|
||||||
|
MusicQueueDialogActions(
|
||||||
|
onNavigate = { viewModel.navigationManager.navigateTo(it) },
|
||||||
|
onClickPlay = { index, _ -> viewModel.play(index) },
|
||||||
|
onClickPlayNext = { index, _ -> viewModel.playNext(index) },
|
||||||
|
onClickRemoveFromQueue = { index, _ -> viewModel.removeFromQueue(index) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var showMoreDialog by remember { mutableStateOf(false) }
|
var showMoreDialog by remember { mutableStateOf(false) }
|
||||||
var lyricsActive by remember { mutableStateOf(true) }
|
var lyricsActive by remember { mutableStateOf(true) }
|
||||||
var showDebugInfo by remember { mutableStateOf(true) }
|
var showDebugInfo by remember { mutableStateOf(true) }
|
||||||
|
var itemMoreDialog by remember { mutableStateOf<DialogParams?>(null) }
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
|
||||||
|
|
@ -189,6 +204,22 @@ fun NowPlayingPage(
|
||||||
controllerViewState = controllerViewState,
|
controllerViewState = controllerViewState,
|
||||||
onMoveQueue = { index, direction -> viewModel.moveQueue(index, direction) },
|
onMoveQueue = { index, direction -> viewModel.moveQueue(index, direction) },
|
||||||
onClickMore = { showMoreDialog = true },
|
onClickMore = { showMoreDialog = true },
|
||||||
|
onClickSong = { index, _ -> viewModel.play(index) },
|
||||||
|
onLongClickSong = { index, song ->
|
||||||
|
itemMoreDialog =
|
||||||
|
DialogParams(
|
||||||
|
title = song.title ?: "",
|
||||||
|
fromLongClick = true,
|
||||||
|
items =
|
||||||
|
buildMoreDialogForMusicQueue(
|
||||||
|
context = context,
|
||||||
|
actions = actions,
|
||||||
|
item = song,
|
||||||
|
index = index,
|
||||||
|
canRemove = true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.background(AppColors.TransparentBlack50)
|
.background(AppColors.TransparentBlack50)
|
||||||
|
|
@ -199,6 +230,16 @@ fun NowPlayingPage(
|
||||||
LoadingPage(focusEnabled = false)
|
LoadingPage(focusEnabled = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
itemMoreDialog?.let { params ->
|
||||||
|
DialogPopup(
|
||||||
|
showDialog = true,
|
||||||
|
title = params.title,
|
||||||
|
dialogItems = params.items,
|
||||||
|
onDismissRequest = { itemMoreDialog = null },
|
||||||
|
dismissOnClick = true,
|
||||||
|
waitToLoad = params.fromLongClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
if (showMoreDialog) {
|
if (showMoreDialog) {
|
||||||
NowPlayingBottomDialog(
|
NowPlayingBottomDialog(
|
||||||
showDebugInfo = showDebugInfo,
|
showDebugInfo = showDebugInfo,
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class NowPlayingViewModel
|
||||||
constructor(
|
constructor(
|
||||||
private val api: ApiClient,
|
private val api: ApiClient,
|
||||||
@param:ApplicationContext private val context: Context,
|
@param:ApplicationContext private val context: Context,
|
||||||
private val navigationManager: NavigationManager,
|
val navigationManager: NavigationManager,
|
||||||
private val favoriteWatchManager: FavoriteWatchManager,
|
private val favoriteWatchManager: FavoriteWatchManager,
|
||||||
private val backdropService: BackdropService,
|
private val backdropService: BackdropService,
|
||||||
private val imageUrlService: ImageUrlService,
|
private val imageUrlService: ImageUrlService,
|
||||||
|
|
@ -127,7 +127,7 @@ class NowPlayingViewModel
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
Timber.v("lyricIndex=$lyricIndex")
|
// Timber.v("lyricIndex=$lyricIndex")
|
||||||
state.update {
|
state.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
lyrics = lyrics,
|
lyrics = lyrics,
|
||||||
|
|
@ -178,6 +178,12 @@ class NowPlayingViewModel
|
||||||
direction: MoveDirection,
|
direction: MoveDirection,
|
||||||
) = viewModelScope.launchDefault { musicService.moveQueue(index, direction) }
|
) = viewModelScope.launchDefault { musicService.moveQueue(index, direction) }
|
||||||
|
|
||||||
|
fun play(index: Int) = viewModelScope.launchDefault { musicService.playIndex(index) }
|
||||||
|
|
||||||
|
fun playNext(index: Int) = viewModelScope.launchDefault { musicService.moveQueue(index, 1) }
|
||||||
|
|
||||||
|
fun removeFromQueue(index: Int) = viewModelScope.launchDefault { musicService.removeFromQueue(index) }
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
player.stop()
|
player.stop()
|
||||||
navigationManager.goBack()
|
navigationManager.goBack()
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||||
import com.github.damontecres.wholphin.ui.enableMarquee
|
import com.github.damontecres.wholphin.ui.enableMarquee
|
||||||
import com.github.damontecres.wholphin.ui.letNotEmpty
|
import com.github.damontecres.wholphin.ui.letNotEmpty
|
||||||
import com.github.damontecres.wholphin.ui.roundMinutes
|
import com.github.damontecres.wholphin.ui.roundMinutes
|
||||||
|
import com.github.damontecres.wholphin.ui.roundSeconds
|
||||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||||
import org.jellyfin.sdk.model.extensions.ticks
|
import org.jellyfin.sdk.model.extensions.ticks
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
@ -68,11 +69,13 @@ fun SongListItem(
|
||||||
artist = if (showArtist) song?.data?.albumArtist else null,
|
artist = if (showArtist) song?.data?.albumArtist else null,
|
||||||
indexNumber = song?.data?.indexNumber,
|
indexNumber = song?.data?.indexNumber,
|
||||||
runtime =
|
runtime =
|
||||||
song
|
remember(song) {
|
||||||
?.data
|
song
|
||||||
?.runTimeTicks
|
?.data
|
||||||
?.ticks
|
?.runTimeTicks
|
||||||
?.roundMinutes,
|
?.ticks
|
||||||
|
?.roundSeconds
|
||||||
|
},
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ import android.content.Context
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.ArrowForward
|
import androidx.compose.material.icons.filled.ArrowForward
|
||||||
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
|
import com.github.damontecres.wholphin.data.model.AudioItem
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogItem
|
import com.github.damontecres.wholphin.ui.components.DialogItem
|
||||||
|
|
@ -34,6 +36,7 @@ data class MusicMoreDialogActions(
|
||||||
val onClickGoToArtist: (UUID) -> Unit = {
|
val onClickGoToArtist: (UUID) -> Unit = {
|
||||||
onNavigate.invoke(Destination.MediaItem(itemId = it, type = BaseItemKind.MUSIC_ARTIST))
|
onNavigate.invoke(Destination.MediaItem(itemId = it, type = BaseItemKind.MUSIC_ARTIST))
|
||||||
},
|
},
|
||||||
|
val onClickRemoveFromQueue: (Int) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun buildMoreDialogForMusic(
|
fun buildMoreDialogForMusic(
|
||||||
|
|
@ -41,6 +44,7 @@ fun buildMoreDialogForMusic(
|
||||||
actions: MusicMoreDialogActions,
|
actions: MusicMoreDialogActions,
|
||||||
item: BaseItem,
|
item: BaseItem,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
canRemove: Boolean,
|
||||||
): List<DialogItem> =
|
): List<DialogItem> =
|
||||||
buildList {
|
buildList {
|
||||||
add(
|
add(
|
||||||
|
|
@ -61,6 +65,16 @@ fun buildMoreDialogForMusic(
|
||||||
actions.onClickPlayNext(index, item)
|
actions.onClickPlayNext(index, item)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
if (canRemove) {
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.remove_from_queue),
|
||||||
|
Icons.Default.Delete,
|
||||||
|
) {
|
||||||
|
actions.onClickRemoveFromQueue(index)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
add(
|
add(
|
||||||
DialogItem(
|
DialogItem(
|
||||||
context.getString(R.string.add_to_queue),
|
context.getString(R.string.add_to_queue),
|
||||||
|
|
@ -112,6 +126,77 @@ fun buildMoreDialogForMusic(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class MusicQueueDialogActions(
|
||||||
|
val onNavigate: (Destination) -> Unit,
|
||||||
|
val onClickPlay: (Int, AudioItem) -> Unit,
|
||||||
|
val onClickPlayNext: (Int, AudioItem) -> 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))
|
||||||
|
},
|
||||||
|
val onClickRemoveFromQueue: (Int, AudioItem) -> Unit,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun buildMoreDialogForMusicQueue(
|
||||||
|
context: Context,
|
||||||
|
actions: MusicQueueDialogActions,
|
||||||
|
item: AudioItem,
|
||||||
|
index: Int,
|
||||||
|
canRemove: Boolean,
|
||||||
|
): List<DialogItem> =
|
||||||
|
buildList {
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.play),
|
||||||
|
Icons.Default.PlayArrow,
|
||||||
|
iconColor = Color.Green.copy(alpha = .8f),
|
||||||
|
) {
|
||||||
|
actions.onClickPlay(index, item)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.play_next),
|
||||||
|
Icons.Default.PlayArrow,
|
||||||
|
iconColor = Color.Green.copy(alpha = .8f),
|
||||||
|
) {
|
||||||
|
actions.onClickPlayNext(index, item)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (canRemove) {
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.remove_from_queue),
|
||||||
|
Icons.Default.Delete,
|
||||||
|
) {
|
||||||
|
actions.onClickRemoveFromQueue(index, item)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (item.albumId != null) {
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.go_to_album),
|
||||||
|
Icons.Default.ArrowForward,
|
||||||
|
) {
|
||||||
|
actions.onClickGoToAlbum.invoke(item.albumId)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (item.artistId != null) {
|
||||||
|
add(
|
||||||
|
DialogItem(
|
||||||
|
context.getString(R.string.go_to_artist),
|
||||||
|
Icons.Default.ArrowForward,
|
||||||
|
) {
|
||||||
|
actions.onClickGoToArtist.invoke(item.artistId)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun ViewModel.getPagerForAlbum(
|
suspend fun ViewModel.getPagerForAlbum(
|
||||||
api: ApiClient,
|
api: ApiClient,
|
||||||
albumId: UUID,
|
albumId: UUID,
|
||||||
|
|
|
||||||
|
|
@ -737,6 +737,7 @@
|
||||||
<string name="hide_lyrics">Hide lyrics</string>
|
<string name="hide_lyrics">Hide lyrics</string>
|
||||||
<string name="show_lyrics">Show lyrics</string>
|
<string name="show_lyrics">Show lyrics</string>
|
||||||
<string name="song_has_lyrics">Song has lyrics</string>
|
<string name="song_has_lyrics">Song has lyrics</string>
|
||||||
|
<string name="remove_from_queue">Remove from queue</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue