Improve downloads menu with the new manga object

This commit is contained in:
Syer10
2021-11-27 17:43:01 -05:00
parent 0b0b3856ba
commit 3156caddf6
3 changed files with 85 additions and 78 deletions

View File

@@ -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
)

View File

@@ -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<DownloadsMenuViewModel>()
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))
}
}

View File

@@ -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)