@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
66import androidx.compose.foundation.layout.padding
77import androidx.compose.foundation.layout.size
88import androidx.compose.foundation.text.appendInlineContent
9+ import androidx.compose.material3.CircularProgressIndicator
910import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
1011import androidx.compose.material3.Icon
1112import androidx.compose.material3.ListItem
@@ -31,16 +32,24 @@ import kotlinx.collections.immutable.persistentListOf
3132import kotlinx.coroutines.launch
3233import navic.composeapp.generated.resources.Res
3334import navic.composeapp.generated.resources.action_add_to_queue
35+ import navic.composeapp.generated.resources.action_play_next
36+ import navic.composeapp.generated.resources.info_download_failed
37+ import navic.composeapp.generated.resources.info_downloaded
3438import navic.composeapp.generated.resources.info_unknown_album
3539import navic.composeapp.generated.resources.info_unknown_year
3640import org.jetbrains.compose.resources.stringResource
3741import paige.navic.LocalNavStack
42+ import paige.navic.data.database.entities.DownloadEntity
43+ import paige.navic.data.database.entities.DownloadStatus
3844import paige.navic.data.models.Screen
3945import paige.navic.data.models.settings.Settings
4046import paige.navic.domain.models.DomainExplicitStatus
4147import paige.navic.domain.models.DomainSong
4248import paige.navic.icons.Icons
49+ import paige.navic.icons.outlined.Check
50+ import paige.navic.icons.outlined.DownloadOff
4351import paige.navic.icons.outlined.Queue
52+ import paige.navic.icons.outlined.QueuePlayNext
4453import paige.navic.ui.components.common.CoverArt
4554import paige.navic.ui.components.common.MarqueeText
4655import paige.navic.ui.components.sheets.SongSheet
@@ -62,7 +71,11 @@ fun SongListScreenItem(
6271 onPlayNext : () -> Unit ,
6372 onAddToQueue : () -> Unit ,
6473 onClick : () -> Unit ,
65- onSetRating : (Int ) -> Unit
74+ onSetRating : (Int ) -> Unit ,
75+ download : DownloadEntity ? ,
76+ onDownload : () -> Unit ,
77+ onCancelDownload : () -> Unit ,
78+ onDeleteDownload : () -> Unit ,
6679) {
6780 val backStack = LocalNavStack .current
6881 val dismissState = rememberSwipeToDismissBoxState()
@@ -73,10 +86,9 @@ fun SongListScreenItem(
7386 modifier = modifier,
7487 state = dismissState,
7588 onDismiss = {
76- if (it == SwipeToDismissBoxValue .EndToStart ) onAddToQueue()
77- scope.launch {
78- dismissState.reset()
79- }
89+ if (it == SwipeToDismissBoxValue .StartToEnd ) onAddToQueue()
90+ if (it == SwipeToDismissBoxValue .EndToStart ) onPlayNext()
91+ scope.launch { dismissState.reset() }
8092 },
8193 backgroundContent = {
8294 Box (
@@ -87,15 +99,25 @@ fun SongListScreenItem(
8799 .padding(horizontal = 20 .dp),
88100 contentAlignment = Alignment .CenterEnd
89101 ) {
90- Icon (
91- imageVector = Icons .Outlined .Queue ,
92- contentDescription = stringResource(Res .string.action_add_to_queue),
93- tint = MaterialTheme .colorScheme.onPrimaryContainer,
94- modifier = Modifier .align(when (dismissState.dismissDirection) {
95- SwipeToDismissBoxValue .StartToEnd -> Alignment .CenterStart
96- else -> Alignment .CenterEnd
97- })
98- )
102+ when (dismissState.dismissDirection) {
103+ SwipeToDismissBoxValue .StartToEnd -> {
104+ Icon (
105+ imageVector = Icons .Outlined .Queue ,
106+ contentDescription = stringResource(Res .string.action_add_to_queue),
107+ tint = MaterialTheme .colorScheme.onPrimaryContainer,
108+ modifier = Modifier .align(Alignment .CenterStart )
109+ )
110+ }
111+ SwipeToDismissBoxValue .EndToStart -> {
112+ Icon (
113+ imageVector = Icons .Outlined .QueuePlayNext ,
114+ contentDescription = stringResource(Res .string.action_play_next),
115+ tint = MaterialTheme .colorScheme.onPrimaryContainer,
116+ modifier = Modifier .align(Alignment .CenterEnd )
117+ )
118+ }
119+ else -> {}
120+ }
99121 }
100122 }
101123 ) {
@@ -133,6 +155,36 @@ fun SongListScreenItem(
133155 modifier = Modifier .size(50 .dp),
134156 shape = ContinuousRoundedRectangle ((Settings .shared.artGridRounding / 1.75f ).dp)
135157 )
158+ },
159+ trailingContent = {
160+ if (download != null ) {
161+ when (download.status) {
162+ DownloadStatus .DOWNLOADING -> {
163+ CircularProgressIndicator (
164+ progress = { download.progress },
165+ modifier = Modifier .size(16 .dp),
166+ strokeWidth = 2 .dp
167+ )
168+ }
169+ DownloadStatus .DOWNLOADED -> {
170+ Icon (
171+ Icons .Outlined .Check ,
172+ contentDescription = stringResource(Res .string.info_downloaded),
173+ modifier = Modifier .size(16 .dp),
174+ tint = MaterialTheme .colorScheme.primary
175+ )
176+ }
177+ DownloadStatus .FAILED -> {
178+ Icon (
179+ Icons .Outlined .DownloadOff ,
180+ contentDescription = stringResource(Res .string.info_download_failed),
181+ modifier = Modifier .size(16 .dp),
182+ tint = MaterialTheme .colorScheme.error
183+ )
184+ }
185+ else -> {}
186+ }
187+ }
136188 }
137189 )
138190 if (selected) {
@@ -161,7 +213,11 @@ fun SongListScreenItem(
161213 onAddToPlaylist = {
162214 playlistDialogShown = true
163215 },
164- onSetRating = onSetRating
216+ onSetRating = onSetRating,
217+ downloadStatus = download?.status ? : DownloadStatus .NOT_DOWNLOADED ,
218+ onDownload = onDownload,
219+ onCancelDownload = onCancelDownload,
220+ onDeleteDownload = onDeleteDownload,
165221 )
166222 }
167223 }
0 commit comments