Browse Source

Add missing chapter warning (#3745)

* Add missing chapter warning

* Flip calculation instead of flipping variables

* Change logic

* Change tint based on reader theme

* Add missing chapter warning to WebtoonTransitionHolder

* Add chapter warning between current/finished and prev/next

* Fix mix up of TextViews

* Fix review comments
Andreas E 4 years ago
parent
commit
7a33e198dc

+ 85 - 15
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt

@@ -6,17 +6,22 @@ import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.ProgressBar
 import android.widget.TextView
 import androidx.appcompat.widget.AppCompatTextView
 import androidx.core.text.bold
 import androidx.core.text.buildSpannedString
+import androidx.core.view.isVisible
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
 import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 import eu.kanade.tachiyomi.util.system.dpToPx
+import eu.kanade.tachiyomi.util.system.getResourceColor
+import eu.kanade.tachiyomi.util.view.setVectorCompat
 import eu.kanade.tachiyomi.widget.ViewPagerAdapter
+import kotlin.math.floor
 import rx.Subscription
 import rx.android.schedulers.AndroidSchedulers
 
@@ -40,10 +45,32 @@ class PagerTransitionHolder(
      */
     private var statusSubscription: Subscription? = null
 
-    /**
-     * Text view used to display the text of the current and next/prev chapters.
-     */
-    private var textView = TextView(context).apply {
+    private var warningContainer: LinearLayout = LinearLayout(context).apply {
+        val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
+        layoutParams.bottomMargin = 16.dpToPx
+        setLayoutParams(layoutParams)
+        orientation = HORIZONTAL
+        gravity = Gravity.CENTER_VERTICAL
+    }
+
+    private var warningImageView: ImageView = ImageView(context).apply {
+        val tintColor = context.getResourceColor(R.attr.colorOnBackground)
+        setVectorCompat(R.drawable.ic_warning_white_24dp, tintColor)
+        wrapContent()
+    }
+
+    private var warningTextView: TextView = TextView(context).apply {
+        wrapContent()
+    }
+
+    private var upperTextView: TextView = TextView(context).apply {
+        val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
+        layoutParams.bottomMargin = 16.dpToPx
+        setLayoutParams(layoutParams)
+        textSize = 17.5F
+    }
+
+    private var lowerTextView: TextView = TextView(context).apply {
         textSize = 17.5F
         wrapContent()
     }
@@ -63,13 +90,44 @@ class PagerTransitionHolder(
         gravity = Gravity.CENTER
         val sidePadding = 64.dpToPx
         setPadding(sidePadding, 0, sidePadding, 0)
-        addView(textView)
+        addView(upperTextView)
+        warningContainer.addView(warningImageView)
+        warningContainer.addView(warningTextView)
+        addView(warningContainer)
+        addView(lowerTextView)
         addView(pagesContainer)
 
         when (transition) {
             is ChapterTransition.Prev -> bindPrevChapterTransition()
             is ChapterTransition.Next -> bindNextChapterTransition()
         }
+
+        missingChapterWarning()
+    }
+
+    private fun missingChapterWarning() {
+        if (transition.to == null) {
+            showMissingChapterWarning(false)
+            return
+        }
+
+        val fromChapterNumber: Float = floor(transition.from.chapter.chapter_number)
+        val toChapterNumber: Float = floor(transition.to!!.chapter.chapter_number)
+
+        val chapterDifference = when (transition) {
+            is ChapterTransition.Prev -> fromChapterNumber - toChapterNumber - 1f
+            is ChapterTransition.Next -> toChapterNumber - fromChapterNumber - 1f
+        }
+
+        val hasMissingChapters = chapterDifference > 0f
+
+        warningTextView.text = resources.getQuantityString(R.plurals.missing_chapters_warning, chapterDifference.toInt(), chapterDifference.toInt())
+        showMissingChapterWarning(hasMissingChapters)
+    }
+
+    private fun showMissingChapterWarning(visible: Boolean) {
+        warningImageView.isVisible = visible
+        warningTextView.isVisible = visible
     }
 
     /**
@@ -87,15 +145,21 @@ class PagerTransitionHolder(
     private fun bindNextChapterTransition() {
         val nextChapter = transition.to
 
-        textView.text = if (nextChapter != null) {
-            buildSpannedString {
+        val hasNextChapter = nextChapter != null
+        lowerTextView.isVisible = hasNextChapter
+        if (hasNextChapter) {
+            gravity = Gravity.CENTER_VERTICAL
+            upperTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_finished)) }
-                append("\n${transition.from.chapter.name}\n\n")
+                append("\n${transition.from.chapter.name}")
+            }
+            lowerTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_next)) }
-                append("\n${nextChapter.chapter.name}\n\n")
+                append("\n${nextChapter!!.chapter.name}")
             }
         } else {
-            context.getString(R.string.transition_no_next)
+            gravity = Gravity.CENTER
+            upperTextView.text = context.getString(R.string.transition_no_next)
         }
 
         if (nextChapter != null) {
@@ -109,15 +173,21 @@ class PagerTransitionHolder(
     private fun bindPrevChapterTransition() {
         val prevChapter = transition.to
 
-        textView.text = if (prevChapter != null) {
-            buildSpannedString {
+        val hasPrevChapter = prevChapter != null
+        lowerTextView.isVisible = hasPrevChapter
+        if (hasPrevChapter) {
+            gravity = Gravity.CENTER_VERTICAL
+            upperTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_current)) }
-                append("\n${transition.from.chapter.name}\n\n")
+                append("\n${transition.from.chapter.name}")
+            }
+            lowerTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_previous)) }
-                append("\n${prevChapter.chapter.name}\n\n")
+                append("\n${prevChapter!!.chapter.name}")
             }
         } else {
-            context.getString(R.string.transition_no_previous)
+            gravity = Gravity.CENTER
+            upperTextView.text = context.getString(R.string.transition_no_previous)
         }
 
         if (prevChapter != null) {

+ 88 - 16
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt

@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
 import android.view.Gravity
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.ProgressBar
 import android.widget.TextView
@@ -16,6 +17,9 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
 import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 import eu.kanade.tachiyomi.util.system.dpToPx
+import eu.kanade.tachiyomi.util.system.getResourceColor
+import eu.kanade.tachiyomi.util.view.setVectorCompat
+import kotlin.math.floor
 import rx.Subscription
 import rx.android.schedulers.AndroidSchedulers
 
@@ -32,14 +36,39 @@ class WebtoonTransitionHolder(
      */
     private var statusSubscription: Subscription? = null
 
-    /**
-     * Text view used to display the text of the current and next/prev chapters.
-     */
-    private var textView = TextView(context).apply {
-        textSize = 17.5F
+    private var warningContainer: LinearLayout = LinearLayout(context).apply {
+        val layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
+        layoutParams.bottomMargin = 16.dpToPx
+        setLayoutParams(layoutParams)
+        orientation = LinearLayout.HORIZONTAL
+        gravity = Gravity.CENTER_VERTICAL
+    }
+
+    private var warningImageView: ImageView = ImageView(context).apply {
+        val tintColor = context.getResourceColor(R.attr.colorOnBackground)
+        setVectorCompat(R.drawable.ic_warning_white_24dp, tintColor)
+        wrapContent()
+    }
+
+    private var warningTextView: TextView = TextView(context).apply {
         wrapContent()
     }
 
+    private var upperTextView: TextView = TextView(context).apply {
+        val layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
+        layoutParams.topMargin = 16.dpToPx
+        layoutParams.bottomMargin = 16.dpToPx
+        setLayoutParams(layoutParams)
+        textSize = 17.5F
+    }
+
+    private var lowerTextView: TextView = TextView(context).apply {
+        val layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
+        layoutParams.bottomMargin = 16.dpToPx
+        setLayoutParams(layoutParams)
+        textSize = 17.5F
+    }
+
     /**
      * View container of the current status of the transition page. Child views will be added
      * dynamically.
@@ -63,7 +92,11 @@ class WebtoonTransitionHolder(
             setMargins(0, childMargins, 0, childMargins)
         }
 
-        layout.addView(textView, childParams)
+        layout.addView(upperTextView)
+        warningContainer.addView(warningImageView)
+        warningContainer.addView(warningTextView)
+        layout.addView(warningContainer)
+        layout.addView(lowerTextView)
         layout.addView(pagesContainer, childParams)
     }
 
@@ -75,6 +108,33 @@ class WebtoonTransitionHolder(
             is ChapterTransition.Prev -> bindPrevChapterTransition(transition)
             is ChapterTransition.Next -> bindNextChapterTransition(transition)
         }
+
+        missingChapterWarning(transition)
+    }
+
+    private fun missingChapterWarning(transition: ChapterTransition) {
+        if (transition.to == null) {
+            showMissingChapterWarning(false)
+            return
+        }
+
+        val fromChapterNumber: Float = floor(transition.from.chapter.chapter_number)
+        val toChapterNumber: Float = floor(transition.to!!.chapter.chapter_number)
+
+        val chapterDifference = when (transition) {
+            is ChapterTransition.Prev -> fromChapterNumber - toChapterNumber - 1f
+            is ChapterTransition.Next -> toChapterNumber - fromChapterNumber - 1f
+        }
+
+        val hasMissingChapters = chapterDifference > 0f
+
+        warningTextView.text = itemView.resources.getQuantityString(R.plurals.missing_chapters_warning, chapterDifference.toInt(), chapterDifference.toInt())
+        showMissingChapterWarning(hasMissingChapters)
+    }
+
+    private fun showMissingChapterWarning(visible: Boolean) {
+        warningImageView.isVisible = visible
+        warningTextView.isVisible = visible
     }
 
     /**
@@ -90,15 +150,21 @@ class WebtoonTransitionHolder(
     private fun bindNextChapterTransition(transition: ChapterTransition.Next) {
         val nextChapter = transition.to
 
-        textView.text = if (nextChapter != null) {
-            buildSpannedString {
+        val hasNextChapter = nextChapter != null
+        lowerTextView.isVisible = hasNextChapter
+        if (hasNextChapter) {
+            layout.gravity = Gravity.CENTER_VERTICAL
+            upperTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_finished)) }
-                append("\n${transition.from.chapter.name}\n\n")
+                append("\n${transition.from.chapter.name}")
+            }
+            lowerTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_next)) }
-                append("\n${nextChapter.chapter.name}\n\n")
+                append("\n${nextChapter!!.chapter.name}")
             }
         } else {
-            context.getString(R.string.transition_no_next)
+            layout.gravity = Gravity.CENTER
+            upperTextView.text = context.getString(R.string.transition_no_next)
         }
 
         if (nextChapter != null) {
@@ -112,15 +178,21 @@ class WebtoonTransitionHolder(
     private fun bindPrevChapterTransition(transition: ChapterTransition.Prev) {
         val prevChapter = transition.to
 
-        textView.text = if (prevChapter != null) {
-            buildSpannedString {
+        val hasPrevChapter = prevChapter != null
+        lowerTextView.isVisible = hasPrevChapter
+        if (hasPrevChapter) {
+            layout.gravity = Gravity.CENTER_VERTICAL
+            upperTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_current)) }
-                append("\n${transition.from.chapter.name}\n\n")
+                append("\n${transition.from.chapter.name}")
+            }
+            lowerTextView.text = buildSpannedString {
                 bold { append(context.getString(R.string.transition_previous)) }
-                append("\n${prevChapter.chapter.name}\n\n")
+                append("\n${prevChapter!!.chapter.name}")
             }
         } else {
-            context.getString(R.string.transition_no_previous)
+            layout.gravity = Gravity.CENTER
+            upperTextView.text = context.getString(R.string.transition_no_previous)
         }
 
         if (prevChapter != null) {

+ 9 - 0
app/src/main/res/drawable/ic_warning_white_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:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"
+      android:fillColor="#ffffff"/>
+</vector>

+ 4 - 0
app/src/main/res/values/strings.xml

@@ -701,4 +701,8 @@
     <string name="tapping_inverted_vertical">Vertical</string>
     <string name="tapping_inverted_both">Both</string>
 
+    <plurals name="missing_chapters_warning">
+        <item quantity="one">There is 1 missing chapter</item>
+        <item quantity="other">There are %d missing chapters</item>
+    </plurals>
 </resources>