diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt index 38786142a2..c46a1fa9cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt @@ -1,15 +1,24 @@ package eu.kanade.tachiyomi.ui.reader.viewer import android.content.Context +import android.text.SpannableStringBuilder +import android.text.style.ImageSpan import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout +import androidx.core.content.ContextCompat import androidx.core.text.bold import androidx.core.text.buildSpannedString +import androidx.core.text.inSpans import androidx.core.view.isVisible import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.databinding.ReaderTransitionViewBinding +import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition +import eu.kanade.tachiyomi.util.system.dpToPx +import kotlin.math.roundToInt class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { @@ -21,10 +30,11 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) } - fun bind(transition: ChapterTransition) { + fun bind(transition: ChapterTransition, downloadManager: DownloadManager, manga: Manga?) { + manga ?: return when (transition) { - is ChapterTransition.Prev -> bindPrevChapterTransition(transition) - is ChapterTransition.Next -> bindNextChapterTransition(transition) + is ChapterTransition.Prev -> bindPrevChapterTransition(transition, downloadManager, manga) + is ChapterTransition.Next -> bindNextChapterTransition(transition, downloadManager, manga) } missingChapterWarning(transition) } @@ -32,20 +42,32 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At /** * Binds a previous chapter transition on this view and subscribes to the page load status. */ - private fun bindPrevChapterTransition(transition: ChapterTransition) { - val prevChapter = transition.to + private fun bindPrevChapterTransition( + transition: ChapterTransition, + downloadManager: DownloadManager, + manga: Manga, + ) { + val prevChapter = transition.to?.chapter - val hasPrevChapter = prevChapter != null - binding.lowerText.isVisible = hasPrevChapter - if (hasPrevChapter) { + binding.lowerText.isVisible = prevChapter != null + if (prevChapter != null) { binding.upperText.textAlignment = TEXT_ALIGNMENT_TEXT_START + val isPrevDownloaded = downloadManager.isChapterDownloaded( + prevChapter.name, + prevChapter.scanlator, + manga.title, + manga.source, + ) + val isCurrentDownloaded = transition.from.pageLoader is DownloadPageLoader binding.upperText.text = buildSpannedString { bold { append(context.getString(R.string.transition_previous)) } - append("\n${prevChapter!!.chapter.name}") + append("\n${prevChapter.name}") + if (isPrevDownloaded) addDLImageSpan() } binding.lowerText.text = buildSpannedString { bold { append(context.getString(R.string.transition_current)) } append("\n${transition.from.chapter.name}") + if (isCurrentDownloaded) addDLImageSpan() } } else { binding.upperText.textAlignment = TEXT_ALIGNMENT_CENTER @@ -56,20 +78,32 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At /** * Binds a next chapter transition on this view and subscribes to the load status. */ - private fun bindNextChapterTransition(transition: ChapterTransition) { - val nextChapter = transition.to + private fun bindNextChapterTransition( + transition: ChapterTransition, + downloadManager: DownloadManager, + manga: Manga, + ) { + val nextChapter = transition.to?.chapter - val hasNextChapter = nextChapter != null - binding.lowerText.isVisible = hasNextChapter - if (hasNextChapter) { + binding.lowerText.isVisible = nextChapter != null + if (nextChapter != null) { binding.upperText.textAlignment = TEXT_ALIGNMENT_TEXT_START + val isCurrentDownloaded = transition.from.pageLoader is DownloadPageLoader + val isNextDownloaded = downloadManager.isChapterDownloaded( + nextChapter.name, + nextChapter.scanlator, + manga.title, + manga.source, + ) binding.upperText.text = buildSpannedString { bold { append(context.getString(R.string.transition_finished)) } append("\n${transition.from.chapter.name}") + if (isCurrentDownloaded) addDLImageSpan() } binding.lowerText.text = buildSpannedString { bold { append(context.getString(R.string.transition_next)) } - append("\n${nextChapter!!.chapter.name}") + append("\n${nextChapter.name}") + if (isNextDownloaded) addDLImageSpan() } } else { binding.upperText.textAlignment = TEXT_ALIGNMENT_CENTER @@ -77,6 +111,17 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At } } + private fun SpannableStringBuilder.addDLImageSpan() { + val icon = ContextCompat.getDrawable(context, R.drawable.ic_offline_pin_24dp)?.mutate() + ?.apply { + val size = binding.lowerText.textSize + 4.dpToPx + setTint(binding.lowerText.currentTextColor) + setBounds(0, 0, size.roundToInt(), size.roundToInt()) + } ?: return + append(" ") + inSpans(ImageSpan(icon)) { append("image") } + } + private fun missingChapterWarning(transition: ChapterTransition) { if (transition.to == null) { binding.warning.isVisible = false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt index 9f712c2da1..4445923d81 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt @@ -61,7 +61,7 @@ class PagerTransitionHolder( addView(transitionView) addView(pagesContainer) - transitionView.bind(transition) + transitionView.bind(transition, viewer.downloadManager, viewer.activity.presenter.manga) transition.to?.let { observeStatus(it) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index 364740fad4..856789fd09 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt @@ -11,6 +11,7 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.viewpager.widget.ViewPager import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.InsertPage @@ -21,6 +22,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.MainScope import kotlinx.coroutines.cancel +import uy.kohesive.injekt.injectLazy import kotlin.math.min /** @@ -29,6 +31,8 @@ import kotlin.math.min @Suppress("LeakingThis") abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer { + val downloadManager: DownloadManager by injectLazy() + private val scope = MainScope() /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt index c905f1275a..67e9b5b1d7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt @@ -63,7 +63,7 @@ class WebtoonTransitionHolder( * Binds the given [transition] with this view holder, subscribing to its state. */ fun bind(transition: ChapterTransition) { - transitionView.bind(transition) + transitionView.bind(transition, viewer.downloadManager, viewer.activity.presenter.manga) transition.to?.let { observeStatus(it, transition) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt index 9ec03ea6dd..0f9f7cb0d2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt @@ -11,6 +11,7 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.WebtoonLayoutManager +import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition @@ -24,6 +25,7 @@ import kotlinx.coroutines.cancel import rx.subscriptions.CompositeSubscription import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import uy.kohesive.injekt.injectLazy import kotlin.math.max import kotlin.math.min @@ -32,6 +34,8 @@ import kotlin.math.min */ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = true) : BaseViewer { + val downloadManager: DownloadManager by injectLazy() + private val scope = MainScope() /** diff --git a/app/src/main/res/drawable/ic_offline_pin_24dp.xml b/app/src/main/res/drawable/ic_offline_pin_24dp.xml new file mode 100644 index 0000000000..9a9cc213f6 --- /dev/null +++ b/app/src/main/res/drawable/ic_offline_pin_24dp.xml @@ -0,0 +1,9 @@ + + +