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 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10s10,-4.5 10,-10S17.5,2 12,2zM17,18H7v-2h10V18zM10.3,14L7,10.7l1.4,-1.4l1.9,1.9l5.3,-5.3L17,7.3L10.3,14z" />
+</vector>