Skip to content

Commit

Permalink
feat(queue): multiselect songs #38
Browse files Browse the repository at this point in the history
  • Loading branch information
Malopieds committed Apr 17, 2024
1 parent 81c74fd commit 8291511
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 45 deletions.
189 changes: 188 additions & 1 deletion app/src/main/java/com/zionhuang/music/ui/menu/SelectionSongsMenu.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.media3.common.Timeline
import androidx.media3.exoplayer.offline.Download
import androidx.media3.exoplayer.offline.DownloadRequest
import androidx.media3.exoplayer.offline.DownloadService
Expand All @@ -30,6 +31,7 @@ import com.zionhuang.music.R
import com.zionhuang.music.db.entities.PlaylistSongMap
import com.zionhuang.music.db.entities.Song
import com.zionhuang.music.extensions.toMediaItem
import com.zionhuang.music.models.MediaMetadata
import com.zionhuang.music.playback.ExoDownloadService
import com.zionhuang.music.playback.queues.ListQueue
import com.zionhuang.music.ui.component.DefaultDialog
Expand Down Expand Up @@ -222,4 +224,189 @@ fun SelectionSongMenu(
}
}
}
}
}

@Composable
fun SelectionMediaMetadataMenu(
songSelection: List<MediaMetadata>,
currentItems: List<Timeline.Window>,
onDismiss: () -> Unit,
clearAction: () -> Unit,
){
val context = LocalContext.current
val database = LocalDatabase.current
val downloadUtil = LocalDownloadUtil.current
val playerConnection = LocalPlayerConnection.current ?: return

var downloadState by remember {
mutableStateOf(Download.STATE_STOPPED)
}

LaunchedEffect(songSelection) {
if (songSelection.isEmpty()) return@LaunchedEffect
downloadUtil.downloads.collect { downloads ->
downloadState =
if (songSelection.all { downloads[it.id]?.state == Download.STATE_COMPLETED })
Download.STATE_COMPLETED
else if (songSelection.all {
downloads[it.id]?.state == Download.STATE_QUEUED
|| downloads[it.id]?.state == Download.STATE_DOWNLOADING
|| downloads[it.id]?.state == Download.STATE_COMPLETED
})
Download.STATE_DOWNLOADING
else
Download.STATE_STOPPED
}
}

var showChoosePlaylistDialog by rememberSaveable {
mutableStateOf(false)
}

AddToPlaylistDialog(
isVisible = showChoosePlaylistDialog,
onAdd = { playlist ->
database.query {
songSelection.forEach { song ->
insert(
PlaylistSongMap(
songId = song.id,
playlistId = playlist.id,
position = playlist.songCount
)
)
}
}
},
onDismiss = { showChoosePlaylistDialog = false }
)

var showRemoveDownloadDialog by remember {
mutableStateOf(false)
}

if (showRemoveDownloadDialog) {
DefaultDialog(
onDismiss = { showRemoveDownloadDialog = false },
content = {
Text(
text = stringResource(R.string.remove_download_playlist_confirm, "selection"),
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(horizontal = 18.dp)
)
},
buttons = {
TextButton(
onClick = {
showRemoveDownloadDialog = false
}
) {
Text(text = stringResource(android.R.string.cancel))
}

TextButton(
onClick = {
showRemoveDownloadDialog = false
songSelection.forEach { song ->
DownloadService.sendRemoveDownload(
context,
ExoDownloadService::class.java,
song.id,
false
)
}
}
) {
Text(text = stringResource(android.R.string.ok))
}
}
)
}

GridMenu (
contentPadding = PaddingValues(
start = 8.dp,
top = 8.dp,
end = 8.dp,
bottom = 8.dp + WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
)
){
GridMenuItem(
icon = R.drawable.delete,
title = R.string.delete
) {
onDismiss()
var i = 0
currentItems.forEach { cur ->
playerConnection.player.removeMediaItem(cur.firstPeriodIndex - i)
i++
}
clearAction()
}

GridMenuItem(
icon = R.drawable.play,
title = R.string.play
) {
onDismiss()
playerConnection.playQueue(
ListQueue(
title = "Selection",
items = songSelection.map { it.toMediaItem() }
)
)
clearAction()
}

GridMenuItem(
icon = R.drawable.shuffle,
title = R.string.shuffle
) {
onDismiss()
playerConnection.playQueue(
ListQueue(
title = "Selection",
items = songSelection.shuffled().map { it.toMediaItem() }
)
)
clearAction()
}

GridMenuItem(
icon = R.drawable.queue_music,
title = R.string.add_to_queue
) {
onDismiss()
playerConnection.addToQueue(songSelection.map { it.toMediaItem() })
clearAction()
}

GridMenuItem(
icon = R.drawable.playlist_add,
title = R.string.add_to_playlist
) {
showChoosePlaylistDialog = true
}

DownloadGridMenu(
state = downloadState,
onDownload = {
songSelection.forEach { song ->
val downloadRequest = DownloadRequest.Builder(song.id, song.id.toUri())
.setCustomCacheKey(song.id)
.setData(song.title.toByteArray())
.build()
DownloadService.sendAddDownload(
context,
ExoDownloadService::class.java,
downloadRequest,
false
)
}
},
onRemoveDownload = {
showRemoveDownloadDialog = true
}
)
}
}
Loading

0 comments on commit 8291511

Please sign in to comment.