diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 4ed15d610f..5f93b4d004 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -494,7 +494,7 @@ class Downloader( // Delete successful downloads from queue if (download.status == Download.DOWNLOADED) { // remove downloaded chapter from queue - queue.remove(download) + queue.remove(download, false) } if (areAllDownloadsFinished()) { DownloadService.stop(context) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/model/DownloadQueue.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/model/DownloadQueue.kt index d7ce067d46..67816a7522 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/model/DownloadQueue.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/model/DownloadQueue.kt @@ -5,7 +5,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.DownloadStore import eu.kanade.tachiyomi.source.model.Page -import rx.Observable import rx.subjects.PublishSubject import java.util.concurrent.CopyOnWriteArrayList @@ -32,7 +31,7 @@ class DownloadQueue( updatedRelay.call(Unit) } - fun remove(download: Download) { + fun remove(download: Download, callListeners: Boolean = true) { val removed = queue.remove(download) store.remove(download) download.setStatusSubject(null) @@ -40,7 +39,9 @@ class DownloadQueue( if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) { download.status = Download.NOT_DOWNLOADED } - downloadListeners.forEach { it.updateDownload(download) } + if (callListeners) { + downloadListeners.forEach { it.updateDownload(download) } + } if (removed) { updatedRelay.call(Unit) } @@ -76,15 +77,6 @@ class DownloadQueue( updatedRelay.call(Unit) } - fun getActiveDownloads(): Observable = - Observable.from(this).filter { download -> download.status == Download.DOWNLOADING } - - fun getStatusObservable(): Observable = statusSubject.onBackpressureBuffer() - - fun getUpdatedObservable(): Observable> = updatedRelay.onBackpressureBuffer() - .startWith(Unit) - .map { this } - private fun setPagesFor(download: Download) { if (download.status == Download.DOWNLOADING) { if (download.pages != null) { @@ -93,12 +85,12 @@ class DownloadQueue( callListeners(download) } } - downloadListeners.forEach { it.updateDownload(download) } + callListeners(download) } else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) { setPagesSubject(download.pages, null) - downloadListeners.forEach { it.updateDownload(download) } + callListeners(download) } else { - downloadListeners.forEach { it.updateDownload(download) } + callListeners(download) } } @@ -106,27 +98,6 @@ class DownloadQueue( downloadListeners.forEach { it.updateDownload(download) } } - fun getProgressObservable(): Observable { - return statusSubject.onBackpressureBuffer() - .startWith(getActiveDownloads()) - .flatMap { download -> - if (download.status == Download.DOWNLOADING) { - val pageStatusSubject = PublishSubject.create() - setPagesSubject(download.pages, pageStatusSubject) - downloadListeners.forEach { it.updateDownload(download) } - return@flatMap pageStatusSubject - .onBackpressureBuffer() - .filter { it == Page.READY } - .map { download } - } else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) { - setPagesSubject(download.pages, null) - downloadListeners.forEach { it.updateDownload(download) } - } - Observable.just(download) - } - .filter { it.status == Download.DOWNLOADING } - } - private fun setPagesSubject(pages: List?, subject: PublishSubject?) { if (pages != null) { for (page in pages) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadButton.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadButton.kt index 478a821bd3..90ed8a81e7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadButton.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadButton.kt @@ -1,18 +1,21 @@ package eu.kanade.tachiyomi.ui.download import android.animation.ObjectAnimator +import android.animation.ValueAnimator import android.content.Context import android.graphics.Color import android.util.AttributeSet import android.widget.FrameLayout import androidx.core.content.ContextCompat import androidx.core.graphics.ColorUtils +import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.databinding.DownloadButtonBinding import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.visible +import eu.kanade.tachiyomi.widget.EndAnimatorListener class DownloadButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { @@ -55,6 +58,14 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut context, R.drawable.ic_check_24dp )?.mutate() + private val filledAnim = AnimatedVectorDrawableCompat.create( + context, + R.drawable.anim_outline_to_filled + ) + private val checkAnim = AnimatedVectorDrawableCompat.create( + context, + R.drawable.anim_dl_to_check_to_dl + ) private var isAnimating = false private var iconAnimation: ObjectAnimator? = null @@ -65,7 +76,7 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut binding = DownloadButtonBinding.bind(this) } - fun setDownloadStatus(state: Int, progress: Int = 0) { + fun setDownloadStatus(state: Int, progress: Int = 0, animated: Boolean = false) { if (state != Download.DOWNLOADING) { iconAnimation?.cancel() binding.downloadIcon.alpha = 1f @@ -124,9 +135,28 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut binding.downloadProgress.gone() binding.downloadBorder.visible() binding.downloadProgressIndeterminate.gone() - binding.downloadBorder.setImageDrawable(filledCircle) binding.downloadBorder.drawable.setTint(downloadedColor) - binding.downloadIcon.drawable.setTint(downloadedTextColor) + if (animated) { + binding.downloadBorder.setImageDrawable(filledAnim) + binding.downloadIcon.setImageDrawable(checkAnim) + filledAnim?.start() + val alphaAnimation = ValueAnimator.ofArgb(disabledColor, downloadedTextColor) + alphaAnimation.addUpdateListener { valueAnimator -> + binding.downloadIcon.drawable.setTint(valueAnimator.animatedValue as Int) + } + alphaAnimation.addListener( + EndAnimatorListener { + binding.downloadIcon.drawable.setTint(downloadedTextColor) + checkAnim?.start() + } + ) + alphaAnimation.duration = 150 + alphaAnimation.start() + binding.downloadBorder.drawable.setTint(downloadedColor) + } else { + binding.downloadBorder.setImageDrawable(filledCircle) + binding.downloadIcon.drawable.setTint(downloadedTextColor) + } } Download.ERROR -> { binding.downloadProgress.gone() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt index 852b371276..47e47ac4e1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt @@ -523,7 +523,8 @@ class MangaDetailsController : getHolder(download.chapter)?.notifyStatus( download.status, presenter.isLockedFromSearch, - download.progress + download.progress, + true ) } 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 b9b13ed796..c0db4958d9 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 @@ -152,12 +152,12 @@ class ChapterHolder( if (binding.frontView.translationX != 0f) itemView.post { adapter.notifyItemChanged(flexibleAdapterPosition) } } - fun notifyStatus(status: Int, locked: Boolean, progress: Int) = with(binding.downloadButton.downloadButton) { + fun notifyStatus(status: Int, locked: Boolean, progress: Int, animated: Boolean = false) = with(binding.downloadButton.downloadButton) { if (locked) { gone() return } visibleIf(!localSource) - setDownloadStatus(status, progress) + setDownloadStatus(status, progress, animated) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt index 5ae36fd945..ca0ae16e9d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt @@ -138,8 +138,8 @@ class RecentMangaHolder( return item.mch.history.id != null } - fun notifyStatus(status: Int, progress: Int, isRead: Boolean) { - binding.downloadButton.downloadButton.setDownloadStatus(status, progress) + fun notifyStatus(status: Int, progress: Int, isRead: Boolean, animated: Boolean = false) { + binding.downloadButton.downloadButton.setDownloadStatus(status, progress, animated) val isChapterRead = if (adapter.showDownloads == RecentMangaAdapter.ShowRecentsDLs.UnreadOrDownloaded) isRead else false binding.downloadButton.downloadButton.isVisible = diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt index 9de28d07f7..f398d90505 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt @@ -415,7 +415,7 @@ class RecentsController(bundle: Bundle? = null) : binding.downloadBottomSheet.dlBottomSheet.onUpdateDownloadedPages(download) val id = download.chapter.id ?: return val holder = binding.recycler.findViewHolderForItemId(id) as? RecentMangaHolder ?: return - holder.notifyStatus(download.status, download.progress, download.chapter.read) + holder.notifyStatus(download.status, download.progress, download.chapter.read, true) } private fun refreshItem(chapterId: Long) { diff --git a/app/src/main/res/drawable/anim_dl_to_check_to_dl.xml b/app/src/main/res/drawable/anim_dl_to_check_to_dl.xml new file mode 100644 index 0000000000..ca39909a20 --- /dev/null +++ b/app/src/main/res/drawable/anim_dl_to_check_to_dl.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/anim_outline_to_filled.xml b/app/src/main/res/drawable/anim_outline_to_filled.xml new file mode 100644 index 0000000000..3503276655 --- /dev/null +++ b/app/src/main/res/drawable/anim_outline_to_filled.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + +