diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt index 4f306b6033..8b53f8ed79 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt @@ -705,7 +705,7 @@ class MangaController : } } - fun onChapterStatusChange(download: Download) { + fun onChapterDownloadUpdate(download: Download) { chaptersAdapter?.currentItems?.find { it.id == download.chapter.id }?.let { chaptersAdapter?.updateItem(it) chaptersAdapter?.notifyDataSetChanged() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index d5c548b5c6..9ae82d5faf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -79,7 +79,8 @@ class MangaPresenter( /** * Subscription to observe download status changes. */ - private var observeDownloadsSubscription: Subscription? = null + private var observeDownloadsStatusSubscription: Subscription? = null + private var observeDownloadsPageSubscription: Subscription? = null override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) @@ -293,12 +294,20 @@ class MangaPresenter( // Chapters list - start private fun observeDownloads() { - observeDownloadsSubscription?.let { remove(it) } - observeDownloadsSubscription = downloadManager.queue.getStatusObservable() + observeDownloadsStatusSubscription?.let { remove(it) } + observeDownloadsStatusSubscription = downloadManager.queue.getStatusObservable() .observeOn(AndroidSchedulers.mainThread()) .filter { download -> download.manga.id == manga.id } .doOnNext { onDownloadStatusChange(it) } - .subscribeLatestCache(MangaController::onChapterStatusChange) { _, error -> + .subscribeLatestCache(MangaController::onChapterDownloadUpdate) { _, error -> + Timber.e(error) + } + + observeDownloadsPageSubscription?.let { remove(it) } + observeDownloadsPageSubscription = downloadManager.queue.getProgressObservable() + .observeOn(AndroidSchedulers.mainThread()) + .filter { download -> download.manga.id == manga.id } + .subscribeLatestCache(MangaController::onChapterDownloadUpdate) { _, error -> Timber.e(error) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt index 9f9bdce450..5b0ff95e83 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt @@ -22,7 +22,7 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att addView(binding.root) } - fun setState(state: Download.State) { + fun setState(state: Download.State, progress: Int = 0) { binding.downloadIconBorder.isVisible = state == Download.State.NOT_DOWNLOADED binding.downloadIcon.isVisible = state == Download.State.NOT_DOWNLOADED || state == Download.State.DOWNLOADING @@ -44,7 +44,13 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att } binding.downloadProgress.isVisible = state == Download.State.DOWNLOADING || state == Download.State.QUEUE - // TODO: show actual download progress + // Spinner when queued + val isDownloading = state == Download.State.DOWNLOADING || (state == Download.State.QUEUE && progress > 0) + binding.downloadProgress.isIndeterminate = !isDownloading + // Actual progress when downloading or partially downloaded + if (isDownloading) { + binding.downloadProgress.progress = progress + } binding.downloadedIcon.isVisible = state == Download.State.DOWNLOADED diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt index a1a9c082ea..a24ee4281d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt @@ -69,6 +69,6 @@ class ChapterHolder( } binding.download.isVisible = item.manga.source != LocalSource.ID - binding.download.setState(item.status) + binding.download.setState(item.status, item.progress) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt index 678fb241e9..4908422bea 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt @@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.source.model.Page class ChapterItem(val chapter: Chapter, val manga: Manga) : AbstractFlexibleItem(), @@ -22,6 +23,12 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) : _status = value } + val progress: Int + get() { + val pages = download?.pages ?: return 0 + return pages.map(Page::progress).average().toInt() + } + @Transient var download: Download? = null diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index 9d4e9bfb1a..e572393e6f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -229,16 +229,13 @@ class UpdatesController : * Update download status of chapter * @param download [Download] object containing download progress. */ - fun onChapterStatusChange(download: Download) { - getHolder(download)?.notifyStatus(download.status) - } - - /** - * Returns holder belonging to chapter - * @param download [Download] object containing download progress. - */ - private fun getHolder(download: Download): UpdatesHolder? { - return binding.recycler.findViewHolderForItemId(download.chapter.id!!) as? UpdatesHolder + fun onChapterDownloadUpdate(download: Download) { + adapter?.currentItems + ?.filterIsInstance() + ?.find { it.chapter.id == download.chapter.id }?.let { + adapter?.updateItem(it) + adapter?.notifyDataSetChanged() + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesHolder.kt index 2d712a484c..49194cae39 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesHolder.kt @@ -8,7 +8,6 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.request.RequestOptions import eu.davidea.viewholders.FlexibleViewHolder import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.glide.toMangaThumbnail import eu.kanade.tachiyomi.databinding.UpdatesItemBinding @@ -52,7 +51,7 @@ class UpdatesHolder(private val view: View, private val adapter: UpdatesAdapter) // Set chapter status binding.download.isVisible = item.manga.source != LocalSource.ID - notifyStatus(item.status) + binding.download.setState(item.status, item.progress) // Set cover GlideApp.with(itemView.context).clear(binding.mangaCover) @@ -66,8 +65,4 @@ class UpdatesHolder(private val view: View, private val adapter: UpdatesAdapter) .dontAnimate() .into(binding.mangaCover) } - - fun notifyStatus(state: Download.State) { - binding.download.setState(state) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesItem.kt index 3ac1d108df..0a9d2fa8e3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesItem.kt @@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.recent.DateSectionItem class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateSectionItem) : @@ -22,6 +23,12 @@ class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateSectionIte _status = value } + val progress: Int + get() { + val pages = download?.pages ?: return 0 + return pages.map(Page::progress).average().toInt() + } + @Transient var download: Download? = null diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt index 18970dfc05..508be4909b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt @@ -39,8 +39,16 @@ class UpdatesPresenter( .observeOn(AndroidSchedulers.mainThread()) .subscribeLatestCache(UpdatesController::onNextRecentChapters) - getChapterStatusObservable() - .subscribeLatestCache(UpdatesController::onChapterStatusChange) { _, error -> + downloadManager.queue.getStatusObservable() + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext { onDownloadStatusChange(it) } + .subscribeLatestCache(UpdatesController::onChapterDownloadUpdate) { _, error -> + Timber.e(error) + } + + downloadManager.queue.getProgressObservable() + .observeOn(AndroidSchedulers.mainThread()) + .subscribeLatestCache(UpdatesController::onChapterDownloadUpdate) { _, error -> Timber.e(error) } } @@ -86,17 +94,6 @@ class UpdatesPresenter( } } - /** - * Returns observable containing chapter status. - * - * @return download object containing download progress. - */ - private fun getChapterStatusObservable(): Observable { - return downloadManager.queue.getStatusObservable() - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext { download -> onDownloadStatusChange(download) } - } - /** * Finds and assigns the list of downloaded chapters. *