diff --git a/src/main/kotlin/ca/gosyer/data/download/model/DownloadChapter.kt b/src/main/kotlin/ca/gosyer/data/download/model/DownloadChapter.kt index 2698f781..555559db 100644 --- a/src/main/kotlin/ca/gosyer/data/download/model/DownloadChapter.kt +++ b/src/main/kotlin/ca/gosyer/data/download/model/DownloadChapter.kt @@ -7,14 +7,16 @@ package ca.gosyer.data.download.model import ca.gosyer.data.models.Chapter +import ca.gosyer.data.models.Manga import kotlinx.serialization.Serializable @Serializable data class DownloadChapter( val chapterIndex: Int, val mangaId: Long, + val chapter: Chapter, + val manga: Manga, val state: DownloadState = DownloadState.Queued, val progress: Float = 0f, - val tries: Int = 0, - val chapter: Chapter? = null, + val tries: Int = 0 ) diff --git a/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenu.kt b/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenu.kt index 5e9bf782..ac608cd9 100644 --- a/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenu.kt +++ b/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenu.kt @@ -7,11 +7,10 @@ package ca.gosyer.ui.downloads import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -20,11 +19,9 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.ContentAlpha import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon import androidx.compose.material.LinearProgressIndicator -import androidx.compose.material.LocalContentColor import androidx.compose.material.MaterialTheme import androidx.compose.material.ProgressIndicatorDefaults import androidx.compose.material.Surface @@ -38,7 +35,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.FilterQuality +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import ca.gosyer.build.BuildConfig import ca.gosyer.data.download.model.DownloadChapter @@ -46,11 +45,19 @@ import ca.gosyer.data.download.model.DownloaderStatus import ca.gosyer.data.models.Chapter import ca.gosyer.ui.base.components.ActionIcon import ca.gosyer.ui.base.components.DropdownIconButton +import ca.gosyer.ui.base.components.MangaListItem +import ca.gosyer.ui.base.components.MangaListItemColumn +import ca.gosyer.ui.base.components.MangaListItemImage +import ca.gosyer.ui.base.components.MangaListItemSubtitle +import ca.gosyer.ui.base.components.MangaListItemTitle import ca.gosyer.ui.base.components.Toolbar +import ca.gosyer.ui.base.components.mangaAspectRatio import ca.gosyer.ui.base.resources.stringResource import ca.gosyer.ui.base.vm.viewModel +import ca.gosyer.ui.manga.openMangaMenu import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.lang.launchApplication +import io.kamel.image.lazyPainterResource import kotlinx.coroutines.DelicateCoroutinesApi @OptIn(DelicateCoroutinesApi::class) @@ -58,14 +65,14 @@ fun openDownloadsMenu() { launchApplication { ThemedWindow(::exitApplication, title = BuildConfig.NAME) { Surface { - DownloadsMenu() + DownloadsMenu(::openMangaMenu) } } } } @Composable -fun DownloadsMenu() { +fun DownloadsMenu(onMangaClick: (Long) -> Unit) { val vm = viewModel() val downloadQueue by vm.downloadQueue.collectAsState() @@ -85,8 +92,9 @@ fun DownloadsMenu() { ) LazyColumn(Modifier.fillMaxSize()) { items(downloadQueue) { - downloadsItem( + DownloadsItem( it, + { onMangaClick(it.mangaId) }, vm::stopDownload, vm::moveToBottom ) @@ -96,71 +104,70 @@ fun DownloadsMenu() { } @Composable -private fun downloadsItem( - chapter: DownloadChapter, - onDownloadCancel: (Chapter?) -> Unit, - onMoveDownloadToBottom: (Chapter?) -> Unit +fun DownloadsItem( + item: DownloadChapter, + onClickCover: () -> Unit, + onClickCancel: (Chapter) -> Unit, + onClickMoveToBottom: (Chapter) -> Unit ) { - BoxWithConstraints { - Row( - modifier = Modifier.fillMaxWidth() - .height(56.dp) - .padding(vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceAround + MangaListItem( + modifier = Modifier + .height(96.dp) + .fillMaxWidth() + .padding(end = 4.dp) + ) { + MangaListItemImage( + modifier = Modifier + .fillMaxHeight() + .aspectRatio(mangaAspectRatio) + .padding(start = 16.dp, top = 8.dp, bottom = 8.dp) + .clip(MaterialTheme.shapes.medium) + .clickable { onClickCover() }, + cover = lazyPainterResource(item.manga, filterQuality = FilterQuality.Medium), + contentDescription = item.manga.title + ) + MangaListItemColumn( + modifier = Modifier + .weight(1f) + .padding(start = 16.dp) ) { - Column(Modifier.fillMaxHeight().width(this@BoxWithConstraints.maxWidth - 46.dp).padding(horizontal = 32.dp), verticalArrangement = Arrangement.SpaceAround) { - Row( - Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - chapter.chapter?.name.toString(), - Modifier.width(this@BoxWithConstraints.maxWidth - 200.dp), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - - ) - // Spacer(Modifier.width(16.dp)) - if (chapter.chapter?.pageCount != null && chapter.chapter.pageCount != -1) { - Text( - "${(chapter.chapter.pageCount * chapter.progress).toInt()}/${chapter.chapter.pageCount}", - Modifier.padding(horizontal = 8.dp), - style = MaterialTheme.typography.body2, - color = LocalContentColor.current.copy(alpha = ContentAlpha.disabled), - maxLines = 1, - overflow = TextOverflow.Visible - ) - } else { - Spacer(Modifier.width(32.dp)) - } - } - Spacer(Modifier.height(4.dp)) - val animatedProgress by animateFloatAsState( - targetValue = chapter.progress, - animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec - ) - LinearProgressIndicator( - animatedProgress, - Modifier.fillMaxWidth() - .padding(bottom = 8.dp) - ) - } - DropdownIconButton( - chapter.mangaId to chapter.chapterIndex, - { - DropdownMenuItem(onClick = { onDownloadCancel(chapter.chapter) }) { - Text(stringResource("action_cancel")) - } - DropdownMenuItem(onClick = { onMoveDownloadToBottom(chapter.chapter) }) { - Text(stringResource("action_move_to_bottom")) - } - } - ) { - Icon( - Icons.Rounded.MoreVert, - null - ) - } + MangaListItemTitle( + text = item.manga.title, + fontWeight = FontWeight.SemiBold + ) + val progress = if (item.chapter.pageCount != null && item.chapter.pageCount != -1) { + " - " + "${(item.chapter.pageCount * item.progress).toInt()}/${item.chapter.pageCount}" + } else "" + MangaListItemSubtitle( + text = item.chapter.name + progress + ) + Spacer(Modifier.height(4.dp)) + val animatedProgress by animateFloatAsState( + targetValue = item.progress, + animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec + ) + LinearProgressIndicator( + animatedProgress, + Modifier.fillMaxWidth() + .padding(bottom = 8.dp) + ) } + DropdownIconButton( + item.mangaId to item.chapterIndex, + { + DropdownMenuItem(onClick = { onClickCancel(item.chapter) }) { + Text(stringResource("action_cancel")) + } + DropdownMenuItem(onClick = { onClickMoveToBottom(item.chapter) }) { + Text(stringResource("action_move_to_bottom")) + } + } + ) { + Icon( + Icons.Rounded.MoreVert, + null + ) + } + Spacer(Modifier.width(16.dp)) } } diff --git a/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenuViewModel.kt b/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenuViewModel.kt index b982145f..620207b2 100644 --- a/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenuViewModel.kt +++ b/src/main/kotlin/ca/gosyer/ui/downloads/DownloadsMenuViewModel.kt @@ -41,15 +41,13 @@ class DownloadsMenuViewModel @Inject constructor( } } - fun stopDownload(chapter: Chapter?) { - chapter ?: return + fun stopDownload(chapter: Chapter) { scope.launch { chapterHandler.stopChapterDownload(chapter) } } - fun moveToBottom(chapter: Chapter?) { - chapter ?: return + fun moveToBottom(chapter: Chapter) { scope.launch { chapterHandler.stopChapterDownload(chapter) chapterHandler.queueChapterDownload(chapter)