From 39b997a4202ac0c3dd051d448362d552dd27f035 Mon Sep 17 00:00:00 2001 From: Jay Date: Fri, 15 Mar 2019 17:59:48 -0700 Subject: [PATCH 01/77] Automatic Reader Background --- .../tachiyomi/ui/reader/ReaderActivity.kt | 4 +- .../ui/reader/viewer/pager/PagerPageHolder.kt | 28 ++++-- .../ui/setting/SettingsReaderController.kt | 4 +- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 87 +++++++++++++++++++ app/src/main/res/values/arrays.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 116 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 9861e288cb..deae549a57 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -110,8 +110,8 @@ class ReaderActivity : BaseRxActivity() { */ override fun onCreate(savedState: Bundle?) { setTheme(when (preferences.readerTheme().getOrDefault()) { - 0 -> R.style.Theme_Reader_Light - else -> R.style.Theme_Reader + 1 -> R.style.Theme_Reader + else -> R.style.Theme_Reader_Light }) super.onCreate(savedState) setContentView(R.layout.reader_activity) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index fc8dece8f0..eb68cd48cf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager import android.annotation.SuppressLint import android.content.Intent +import android.graphics.BitmapFactory import android.graphics.PointF import android.graphics.drawable.Drawable import android.net.Uri @@ -27,19 +28,19 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.github.chrisbanes.photoview.PhotoView import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.glide.GlideApp +import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType -import eu.kanade.tachiyomi.util.ImageUtil -import eu.kanade.tachiyomi.util.dpToPx -import eu.kanade.tachiyomi.util.gone -import eu.kanade.tachiyomi.util.visible +import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.widget.ViewPagerAdapter +import kotlinx.coroutines.experimental.async import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers +import uy.kohesive.injekt.injectLazy import java.io.InputStream import java.util.concurrent.TimeUnit @@ -99,6 +100,8 @@ class PagerPageHolder( */ private var readImageHeaderSubscription: Subscription? = null + private val preferences by injectLazy() + init { addView(progressBar) observeStatus() @@ -243,7 +246,22 @@ class PagerPageHolder( .observeOn(AndroidSchedulers.mainThread()) .doOnNext { isAnimated -> if (!isAnimated) { - initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) + if (preferences.readerTheme().get() == 2) { + val bytesArray = openStream!!.readBytes() + + val imageView = initSubsamplingImageView() + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + + launchUI { + val backgroundD = async { ImageUtil.autoSetBackground(BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size)) } + imageView.background = backgroundD.await() + } + bytesStream.close() + } + else { + initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) + } } else { initImageView().setImage(openStream!!) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt index 9439953850..79b08b243d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt @@ -49,8 +49,8 @@ class SettingsReaderController : SettingsController() { intListPreference { key = Keys.readerTheme titleRes = R.string.pref_reader_theme - entriesRes = arrayOf(R.string.white_background, R.string.black_background) - entryValues = arrayOf("0", "1") + entriesRes = arrayOf(R.string.white_background, R.string.black_background, R.string.auto_background) + entryValues = arrayOf("0", "1", "2") defaultValue = "0" summary = "%s" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index fa879d4b4f..8a5814458f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -1,5 +1,8 @@ package eu.kanade.tachiyomi.util +import android.graphics.Bitmap +import android.graphics.Color +import android.graphics.drawable.* import java.io.InputStream import java.net.URLConnection @@ -49,6 +52,90 @@ object ImageUtil { return null } + fun autoSetBackground(image: Bitmap): Drawable { + if (image.width < 50 || image.height < 50) + return ColorDrawable(Color.WHITE) + val topLeftIsDark = isDark(image.getPixel(2,2)) + val topRightIsDark = isDark(image.getPixel(image.width - 2,2)) + val midLeftIsDark = isDark(image.getPixel(2,image.height/2)) + val midRightIsDark = isDark(image.getPixel(image.width - 2,image.height/2)) + val topMidIsDark = isDark(image.getPixel(image.width/2, 2)) + val botLeftIsDark = isDark(image.getPixel(2,image.height - 2)) + val botRightIsDark = isDark(image.getPixel(image.width - 2,image.height - 2)) + + var darkBG = (topLeftIsDark && (botLeftIsDark || botRightIsDark || topRightIsDark || midLeftIsDark || topMidIsDark)) + || (topRightIsDark && (botRightIsDark || botLeftIsDark || midRightIsDark || topMidIsDark)) + if (darkBG) { + if (isWhite(image.getPixel(2,2)).toInt() + + isWhite(image.getPixel(image.width - 2,2)).toInt() + + isWhite(image.getPixel(2,image.height - 2)).toInt() + + isWhite(image.getPixel(image.width - 2,image.height - 2)).toInt() > 2) + darkBG = false + var overallWhitePixels = 0 + var overallBlackPixels = 0 + outer@ for (x in intArrayOf(2,image.width-2)) { + var whitePixelsStreak = 0 + var whitePixels = 0 + var blackPixelsStreak = 0 + var blackPixels = 0 + var blackStreak = false + var whiteStrak = false + for (y in (0 until image.height step image.height / 25)) { + val pixel = image.getPixel(x, y) + if (isWhite(pixel)) { + blackPixelsStreak = 0 + whitePixelsStreak++ + whitePixels++ + overallWhitePixels++ + if (whitePixelsStreak > 14) { + whiteStrak = true + } + } + else { + whitePixelsStreak = 0 + if (isDark(pixel)) { + blackPixels++ + overallBlackPixels++ + blackPixelsStreak++ + if (blackPixelsStreak > 14) { + blackStreak = true + } + } + else { + blackPixelsStreak = 0 + } + } + } + when { + blackPixels > 22 -> return ColorDrawable(Color.BLACK) + blackStreak -> darkBG = true + whiteStrak || whitePixels > 22 -> darkBG = false + } + } + if (overallWhitePixels > 9 && overallWhitePixels >= overallBlackPixels) + darkBG = false + } + if (darkBG) + { + if (isWhite(image.getPixel(2,image.height - 2)) && isWhite(image.getPixel(image.width - 2,image.height - 2))) + return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf(Color.BLACK, Color.BLACK, Color.WHITE, Color.WHITE)) + else + return ColorDrawable(Color.BLACK) + } + return ColorDrawable(Color.WHITE) + } + + fun Boolean.toInt() = if (this) 1 else 0 + private fun isDark(color: Int): Boolean { + return Color.red(color) < 33 && Color.blue(color) < 33 && Color.green(color) < 33 + } + + + private fun isWhite(color: Int): Boolean { + return Color.red(color) + Color.blue(color) + Color.green(color) > 740 + } + private fun ByteArray.compareWith(magic: ByteArray): Boolean { for (i in 0 until magic.size) { if (this[i] != magic[i]) return false diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 9018a31f7c..ebdccc0d03 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -25,6 +25,7 @@ @string/white_background @string/black_background + @string/auto_background diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 73a073c77d..1bd4fc5a0d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -185,6 +185,7 @@ Background color White Black + Automatic Default viewer Default Left to right From 3d2a2c058fa6583059ca45a8aed51fd0c9878056 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 24 Mar 2019 20:34:57 -0700 Subject: [PATCH 02/77] Updated auto check --- .../ui/reader/viewer/pager/PagerConfig.kt | 6 ++ .../ui/reader/viewer/pager/PagerPageHolder.kt | 19 +++--- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 66 +++++++++++++------ 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt index c07c7b65fb..b2ba6e9cd9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt @@ -43,6 +43,9 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe var doubleTapAnimDuration = 500 private set + var readerTheme = 0 + private set + init { preferences.readWithTapping() .register({ tappingEnabled = it }) @@ -70,6 +73,9 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe preferences.readWithVolumeKeysInverted() .register({ volumeKeysInverted = it }) + + preferences.readerTheme() + .register({ readerTheme = it }) } fun unsubscribe() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index eb68cd48cf..b72f9ea66f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -28,7 +28,6 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.github.chrisbanes.photoview.PhotoView import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.glide.GlideApp -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar @@ -100,8 +99,6 @@ class PagerPageHolder( */ private var readImageHeaderSubscription: Subscription? = null - private val preferences by injectLazy() - init { addView(progressBar) observeStatus() @@ -246,18 +243,22 @@ class PagerPageHolder( .observeOn(AndroidSchedulers.mainThread()) .doOnNext { isAnimated -> if (!isAnimated) { - if (preferences.readerTheme().get() == 2) { + if (viewer.config.readerTheme == 2) { val bytesArray = openStream!!.readBytes() val imageView = initSubsamplingImageView() - val bytesStream = bytesArray.inputStream() - imageView.setImage(ImageSource.inputStream(bytesStream)) + if (viewer.config.imageCropBorders) { + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + bytesStream.close() + } launchUI { - val backgroundD = async { ImageUtil.autoSetBackground(BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size)) } - imageView.background = backgroundD.await() + val image = async { BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size) } + imageView.background = ImageUtil.autoSetBackground(image.await()) + if (!viewer.config.imageCropBorders) + imageView.setImage(ImageSource.bitmap(image.await())) } - bytesStream.close() } else { initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index 8a5814458f..2c24206eb0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -5,6 +5,7 @@ import android.graphics.Color import android.graphics.drawable.* import java.io.InputStream import java.net.URLConnection +import kotlin.math.abs object ImageUtil { @@ -55,25 +56,43 @@ object ImageUtil { fun autoSetBackground(image: Bitmap): Drawable { if (image.width < 50 || image.height < 50) return ColorDrawable(Color.WHITE) - val topLeftIsDark = isDark(image.getPixel(2,2)) - val topRightIsDark = isDark(image.getPixel(image.width - 2,2)) - val midLeftIsDark = isDark(image.getPixel(2,image.height/2)) - val midRightIsDark = isDark(image.getPixel(image.width - 2,image.height/2)) - val topMidIsDark = isDark(image.getPixel(image.width/2, 2)) - val botLeftIsDark = isDark(image.getPixel(2,image.height - 2)) - val botRightIsDark = isDark(image.getPixel(image.width - 2,image.height - 2)) + val top = 5 + val bot = image.height - 5 + val left = (image.width * 0.025).toInt() + val right = image.width - left + val midX = image.width / 2 + val midY = image.height / 2 + val topLeftIsDark = isDark(image.getPixel(left,top)) + val topRightIsDark = isDark(image.getPixel(right,top)) + val midLeftIsDark = isDark(image.getPixel(left,midY)) + val midRightIsDark = isDark(image.getPixel(right,midY)) + val topMidIsDark = isDark(image.getPixel(midX, top)) + val botLeftIsDark = isDark(image.getPixel(left,bot)) + val botRightIsDark = isDark(image.getPixel(right,bot)) var darkBG = (topLeftIsDark && (botLeftIsDark || botRightIsDark || topRightIsDark || midLeftIsDark || topMidIsDark)) || (topRightIsDark && (botRightIsDark || botLeftIsDark || midRightIsDark || topMidIsDark)) - if (darkBG) { - if (isWhite(image.getPixel(2,2)).toInt() + - isWhite(image.getPixel(image.width - 2,2)).toInt() + - isWhite(image.getPixel(2,image.height - 2)).toInt() + - isWhite(image.getPixel(image.width - 2,image.height - 2)).toInt() > 2) + if (pixelIsClose(image.getPixel(left,top), image.getPixel(midX,top)) && // top left & top mid + pixelIsClose(image.getPixel(midX,top), image.getPixel(right,top)) && //top mid & top right + pixelIsClose(image.getPixel(right,top), image.getPixel(right,bot)) && // top right & bot right + pixelIsClose(image.getPixel(right,bot), image.getPixel(midX,bot)) && // bot right & bot mid + pixelIsClose(image.getPixel(midX,bot), image.getPixel(left,bot))) // bot mid & bot left + return ColorDrawable(image.getPixel(left,top)) + val blackPixel = when { + topLeftIsDark -> image.getPixel (left, top) + topRightIsDark -> image.getPixel(right, top) + botLeftIsDark ->image.getPixel(left, bot) + else -> image.getPixel(right, bot) + } + + if (isWhite(image.getPixel(left,top)).toInt() + + isWhite(image.getPixel(right,top)).toInt() + + isWhite(image.getPixel(left,bot)).toInt() + + isWhite(image.getPixel(right,bot)).toInt() > 2) darkBG = false var overallWhitePixels = 0 var overallBlackPixels = 0 - outer@ for (x in intArrayOf(2,image.width-2)) { + outer@ for (x in intArrayOf(left,right)) { var whitePixelsStreak = 0 var whitePixels = 0 var blackPixelsStreak = 0 @@ -107,30 +126,37 @@ object ImageUtil { } } when { - blackPixels > 22 -> return ColorDrawable(Color.BLACK) + blackPixels > 22 -> { darkBG = true; overallWhitePixels = 0; break@outer } blackStreak -> darkBG = true whiteStrak || whitePixels > 22 -> darkBG = false } } - if (overallWhitePixels > 9 && overallWhitePixels >= overallBlackPixels) + if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) darkBG = false - } if (darkBG) { - if (isWhite(image.getPixel(2,image.height - 2)) && isWhite(image.getPixel(image.width - 2,image.height - 2))) + if (isWhite(image.getPixel(left,bot)) && isWhite(image.getPixel(right,bot))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(Color.BLACK, Color.BLACK, Color.WHITE, Color.WHITE)) + intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) + else if (isWhite(image.getPixel(left,top)) && isWhite(image.getPixel(right,top))) + return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) else - return ColorDrawable(Color.BLACK) + return ColorDrawable(blackPixel) } return ColorDrawable(Color.WHITE) } fun Boolean.toInt() = if (this) 1 else 0 private fun isDark(color: Int): Boolean { - return Color.red(color) < 33 && Color.blue(color) < 33 && Color.green(color) < 33 + return Color.red(color) < 40 && Color.blue(color) < 40 && Color.green(color) < 40 } + private fun pixelIsClose(color1: Int, color2: Int): Boolean { + return abs(Color.red(color1) - Color.red(color2)) < 30 && + abs(Color.green(color1) - Color.green(color2)) < 30 && + abs(Color.blue(color1) - Color.blue(color2)) < 30 + } private fun isWhite(color: Int): Boolean { return Color.red(color) + Color.blue(color) + Color.green(color) > 740 From e2472fb9b2ef993d65fe1aa6d143993da5173702 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 31 Mar 2019 18:37:12 -0700 Subject: [PATCH 03/77] Better auto background detection --- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 144 ++++++++++-------- 1 file changed, 77 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index 2c24206eb0..9398b9d880 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -58,92 +58,102 @@ object ImageUtil { return ColorDrawable(Color.WHITE) val top = 5 val bot = image.height - 5 - val left = (image.width * 0.025).toInt() + val left = (image.width * 0.0275).toInt() val right = image.width - left val midX = image.width / 2 val midY = image.height / 2 - val topLeftIsDark = isDark(image.getPixel(left,top)) - val topRightIsDark = isDark(image.getPixel(right,top)) - val midLeftIsDark = isDark(image.getPixel(left,midY)) - val midRightIsDark = isDark(image.getPixel(right,midY)) + val topLeftIsDark = isDark(image.getPixel(left, top)) + val topRightIsDark = isDark(image.getPixel(right, top)) + val midLeftIsDark = isDark(image.getPixel(left, midY)) + val midRightIsDark = isDark(image.getPixel(right, midY)) val topMidIsDark = isDark(image.getPixel(midX, top)) - val botLeftIsDark = isDark(image.getPixel(left,bot)) - val botRightIsDark = isDark(image.getPixel(right,bot)) + val botLeftIsDark = isDark(image.getPixel(left, bot)) + val botRightIsDark = isDark(image.getPixel(right, bot)) var darkBG = (topLeftIsDark && (botLeftIsDark || botRightIsDark || topRightIsDark || midLeftIsDark || topMidIsDark)) || (topRightIsDark && (botRightIsDark || botLeftIsDark || midRightIsDark || topMidIsDark)) - if (pixelIsClose(image.getPixel(left,top), image.getPixel(midX,top)) && // top left & top mid - pixelIsClose(image.getPixel(midX,top), image.getPixel(right,top)) && //top mid & top right - pixelIsClose(image.getPixel(right,top), image.getPixel(right,bot)) && // top right & bot right - pixelIsClose(image.getPixel(right,bot), image.getPixel(midX,bot)) && // bot right & bot mid - pixelIsClose(image.getPixel(midX,bot), image.getPixel(left,bot))) // bot mid & bot left - return ColorDrawable(image.getPixel(left,top)) - val blackPixel = when { - topLeftIsDark -> image.getPixel (left, top) - topRightIsDark -> image.getPixel(right, top) - botLeftIsDark ->image.getPixel(left, bot) - else -> image.getPixel(right, bot) - } - if (isWhite(image.getPixel(left,top)).toInt() + - isWhite(image.getPixel(right,top)).toInt() + - isWhite(image.getPixel(left,bot)).toInt() + - isWhite(image.getPixel(right,bot)).toInt() > 2) - darkBG = false - var overallWhitePixels = 0 - var overallBlackPixels = 0 - outer@ for (x in intArrayOf(left,right)) { - var whitePixelsStreak = 0 - var whitePixels = 0 - var blackPixelsStreak = 0 - var blackPixels = 0 - var blackStreak = false - var whiteStrak = false - for (y in (0 until image.height step image.height / 25)) { - val pixel = image.getPixel(x, y) - if (isWhite(pixel)) { + if (!isWhite(image.getPixel(left, top)) && pixelIsClose(image.getPixel(left, top), image.getPixel(midX, top)) && + !isWhite(image.getPixel(midX, top)) && pixelIsClose(image.getPixel(midX, top), image.getPixel(right, top)) && + !isWhite(image.getPixel(right, top)) && pixelIsClose(image.getPixel(right, top), image.getPixel(right, bot)) && + !isWhite(image.getPixel(right, bot)) && pixelIsClose(image.getPixel(right, bot), image.getPixel(midX, bot)) && + !isWhite(image.getPixel(midX, bot)) && pixelIsClose(image.getPixel(midX, bot), image.getPixel(left, bot)) && + !isWhite(image.getPixel(left, bot)) && pixelIsClose(image.getPixel(left, bot), image.getPixel(left, top))) + return ColorDrawable(image.getPixel(left, top)) + + if (isWhite(image.getPixel(left, top)).toInt() + + isWhite(image.getPixel(right, top)).toInt() + + isWhite(image.getPixel(left, bot)).toInt() + + isWhite(image.getPixel(right, bot)).toInt() > 2) + darkBG = false + + var overallWhitePixels = 0 + var overallBlackPixels = 0 + outer@ for (x in intArrayOf(left, right)) { + var whitePixelsStreak = 0 + var whitePixels = 0 + var blackPixelsStreak = 0 + var blackPixels = 0 + var blackStreak = false + var whiteStrak = false + for (y in (0 until image.height step image.height / 25)) { + val pixel = image.getPixel(x, y) + if (isWhite(pixel)) { + blackPixelsStreak = 0 + whitePixelsStreak++ + whitePixels++ + overallWhitePixels++ + if (whitePixelsStreak > 14) { + whiteStrak = true + } + } else { + whitePixelsStreak = 0 + if (isDark(pixel)) { + blackPixels++ + overallBlackPixels++ + blackPixelsStreak++ + if (blackPixelsStreak > 14) { + blackStreak = true + } + } else { blackPixelsStreak = 0 - whitePixelsStreak++ - whitePixels++ - overallWhitePixels++ - if (whitePixelsStreak > 14) { - whiteStrak = true - } } - else { - whitePixelsStreak = 0 - if (isDark(pixel)) { - blackPixels++ - overallBlackPixels++ - blackPixelsStreak++ - if (blackPixelsStreak > 14) { - blackStreak = true - } - } - else { - blackPixelsStreak = 0 - } - } - } - when { - blackPixels > 22 -> { darkBG = true; overallWhitePixels = 0; break@outer } - blackStreak -> darkBG = true - whiteStrak || whitePixels > 22 -> darkBG = false } } - if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) - darkBG = false - if (darkBG) - { - if (isWhite(image.getPixel(left,bot)) && isWhite(image.getPixel(right,bot))) + when { + blackPixels > 22 -> { + darkBG = true; overallWhitePixels = 0; break@outer + } + blackStreak -> darkBG = true + whiteStrak || whitePixels > 22 -> darkBG = false + } + } + + val blackPixel = when { + topLeftIsDark -> image.getPixel(left, top) + topRightIsDark -> image.getPixel(right, top) + botLeftIsDark -> image.getPixel(left, bot) + else -> image.getPixel(right, bot) + } + if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) { + darkBG = false + } + if (darkBG) { + if (isWhite(image.getPixel(left, bot)) && isWhite(image.getPixel(right, bot))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) - else if (isWhite(image.getPixel(left,top)) && isWhite(image.getPixel(right,top))) + else if (isWhite(image.getPixel(left, top)) && isWhite(image.getPixel(right, top))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) else return ColorDrawable(blackPixel) } + if (topLeftIsDark && topRightIsDark && (topMidIsDark || overallBlackPixels > 9)) + return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) + else if (botLeftIsDark && botRightIsDark && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9)) + return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) return ColorDrawable(Color.WHITE) } From 220cdd3c0566db7b63fe6851f4c4c6b6c240e87c Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 13 Apr 2019 09:44:25 -0700 Subject: [PATCH 04/77] Update PagerPageHolder.kt --- .../ui/reader/viewer/pager/PagerPageHolder.kt | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index b72f9ea66f..9178d03a7f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -4,8 +4,10 @@ import android.annotation.SuppressLint import android.content.Intent import android.graphics.BitmapFactory import android.graphics.PointF +import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.net.Uri +import android.support.v4.graphics.ColorUtils import android.view.GestureDetector import android.view.Gravity import android.view.MotionEvent @@ -255,9 +257,23 @@ class PagerPageHolder( launchUI { val image = async { BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size) } - imageView.background = ImageUtil.autoSetBackground(image.await()) - if (!viewer.config.imageCropBorders) - imageView.setImage(ImageSource.bitmap(image.await())) + val bg = ImageUtil.autoSetBackground(image.await()) + imageView.background = bg + if (!viewer.config.imageCropBorders) { + if (bg is ColorDrawable) { + val array = FloatArray(3) + ColorUtils.colorToHSL(bg.color, array) + if (array[1] < 0.2) { + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + bytesStream.close() + } + else + imageView.setImage(ImageSource.bitmap(image.await())) + } + else + imageView.setImage(ImageSource.bitmap(image.await())) + } } } else { From afde195534f5238d6821fc3990e04995664c28c7 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 13 Apr 2019 12:29:25 -0700 Subject: [PATCH 05/77] More work on bg detection --- .../ui/reader/viewer/pager/PagerPageHolder.kt | 28 ++------- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 58 ++++++++++++++----- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 9178d03a7f..ad7ba428cf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -4,10 +4,8 @@ import android.annotation.SuppressLint import android.content.Intent import android.graphics.BitmapFactory import android.graphics.PointF -import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.net.Uri -import android.support.v4.graphics.ColorUtils import android.view.GestureDetector import android.view.Gravity import android.view.MotionEvent @@ -249,31 +247,13 @@ class PagerPageHolder( val bytesArray = openStream!!.readBytes() val imageView = initSubsamplingImageView() - if (viewer.config.imageCropBorders) { - val bytesStream = bytesArray.inputStream() - imageView.setImage(ImageSource.inputStream(bytesStream)) - bytesStream.close() - } + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + bytesStream.close() launchUI { val image = async { BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size) } - val bg = ImageUtil.autoSetBackground(image.await()) - imageView.background = bg - if (!viewer.config.imageCropBorders) { - if (bg is ColorDrawable) { - val array = FloatArray(3) - ColorUtils.colorToHSL(bg.color, array) - if (array[1] < 0.2) { - val bytesStream = bytesArray.inputStream() - imageView.setImage(ImageSource.inputStream(bytesStream)) - bytesStream.close() - } - else - imageView.setImage(ImageSource.bitmap(image.await())) - } - else - imageView.setImage(ImageSource.bitmap(image.await())) - } + imageView.background = ImageUtil.autoSetBackground(image.await()) } } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index 9398b9d880..da910d2af0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -62,6 +62,8 @@ object ImageUtil { val right = image.width - left val midX = image.width / 2 val midY = image.height / 2 + val offsetX = (image.width * 0.01).toInt() + val offsetY = (image.height * 0.01).toInt() val topLeftIsDark = isDark(image.getPixel(left, top)) val topRightIsDark = isDark(image.getPixel(right, top)) val midLeftIsDark = isDark(image.getPixel(left, midY)) @@ -87,32 +89,43 @@ object ImageUtil { isWhite(image.getPixel(right, bot)).toInt() > 2) darkBG = false + var blackPixel = when { + topLeftIsDark -> image.getPixel(left, top) + topRightIsDark -> image.getPixel(right, top) + botLeftIsDark -> image.getPixel(left, bot) + else -> image.getPixel(right, bot) + } + var overallWhitePixels = 0 var overallBlackPixels = 0 - outer@ for (x in intArrayOf(left, right)) { + outer@ for (x in intArrayOf(left, left - offsetX, right, right + offsetX)) { var whitePixelsStreak = 0 var whitePixels = 0 var blackPixelsStreak = 0 var blackPixels = 0 var blackStreak = false var whiteStrak = false + val notOffset = x == left || x == right for (y in (0 until image.height step image.height / 25)) { val pixel = image.getPixel(x, y) + val pixelOff = image.getPixel(x + (if (x == left) -offsetX else offsetX), y) if (isWhite(pixel)) { blackPixelsStreak = 0 whitePixelsStreak++ whitePixels++ - overallWhitePixels++ + if (notOffset) + overallWhitePixels++ if (whitePixelsStreak > 14) { whiteStrak = true } } else { whitePixelsStreak = 0 - if (isDark(pixel)) { + if (isDark(pixel) && isDark(pixelOff)) { blackPixels++ - overallBlackPixels++ + if (notOffset) + overallBlackPixels++ blackPixelsStreak++ - if (blackPixelsStreak > 14) { + if (blackPixelsStreak >= 14) { blackStreak = true } } else { @@ -122,19 +135,34 @@ object ImageUtil { } when { blackPixels > 22 -> { - darkBG = true; overallWhitePixels = 0; break@outer + if (x == right || x == right + offsetX) + blackPixel = when { + topRightIsDark -> image.getPixel(right, top) + botRightIsDark -> image.getPixel(right, bot) + else -> blackPixel + } + darkBG = true; + overallWhitePixels = 0; + break@outer + } + blackStreak -> { + darkBG = true + if (x == right || x == right + offsetX) + blackPixel = when { + topRightIsDark -> image.getPixel(right, top) + botRightIsDark -> image.getPixel(right, bot) + else -> blackPixel + } + if (blackPixels > 18) { + overallWhitePixels = 0; + break@outer + } } - blackStreak -> darkBG = true whiteStrak || whitePixels > 22 -> darkBG = false } } - val blackPixel = when { - topLeftIsDark -> image.getPixel(left, top) - topRightIsDark -> image.getPixel(right, top) - botLeftIsDark -> image.getPixel(left, bot) - else -> image.getPixel(right, bot) - } + if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) { darkBG = false } @@ -151,7 +179,9 @@ object ImageUtil { if (topLeftIsDark && topRightIsDark && (topMidIsDark || overallBlackPixels > 9)) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) - else if (botLeftIsDark && botRightIsDark && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9)) + else if (botLeftIsDark && botRightIsDark + && isDark(image.getPixel(left - offsetX, bot)) && isDark(image.getPixel(right + offsetX, bot)) + && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9)) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) return ColorDrawable(Color.WHITE) From dc4555f032bab8dfed5036a38d3f809c4ba47e55 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 13 Apr 2019 14:56:56 -0700 Subject: [PATCH 06/77] Moved logic to first load of page stream --- .../ui/reader/loader/HttpPageLoader.kt | 16 +++++++++++++ .../tachiyomi/ui/reader/model/ReaderPage.kt | 4 +++- .../ui/reader/viewer/pager/PagerPageHolder.kt | 23 ++++++++++++------- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 2 +- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 223e9811e3..55b32e5aa5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -1,11 +1,17 @@ package eu.kanade.tachiyomi.ui.reader.loader +import android.graphics.BitmapFactory import eu.kanade.tachiyomi.data.cache.ChapterCache +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderPage +import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig +import eu.kanade.tachiyomi.util.ImageUtil import eu.kanade.tachiyomi.util.plusAssign +import kotlinx.coroutines.experimental.async import rx.Completable import rx.Observable import rx.schedulers.Schedulers @@ -15,6 +21,7 @@ import rx.subscriptions.CompositeSubscription import timber.log.Timber import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import uy.kohesive.injekt.injectLazy import java.util.concurrent.PriorityBlockingQueue import java.util.concurrent.atomic.AtomicInteger @@ -37,6 +44,11 @@ class HttpPageLoader( */ private val subscriptions = CompositeSubscription() + /** + * Preferences helper. + */ + private val preferences by injectLazy() + init { subscriptions += Observable.defer { Observable.just(queue.take().page) } .filter { it.status == Page.QUEUE } @@ -206,6 +218,10 @@ class HttpPageLoader( } .doOnNext { page.stream = { chapterCache.getImageFile(imageUrl).inputStream() } + if (preferences.readerTheme().get() == 2) { + val image = BitmapFactory.decodeStream(chapterCache.getImageFile(imageUrl).inputStream()) + page.bg = ImageUtil.autoSetBackground(image) + } page.status = Page.READY } .doOnError { page.status = Page.ERROR } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt index 34b415253d..4b9b242ebc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.reader.model +import android.graphics.drawable.Drawable import eu.kanade.tachiyomi.source.model.Page import java.io.InputStream @@ -7,7 +8,8 @@ class ReaderPage( index: Int, url: String = "", imageUrl: String? = null, - var stream: (() -> InputStream)? = null + var stream: (() -> InputStream)? = null, + var bg: Drawable? = null ) : Page(index, url, imageUrl, null) { lateinit var chapter: ReaderChapter diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index ad7ba428cf..892126fb31 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -244,16 +244,23 @@ class PagerPageHolder( .doOnNext { isAnimated -> if (!isAnimated) { if (viewer.config.readerTheme == 2) { - val bytesArray = openStream!!.readBytes() - val imageView = initSubsamplingImageView() - val bytesStream = bytesArray.inputStream() - imageView.setImage(ImageSource.inputStream(bytesStream)) - bytesStream.close() + if (page.bg != null) { + imageView.setImage(ImageSource.inputStream(openStream!!)) + imageView.background = page.bg + } + // if the user switches to automatic when pages are already cached, the bg needs to be loaded + else { + val bytesArray = openStream!!.readBytes() + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + bytesStream.close() - launchUI { - val image = async { BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size) } - imageView.background = ImageUtil.autoSetBackground(image.await()) + launchUI { + val image = async { BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size) } + imageView.background = ImageUtil.autoSetBackground(image.await()) + page.bg = imageView.background + } } } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index da910d2af0..c6912747f3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -98,7 +98,7 @@ object ImageUtil { var overallWhitePixels = 0 var overallBlackPixels = 0 - outer@ for (x in intArrayOf(left, left - offsetX, right, right + offsetX)) { + outer@ for (x in intArrayOf(left, right, left - offsetX, right + offsetX)) { var whitePixelsStreak = 0 var whitePixels = 0 var blackPixelsStreak = 0 From b36703a91fddd92dfce8df2a6e2570f702dcf8e1 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 14 May 2019 00:03:25 -0700 Subject: [PATCH 07/77] Fixed loading of background via httppageloader more auto work --- .../ui/reader/loader/HttpPageLoader.kt | 6 ++- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 46 ++++++++++++------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 55b32e5aa5..5e25252334 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -217,11 +217,13 @@ class HttpPageLoader( } } .doOnNext { - page.stream = { chapterCache.getImageFile(imageUrl).inputStream() } if (preferences.readerTheme().get() == 2) { - val image = BitmapFactory.decodeStream(chapterCache.getImageFile(imageUrl).inputStream()) + val stream = chapterCache.getImageFile(imageUrl).inputStream() + val image = BitmapFactory.decodeStream(stream) page.bg = ImageUtil.autoSetBackground(image) + stream.close() } + page.stream = { chapterCache.getImageFile(imageUrl).inputStream() } page.status = Page.READY } .doOnError { page.status = Page.ERROR } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index c6912747f3..382b32430f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -98,6 +98,10 @@ object ImageUtil { var overallWhitePixels = 0 var overallBlackPixels = 0 + var topBlackStreak = 0 + var topWhiteStreak = 0 + var botBlackStreak = 0 + var botWhiteStreak = 0 outer@ for (x in intArrayOf(left, right, left - offsetX, right + offsetX)) { var whitePixelsStreak = 0 var whitePixels = 0 @@ -106,18 +110,18 @@ object ImageUtil { var blackStreak = false var whiteStrak = false val notOffset = x == left || x == right - for (y in (0 until image.height step image.height / 25)) { + for ((index, y) in (0 until image.height step image.height / 25).withIndex()) { val pixel = image.getPixel(x, y) - val pixelOff = image.getPixel(x + (if (x == left) -offsetX else offsetX), y) + val pixelOff = image.getPixel(x + (if (x < image.width/2) -offsetX else offsetX), y) if (isWhite(pixel)) { - blackPixelsStreak = 0 whitePixelsStreak++ whitePixels++ if (notOffset) overallWhitePixels++ - if (whitePixelsStreak > 14) { + if (whitePixelsStreak > 14) whiteStrak = true - } + if (whitePixelsStreak > 6 && whitePixelsStreak >= index - 1) + topWhiteStreak = whitePixelsStreak } else { whitePixelsStreak = 0 if (isDark(pixel) && isDark(pixelOff)) { @@ -125,14 +129,20 @@ object ImageUtil { if (notOffset) overallBlackPixels++ blackPixelsStreak++ - if (blackPixelsStreak >= 14) { + if (blackPixelsStreak >= 14) blackStreak = true - } - } else { - blackPixelsStreak = 0 + continue } } + if (blackPixelsStreak > 6 && blackPixelsStreak >= index - 1) + topBlackStreak = blackPixelsStreak + blackPixelsStreak = 0 + } + if (blackPixelsStreak > 6) + botBlackStreak = blackPixelsStreak + else if (whitePixelsStreak > 6) + botWhiteStreak = whitePixelsStreak when { blackPixels > 22 -> { if (x == right || x == right + offsetX) @@ -162,10 +172,12 @@ object ImageUtil { } } - - if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) { + val topIsBlackStreak = topBlackStreak > topWhiteStreak + val bottomIsBlackStreak = botBlackStreak > botWhiteStreak + if (overallWhitePixels > 9 && overallWhitePixels > overallBlackPixels) darkBG = false - } + if (topIsBlackStreak && bottomIsBlackStreak) + darkBG = true if (darkBG) { if (isWhite(image.getPixel(left, bot)) && isWhite(image.getPixel(right, bot))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, @@ -176,12 +188,14 @@ object ImageUtil { else return ColorDrawable(blackPixel) } - if (topLeftIsDark && topRightIsDark && (topMidIsDark || overallBlackPixels > 9)) + if (topIsBlackStreak || (topLeftIsDark && topRightIsDark + && isDark(image.getPixel(left - offsetX, top)) && isDark(image.getPixel(right + offsetX, top)) + && (topMidIsDark || overallBlackPixels > 9))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) - else if (botLeftIsDark && botRightIsDark - && isDark(image.getPixel(left - offsetX, bot)) && isDark(image.getPixel(right + offsetX, bot)) - && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9)) + else if (bottomIsBlackStreak || (botLeftIsDark && botRightIsDark + && isDark(image.getPixel(left - offsetX, bot)) && isDark(image.getPixel(right + offsetX, bot)) + && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) return ColorDrawable(Color.WHITE) From c0e4b9bb3805c663598f258a707d6e1c354b133b Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 23 Oct 2019 23:43:18 -0700 Subject: [PATCH 08/77] Dark Theme based on system --- .../kanade/tachiyomi/ui/main/MainActivity.kt | 41 +++++++++-- .../ui/setting/SettingsGeneralController.kt | 16 +++-- .../eu/kanade/tachiyomi/util/ImageUtil.kt | 11 +-- app/src/main/res/layout/main_activity.xml | 1 + app/src/main/res/values-night/themes.xml | 71 +++++++++++++++++++ app/src/main/res/values-v21/themes.xml | 12 +--- app/src/main/res/values-v29/themes.xml | 28 ++++++++ app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 67 +---------------- 9 files changed, 161 insertions(+), 89 deletions(-) create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values-v29/themes.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 9fc4fa6ccf..69dc5ab0e4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -3,12 +3,18 @@ package eu.kanade.tachiyomi.ui.main import android.animation.ObjectAnimator import android.app.SearchManager import android.content.Intent +import android.content.res.Configuration import android.graphics.Color import android.os.Bundle import android.support.v4.view.GravityCompat import android.support.v4.widget.DrawerLayout +import android.support.v7.app.AppCompatDelegate +import android.support.v7.app.AppCompatDelegate.* import android.support.v7.graphics.drawable.DrawerArrowDrawable +import android.view.View import android.view.ViewGroup +import android.view.WindowInsets +import android.widget.LinearLayout import com.bluelinelabs.conductor.* import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.R @@ -50,10 +56,14 @@ class MainActivity : BaseActivity() { lateinit var tabAnimator: TabsAnimator override fun onCreate(savedInstanceState: Bundle?) { + setDefaultNightMode(when (preferences.theme()) { + 1 -> MODE_NIGHT_NO + 2, 3, 4 -> MODE_NIGHT_YES + else -> MODE_NIGHT_FOLLOW_SYSTEM + }) setTheme(when (preferences.theme()) { - 2 -> R.style.Theme_Tachiyomi_Dark - 3 -> R.style.Theme_Tachiyomi_Amoled - 4 -> R.style.Theme_Tachiyomi_DarkBlue + 3, 6 -> R.style.Theme_Tachiyomi_Amoled + 4, 7 -> R.style.Theme_Tachiyomi_DarkBlue else -> R.style.Theme_Tachiyomi }) super.onCreate(savedInstanceState) @@ -63,7 +73,7 @@ class MainActivity : BaseActivity() { finish() return } - + //AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO) setContentView(R.layout.main_activity) setSupportActionBar(toolbar) @@ -103,6 +113,15 @@ class MainActivity : BaseActivity() { val container: ViewGroup = findViewById(R.id.controller_container) + val content: LinearLayout = findViewById(R.id.main_content) + container.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + content.setOnApplyWindowInsetsListener(NoopWindowInsetsListener) + router = Conductor.attachRouter(this, container, savedInstanceState) if (!router.hasRootController()) { // Set start screen @@ -280,3 +299,17 @@ class MainActivity : BaseActivity() { } } + +object NoopWindowInsetsListener : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + v.setPadding(0,insets.systemWindowInsetTop,0,0) + return insets + } +} + +object NoopWindowInsetsListener2 : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + v.setPadding(0,0,0,insets.systemWindowInsetBottom) + return insets + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt index bc1eb64683..47fe4b8e40 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt @@ -1,8 +1,10 @@ package eu.kanade.tachiyomi.ui.setting import android.app.Dialog +import android.os.Build import android.os.Bundle import android.os.Handler +import android.support.v7.app.AppCompatDelegate import android.support.v7.preference.PreferenceScreen import android.view.View import com.afollestad.materialdialogs.MaterialDialog @@ -53,12 +55,18 @@ class SettingsGeneralController : SettingsController() { key = Keys.theme titleRes = R.string.pref_theme entriesRes = arrayOf(R.string.light_theme, R.string.dark_theme, - R.string.amoled_theme, R.string.darkblue_theme) - entryValues = arrayOf("1", "2", "3", "4") - defaultValue = "1" + R.string.amoled_theme, R.string.darkblue_theme, + R.string.system_theme, R.string.system_amoled_theme, R.string.system_darkblue_theme) + entryValues = arrayOf("1", "2", "3", "4", "5", "6", "7") + defaultValue = "5" summary = "%s" - onChange { + onChange {newValue -> + AppCompatDelegate.setDefaultNightMode(when (newValue) { + "1" -> AppCompatDelegate.MODE_NIGHT_NO + "2", "3", "4" -> AppCompatDelegate.MODE_NIGHT_YES + else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM + }) activity?.recreate() true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index 382b32430f..0d0524f0f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -178,13 +178,14 @@ object ImageUtil { darkBG = false if (topIsBlackStreak && bottomIsBlackStreak) darkBG = true + val whiteColor = android.R.attr.colorBackground if (darkBG) { if (isWhite(image.getPixel(left, bot)) && isWhite(image.getPixel(right, bot))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) + intArrayOf(blackPixel, blackPixel, whiteColor, whiteColor)) else if (isWhite(image.getPixel(left, top)) && isWhite(image.getPixel(right, top))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) + intArrayOf(whiteColor, whiteColor, blackPixel, blackPixel)) else return ColorDrawable(blackPixel) } @@ -192,13 +193,13 @@ object ImageUtil { && isDark(image.getPixel(left - offsetX, top)) && isDark(image.getPixel(right + offsetX, top)) && (topMidIsDark || overallBlackPixels > 9))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(blackPixel, blackPixel, Color.WHITE, Color.WHITE)) + intArrayOf(blackPixel, blackPixel, whiteColor, whiteColor)) else if (bottomIsBlackStreak || (botLeftIsDark && botRightIsDark && isDark(image.getPixel(left - offsetX, bot)) && isDark(image.getPixel(right + offsetX, bot)) && (isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9))) return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(Color.WHITE, Color.WHITE, blackPixel, blackPixel)) - return ColorDrawable(Color.WHITE) + intArrayOf(whiteColor, whiteColor, blackPixel, blackPixel)) + return ColorDrawable(whiteColor) } fun Boolean.toInt() = if (this) 1 else 0 diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index cbc9d2a6f4..beeedf5c33 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -11,6 +11,7 @@ android:orientation="vertical" android:id="@+id/main_content" android:layout_width="match_parent" + android:fitsSystemWindows="true" android:layout_height="match_parent"> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml index a7ff1d5c4b..2af45a9f12 100644 --- a/app/src/main/res/values-v21/themes.xml +++ b/app/src/main/res/values-v21/themes.xml @@ -10,17 +10,7 @@ @color/colorPrimaryDark - - - - - - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 506a528dd2..ae22047bd8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -143,6 +143,9 @@ Dark theme AMOLED theme Dark blue + System default + System default (AMOLED) + System default (Dark blue) Start screen Language System default diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index c04866ac69..3d13686f1d 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -9,7 +9,7 @@ - - - - - - - - - - - - - - - - - - - - - - - From b17717181dbdbe5652187f918df764ec15ca0542 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 24 Oct 2019 02:47:41 -0700 Subject: [PATCH 10/77] android 28 sdk --- app/build.gradle | 8 ++++---- .../catalogue/browse/BrowseCatalogueController.kt | 2 +- .../global_search/CatalogueSearchAdapter.kt | 4 ++-- .../kanade/tachiyomi/ui/manga/MangaController.kt | 2 +- .../reader/viewer/webtoon/WebtoonRecyclerView.kt | 4 ++-- .../ui/reader/viewer/webtoon/WebtoonViewer.kt | 14 ++++++++------ .../ui/setting/SettingsAboutController.kt | 4 ++-- app/src/main/res/values-night/themes.xml | 12 +----------- app/src/main/res/values-v21/themes.xml | 2 +- 9 files changed, 22 insertions(+), 30 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 141e7ec695..c3e57db263 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,14 +29,14 @@ ext { } android { - compileSdkVersion 27 - buildToolsVersion '28.0.3' + compileSdkVersion 28 + buildToolsVersion '29.0.2' publishNonDefault true defaultConfig { applicationId "eu.kanade.tachiyomi" minSdkVersion 16 - targetSdkVersion 27 + targetSdkVersion 28 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" versionCode 41 versionName "0.8.4" @@ -101,7 +101,7 @@ dependencies { implementation 'com.github.inorichi:junrar-android:634c1f5' // Android support library - final support_library_version = '27.0.2' + final support_library_version = '28.0.0' implementation "com.android.support:support-v4:$support_library_version" implementation "com.android.support:appcompat-v7:$support_library_version" implementation "com.android.support:cardview-v7:$support_library_version" diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 97cfd76e16..de7e23ca26 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -201,7 +201,7 @@ open class BrowseCatalogueController(bundle: Bundle) : catalogue_view.addView(recycler, 1) if (oldPosition != RecyclerView.NO_POSITION) { - recycler.layoutManager.scrollToPosition(oldPosition) + recycler.layoutManager?.scrollToPosition(oldPosition) } this.recycler = recycler } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt index 0b1b822e0f..0eabb89810 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt @@ -19,8 +19,8 @@ class CatalogueSearchAdapter(val controller: CatalogueSearchController) : */ private var bundle = Bundle() - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: List?) { - super.onBindViewHolder(holder, position, payloads) + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + super.onBindViewHolder(holder, position) restoreHolderState(holder) } 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 c56cc7541c..a57a2319b5 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 @@ -187,7 +187,7 @@ class MangaController : RxController, TabbedController { const val CHAPTERS_CONTROLLER = 1 const val TRACK_CONTROLLER = 2 - private val tabField = TabLayout.Tab::class.java.getDeclaredField("mView") + private val tabField = TabLayout.Tab::class.java.getDeclaredField("view") .apply { isAccessible = true } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt index eae782c931..5ae6b4dcb9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt @@ -62,8 +62,8 @@ open class WebtoonRecyclerView @JvmOverloads constructor( override fun onScrollStateChanged(state: Int) { super.onScrollStateChanged(state) val layoutManager = layoutManager - val visibleItemCount = layoutManager.childCount - val totalItemCount = layoutManager.itemCount + val visibleItemCount = layoutManager?.childCount ?: 0 + val totalItemCount = layoutManager?.itemCount ?: 0 atLastPosition = visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 atFirstPosition = firstVisibleItemPosition == 0 } 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 6adee83c2f..51d8bd1213 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 @@ -67,7 +67,7 @@ class WebtoonViewer(val activity: ReaderActivity) : BaseViewer { recycler.layoutManager = layoutManager recycler.adapter = adapter recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { - override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { val position = layoutManager.findLastEndVisibleItemPosition() val item = adapter.items.getOrNull(position) if (item != null && currentPage != item) { @@ -98,11 +98,13 @@ class WebtoonViewer(val activity: ReaderActivity) : BaseViewer { recycler.longTapListener = f@ { event -> if (activity.menuVisible || config.longTapEnabled) { val child = recycler.findChildViewUnder(event.x, event.y) - val position = recycler.getChildAdapterPosition(child) - val item = adapter.items.getOrNull(position) - if (item is ReaderPage) { - activity.onPageLongTap(item) - return@f true + if(child != null) { + val position = recycler.getChildAdapterPosition(child) + val item = adapter.items.getOrNull(position) + if (item is ReaderPage) { + activity.onPageLongTap(item) + return@f true + } } } false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt index a736da2a5e..7e96803e7b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt @@ -151,14 +151,14 @@ class SettingsAboutController : SettingsController() { override fun onCreateDialog(savedViewState: Bundle?): Dialog { return MaterialDialog.Builder(activity!!) .title(R.string.update_check_title) - .content(args.getString(BODY_KEY)) + .content(args.getString(BODY_KEY) ?: "") .positiveText(R.string.update_check_confirm) .negativeText(R.string.update_check_ignore) .onPositive { _, _ -> val appContext = applicationContext if (appContext != null) { // Start download - val url = args.getString(URL_KEY) + val url = args.getString(URL_KEY) ?: "" UpdaterService.downloadUpdate(appContext, url) } } diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index b80e9d0e3c..b543bf07dc 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -16,6 +16,7 @@ @drawable/line_divider_dark + true @style/ThemeOverlay.AppCompat.Dark.ActionBar @style/ThemeOverlay.AppCompat @style/PreferenceThemeOverlay.Material @@ -30,17 +31,6 @@ @color/textColorPrimaryDark @color/dialogDark @color/iconColorDark - - - @android:color/transparent - @color/colorDarkPrimaryDark - - - diff --git a/app/src/main/res/values-v29/themes.xml b/app/src/main/res/values-v29/themes.xml index bb7e609435..54e5d44548 100644 --- a/app/src/main/res/values-v29/themes.xml +++ b/app/src/main/res/values-v29/themes.xml @@ -8,9 +8,6 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index eab6d88749..9ff1db179d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -2,10 +2,10 @@ #54759E - #435E7E + #54759E #212121 - #1C1C1D + #212121 @color/md_black_1000 From 3930345cbd537053929bbead87e218430db55499 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 14:20:46 -0700 Subject: [PATCH 13/77] more insets work --- .../browse/BrowseCatalogueController.kt | 6 +++-- .../tachiyomi/ui/library/LibraryController.kt | 24 ++++++++++++++--- .../kanade/tachiyomi/ui/main/MainActivity.kt | 19 +++++++++++--- .../ui/manga/chapter/ChaptersController.kt | 1 - .../tachiyomi/ui/reader/ReaderActivity.kt | 13 ++++++++++ .../kanade/tachiyomi/util/ViewExtensions.kt | 26 +++++++++++++++++++ .../tachiyomi/widget/SimpleNavigationView.kt | 3 ++- app/src/main/res/drawable/bg_snackbar.xml | 6 +++++ app/src/main/res/layout/catalogue_drawer.xml | 9 +++++-- app/src/main/res/layout/library_drawer.xml | 9 ++++++- .../main/res/values-notnight-v29/themes.xml | 2 ++ 11 files changed, 105 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/drawable/bg_snackbar.xml create mode 100644 app/src/main/res/values-notnight-v29/themes.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 29b9ed0d01..63e3125f48 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog +import eu.kanade.tachiyomi.ui.library.HeightTopWindowInsetsListener import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController @@ -154,9 +155,10 @@ open class BrowseCatalogueController(bundle: Bundle) : presenter.sourceFilters = newFilters navView.setFilters(presenter.filterItems) } - + val statusScrim = navView.findViewById(R.id.status_bar_scrim) as View + statusScrim.setOnApplyWindowInsetsListener(HeightTopWindowInsetsListener) navView.doOnApplyWindowInsets { v, insets, padding -> - v.updatePaddingRelative( + navView.recycler.updatePaddingRelative( bottom = padding.bottom + insets.systemWindowInsetBottom, top = padding.top + insets.systemWindowInsetTop ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 61b544f428..5eadbacf0a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -191,10 +191,16 @@ class LibraryController( is LibraryNavigationView.BadgeGroup -> onDownloadBadgeChanged() } } + + drawer.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + val statusScrim = view.findViewById(R.id.status_bar_scrim) as View + statusScrim.setOnApplyWindowInsetsListener(HeightTopWindowInsetsListener) view.doOnApplyWindowInsets { v, insets, padding -> - v.updatePaddingRelative( - bottom = padding.bottom + insets.systemWindowInsetBottom, - top = padding.top + insets.systemWindowInsetTop + view.recycler.updatePaddingRelative( + bottom = view.recycler.bottom + insets.systemWindowInsetBottom, + top = view.recycler.top + insets.systemWindowInsetTop ) } return view @@ -530,3 +536,15 @@ class LibraryController( } } + +object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + val topInset = insets.systemWindowInsetTop + v.setPadding(0,topInset,0,0) + if (v.layoutParams.height != topInset) { + v.layoutParams.height = topInset + v.requestLayout() + } + return insets + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 5381d33eeb..5f345e1fc8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -5,7 +5,9 @@ import android.app.SearchManager import android.content.Intent import android.content.res.Configuration import android.graphics.Color +import android.os.Build import android.os.Bundle +import android.support.annotation.NonNull import android.support.annotation.Px import android.support.annotation.RequiresApi import android.support.v4.view.GravityCompat @@ -120,6 +122,12 @@ class MainActivity : BaseActivity() { true } + nav_view.doOnApplyWindowInsets { v, insets, padding -> + v.updatePaddingRelative( + start = padding.left + insets.systemWindowInsetLeft + ) + } + val container: ViewGroup = findViewById(R.id.controller_container) val content: LinearLayout = findViewById(R.id.main_content) @@ -130,6 +138,10 @@ class MainActivity : BaseActivity() { View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION content.setOnApplyWindowInsetsListener(NoopWindowInsetsListener) + val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + if (Build.VERSION.SDK_INT >= 26 && currentNightMode == Configuration.UI_MODE_NIGHT_NO) { + content.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR + } router = Conductor.attachRouter(this, container, savedInstanceState) if (!router.hasRootController()) { @@ -319,16 +331,17 @@ object NoopWindowInsetsListener : View.OnApplyWindowInsetsListener { object NoopWindowInsetsListener2 : View.OnApplyWindowInsetsListener { override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { - v.setPadding(0,0,0,insets.systemWindowInsetBottom) + v.setPadding(0,0,0,insets + .systemWindowInsetBottom) insets.consumeSystemWindowInsets() return insets } } -fun View.doOnApplyWindowInsets(f: (View, WindowInsetsCompat, ViewPaddingState) -> Unit) { +fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) { // Create a snapshot of the view's padding state val paddingState = createStateForView(this) - ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets -> + setOnApplyWindowInsetsListener { v, insets -> f(v, insets, paddingState) insets } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index 602fcaec9d..334988a550 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -98,7 +98,6 @@ class ChaptersController : NucleusController(), bottomMargin = insets.systemWindowInsetBottom } } - //fast_scroller.setOnApplyWindowInsetsListener(NoopWindowInsetsListener2) swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() } fab.clicks().subscribeUntilDestroy { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 82c7ffbe5a..1d5ef8f265 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -21,6 +21,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity +import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets +import eu.kanade.tachiyomi.ui.main.updateLayoutParams +import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success @@ -136,6 +139,16 @@ class ReaderActivity : BaseRxActivity() { config = ReaderConfig() initializeMenu() + val container: ViewGroup = findViewById(R.id.reader_container) + val readerBHeight = reader_menu_bottom.layoutParams.height + container.doOnApplyWindowInsets { _, insets, padding -> + val bottomInset = insets.mandatorySystemGestureInsets.bottom - insets + .systemWindowInsetBottom + reader_menu_bottom.updateLayoutParams { + height = readerBHeight + bottomInset + } + reader_menu_bottom.updatePaddingRelative(bottom = padding.bottom + bottomInset) + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt index af9b041e29..5e3c94a57a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -2,14 +2,26 @@ package eu.kanade.tachiyomi.util +import android.content.Context import android.graphics.Color import android.graphics.Point import android.graphics.Typeface +import android.os.Build import android.support.design.widget.Snackbar +import android.support.v4.view.ViewCompat +import android.support.v4.view.WindowInsetsCompat import android.view.View +import android.view.ViewGroup +import android.view.Window +import android.view.WindowInsets import android.widget.TextView import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.util.ColorGenerator +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets +import eu.kanade.tachiyomi.ui.main.marginBottom +import eu.kanade.tachiyomi.ui.main.updateLayoutParams +import eu.kanade.tachiyomi.ui.main.updatePaddingRelative /** * Returns coordinates of view. @@ -30,11 +42,25 @@ inline fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: Sn val snack = Snackbar.make(this, message, length) val textView: TextView = snack.view.findViewById(android.support.design.R.id.snackbar_text) textView.setTextColor(Color.WHITE) + when { + Build.VERSION.SDK_INT >= 23 -> snack.config(context, rootWindowInsets.systemWindowInsetBottom) + else -> snack.config(context) + } snack.f() snack.show() return snack } +fun Snackbar.config(context: Context, bottomMargin: Int = 0) { + val params = this.view.layoutParams as ViewGroup.MarginLayoutParams + params.setMargins(12, 12, 12, 12 + bottomMargin) + this.view.layoutParams = params + + this.view.background = context.getDrawable(R.drawable.bg_snackbar) + + ViewCompat.setElevation(this.view, 6f) +} + inline fun View.visible() { visibility = View.VISIBLE } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/SimpleNavigationView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/SimpleNavigationView.kt index 31fcec901c..4c21e897cd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/SimpleNavigationView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/SimpleNavigationView.kt @@ -32,7 +32,7 @@ open class SimpleNavigationView @JvmOverloads constructor( /** * Recycler view containing all the items. */ - protected val recycler = RecyclerView(context) + val recycler = RecyclerView(context) init { // Custom attributes @@ -57,6 +57,7 @@ open class SimpleNavigationView @JvmOverloads constructor( a.recycle() recycler.layoutManager = LinearLayoutManager(context) + recycler.clipToPadding = false } /** diff --git a/app/src/main/res/drawable/bg_snackbar.xml b/app/src/main/res/drawable/bg_snackbar.xml new file mode 100644 index 0000000000..63ea0348c8 --- /dev/null +++ b/app/src/main/res/drawable/bg_snackbar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/catalogue_drawer.xml b/app/src/main/res/layout/catalogue_drawer.xml index 672161f6c8..cfcd725c1c 100644 --- a/app/src/main/res/layout/catalogue_drawer.xml +++ b/app/src/main/res/layout/catalogue_drawer.xml @@ -5,5 +5,10 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="end" - android:fitsSystemWindows="true"/> - + android:fitsSystemWindows="true"> + + diff --git a/app/src/main/res/layout/library_drawer.xml b/app/src/main/res/layout/library_drawer.xml index 914c329ddb..1289498950 100644 --- a/app/src/main/res/layout/library_drawer.xml +++ b/app/src/main/res/layout/library_drawer.xml @@ -5,4 +5,11 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="end" - android:fitsSystemWindows="true" /> + android:fitsSystemWindows="true" + android:clipToPadding="true"> + + \ No newline at end of file diff --git a/app/src/main/res/values-notnight-v29/themes.xml b/app/src/main/res/values-notnight-v29/themes.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/app/src/main/res/values-notnight-v29/themes.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 71bf9dc828f1e046a003980a0261fa562d1b7f45 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 14:49:34 -0700 Subject: [PATCH 14/77] Updated gradle gms --- app/build.gradle | 2 +- .../tachiyomi/data/backup/BackupRestoreService.kt | 2 +- .../tachiyomi/data/library/LibraryUpdateJob.kt | 2 +- .../data/preference/SharedPreferencesDataStore.kt | 2 +- .../extension/util/ExtensionInstallActivity.kt | 2 +- .../tachiyomi/extension/util/ExtensionLoader.kt | 2 +- .../ui/catalogue/SourceDividerItemDecoration.kt | 2 +- .../global_search/CatalogueSearchAdapter.kt | 2 +- .../ui/extension/ExtensionDetailsController.kt | 2 +- .../ui/extension/ExtensionDividerItemDecoration.kt | 2 +- .../tachiyomi/ui/extension/ExtensionTrustDialog.kt | 4 ++-- .../kanade/tachiyomi/ui/library/LibraryController.kt | 5 +++-- .../tachiyomi/ui/manga/info/MangaInfoController.kt | 2 +- .../tachiyomi/ui/manga/track/TrackSearchAdapter.kt | 2 +- .../eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt | 4 ++-- .../tachiyomi/ui/reader/loader/DownloadPageLoader.kt | 4 +++- .../tachiyomi/ui/setting/SettingsBackupController.kt | 12 +++++++----- .../ui/setting/SettingsDownloadController.kt | 7 ++++--- .../java/eu/kanade/tachiyomi/util/LocaleHelper.kt | 6 +++--- build.gradle | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 21 files changed, 41 insertions(+), 35 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 7771286ac1..c2875906b1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -234,7 +234,7 @@ dependencies { } buildscript { - ext.kotlin_version = '1.2.71' + ext.kotlin_version = '1.3.50' repositories { mavenCentral() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index db6866e289..87701c20d9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -189,7 +189,7 @@ class BackupRestoreService : Service() { return Observable.just(Unit) .map { - val reader = JsonReader(contentResolver.openInputStream(uri).bufferedReader()) + val reader = JsonReader(contentResolver.openInputStream(uri)!!.bufferedReader()) val json = JsonParser().parse(reader).asJsonObject // Get parser version diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index ab386b1330..2fb2e5d83a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -22,7 +22,7 @@ class LibraryUpdateJob : Job() { val preferences = Injekt.get() val interval = prefInterval ?: preferences.libraryUpdateInterval().getOrDefault() if (interval > 0) { - val restrictions = preferences.libraryUpdateRestriction() + val restrictions = preferences.libraryUpdateRestriction()!! val acRestriction = "ac" in restrictions val wifiRestriction = if ("wifi" in restrictions) JobRequest.NetworkType.UNMETERED diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt index bb07bb0a52..8ac81e6b2b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt @@ -46,7 +46,7 @@ class SharedPreferencesDataStore(private val prefs: SharedPreferences) : Prefere } override fun getStringSet(key: String?, defValues: MutableSet?): MutableSet { - return prefs.getStringSet(key, defValues) + return prefs.getStringSet(key, defValues)!! } override fun putStringSet(key: String?, values: MutableSet?) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt index 421cfb191d..5dcd6bb126 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt @@ -39,7 +39,7 @@ class ExtensionInstallActivity : Activity() { } private fun checkInstallationResult(resultCode: Int) { - val downloadId = intent.extras.getLong(ExtensionInstaller.EXTRA_DOWNLOAD_ID) + val downloadId = intent.extras!!.getLong(ExtensionInstaller.EXTRA_DOWNLOAD_ID) val success = resultCode == RESULT_OK val extensionManager = Injekt.get() diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt index 805effe064..450eae3127 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt @@ -121,7 +121,7 @@ internal object ExtensionLoader { val classLoader = PathClassLoader(appInfo.sourceDir, null, context.classLoader) - val sources = appInfo.metaData.getString(METADATA_SOURCE_CLASS) + val sources = appInfo.metaData.getString(METADATA_SOURCE_CLASS)!! .split(";") .map { val sourceClass = it.trim() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceDividerItemDecoration.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceDividerItemDecoration.kt index a4c33beb75..e21b58124f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceDividerItemDecoration.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceDividerItemDecoration.kt @@ -13,7 +13,7 @@ class SourceDividerItemDecoration(context: Context) : RecyclerView.ItemDecoratio init { val a = context.obtainStyledAttributes(intArrayOf(android.R.attr.listDivider)) - divider = a.getDrawable(0) + divider = a.getDrawable(0)!! a.recycle() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt index 0eabb89810..430b6f5b67 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchAdapter.kt @@ -38,7 +38,7 @@ class CatalogueSearchAdapter(val controller: CatalogueSearchController) : override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) - bundle = savedInstanceState.getBundle(HOLDER_BUNDLE_KEY) + bundle = savedInstanceState.getBundle(HOLDER_BUNDLE_KEY)!! } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt index 2005a93889..d0c457f3ec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt @@ -47,7 +47,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) : } override fun createPresenter(): ExtensionDetailsPresenter { - return ExtensionDetailsPresenter(args.getString(PKGNAME_KEY)) + return ExtensionDetailsPresenter(args.getString(PKGNAME_KEY)!!) } override fun getTitle(): String? { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDividerItemDecoration.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDividerItemDecoration.kt index 40fe44505d..247206df7c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDividerItemDecoration.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDividerItemDecoration.kt @@ -13,7 +13,7 @@ class ExtensionDividerItemDecoration(context: Context) : RecyclerView.ItemDecora init { val a = context.obtainStyledAttributes(intArrayOf(android.R.attr.listDivider)) - divider = a.getDrawable(0) + divider = a.getDrawable(0)!! a.recycle() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionTrustDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionTrustDialog.kt index 3094e90620..6c1f8bc0a0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionTrustDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionTrustDialog.kt @@ -24,10 +24,10 @@ class ExtensionTrustDialog(bundle: Bundle? = null) : DialogController(bundle) .positiveText(R.string.ext_trust) .negativeText(R.string.ext_uninstall) .onPositive { _, _ -> - (targetController as? Listener)?.trustSignature(args.getString(SIGNATURE_KEY)) + (targetController as? Listener)?.trustSignature(args.getString(SIGNATURE_KEY)!!) } .onNegative { _, _ -> - (targetController as? Listener)?.uninstallExtension(args.getString(PKGNAME_KEY)) + (targetController as? Listener)?.uninstallExtension(args.getString(PKGNAME_KEY)!!) } .build() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 5eadbacf0a..a8bee9cdcc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -4,6 +4,7 @@ import android.app.Activity import android.content.Intent import android.content.res.Configuration import android.graphics.Color +import android.net.Uri import android.os.Bundle import android.support.design.widget.TabLayout import android.support.v4.graphics.drawable.DrawableCompat @@ -512,9 +513,9 @@ class LibraryController( try { // Get the file's input stream from the incoming Intent - activity.contentResolver.openInputStream(data.data).use { + activity.contentResolver.openInputStream(data.data ?: Uri.EMPTY).use { // Update cover to selected file, show error if something went wrong - if (presenter.editCoverWithStream(it, manga)) { + if (it != null && presenter.editCoverWithStream(it, manga)) { // TODO refresh cover } else { activity.toast(R.string.notification_cover_update_failed) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index 0589b8b086..6e018e3d23 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -521,7 +521,7 @@ class MangaInfoController : NucleusController(), val view = view ?: return val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.primaryClip = ClipData.newPlainText(label, content) + clipboard.setPrimaryClip(ClipData.newPlainText(label, content)) activity.toast(view.context.getString(R.string.copied_to_clipboard, content.truncateCenter(20)), Toast.LENGTH_SHORT) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt index c11a9bdd0a..a4ea105ef4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt @@ -19,7 +19,7 @@ class TrackSearchAdapter(context: Context) override fun getView(position: Int, view: View?, parent: ViewGroup): View { var v = view // Get the data item for this position - val track = getItem(position) + val track = getItem(position)!! // Check if an existing view is being reused, otherwise inflate the view val holder: TrackSearchHolder // view lookup cache stored in tag if (v == null) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 1d5ef8f265..1547b863fd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -122,8 +122,8 @@ class ReaderActivity : BaseRxActivity() { setContentView(R.layout.reader_activity) if (presenter.needsInit()) { - val manga = intent.extras.getLong("manga", -1) - val chapter = intent.extras.getLong("chapter", -1) + val manga = intent.extras!!.getLong("manga", -1) + val chapter = intent.extras!!.getLong("chapter", -1) if (manga == -1L || chapter == -1L) { finish() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt index af7d969305..c64947a321 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.reader.loader import android.app.Application +import android.net.Uri import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.source.Source @@ -9,6 +10,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import rx.Observable import uy.kohesive.injekt.injectLazy +import java.io.InputStream /** * Loader used to load a chapter from the downloaded chapters. @@ -33,7 +35,7 @@ class DownloadPageLoader( .map { pages -> pages.map { page -> ReaderPage(page.index, page.url, page.imageUrl, { - context.contentResolver.openInputStream(page.uri) + context.contentResolver.openInputStream(page.uri ?: Uri.EMPTY)!! }).apply { status = Page.READY } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt index 597cc4eef2..804d097e59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt @@ -158,7 +158,7 @@ class SettingsBackupController : SettingsController() { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION - + if (uri != null) activity.contentResolver.takePersistableUriPermission(uri, flags) } @@ -168,7 +168,7 @@ class SettingsBackupController : SettingsController() { CODE_BACKUP_CREATE -> if (data != null && resultCode == Activity.RESULT_OK) { val activity = activity ?: return val uri = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - val dir = data.data.path + val dir = data.data?.path val file = File(dir, Backup.getDefaultFilename()) Uri.fromFile(file) @@ -177,6 +177,7 @@ class SettingsBackupController : SettingsController() { val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION + if (uri != null) activity.contentResolver.takePersistableUriPermission(uri, flags) val file = UniFile.fromUri(activity, uri) @@ -188,7 +189,8 @@ class SettingsBackupController : SettingsController() { } CODE_BACKUP_RESTORE -> if (data != null && resultCode == Activity.RESULT_OK) { val uri = data.data - RestoreBackupDialog(uri).showDialog(router) + if (uri != null) + RestoreBackupDialog(uri).showDialog(router) } } } @@ -311,7 +313,7 @@ class SettingsBackupController : SettingsController() { val context = applicationContext if (context != null) { RestoringBackupDialog().showDialog(router, TAG_RESTORING_BACKUP_DIALOG) - BackupRestoreService.start(context, args.getParcelable(KEY_URI)) + BackupRestoreService.start(context, args.getParcelable(KEY_URI)!!) } } .build() @@ -385,7 +387,7 @@ class SettingsBackupController : SettingsController() { .negativeText(R.string.action_open_log) .onNegative { _, _ -> val context = applicationContext ?: return@onNegative - if (!path.isEmpty()) { + if (!path!!.isEmpty()) { val destFile = File(path, file) val uri = destFile.getUriCompat(context) val sendIntent = Intent(Intent.ACTION_VIEW).apply { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt index 1b6119b13c..ae53eeabad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt @@ -118,8 +118,8 @@ class SettingsDownloadController : SettingsController() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { DOWNLOAD_DIR_PRE_L -> if (data != null && resultCode == Activity.RESULT_OK) { - val uri = Uri.fromFile(File(data.data.path)) - preferences.downloadsDirectory().set(uri.toString()) + val uri = Uri.fromFile(File(data.data?.path)) + preferences.downloadsDirectory().set(uri?.toString() ?: "") } DOWNLOAD_DIR_L -> if (data != null && resultCode == Activity.RESULT_OK) { val context = applicationContext ?: return @@ -128,7 +128,8 @@ class SettingsDownloadController : SettingsController() { Intent.FLAG_GRANT_WRITE_URI_PERMISSION @Suppress("NewApi") - context.contentResolver.takePersistableUriPermission(uri, flags) + if (uri != null) + context.contentResolver.takePersistableUriPermission(uri, flags) val file = UniFile.fromUri(context, uri) preferences.downloadsDirectory().set(file.uri.toString()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt index 14e6726e3a..0cb6715f75 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt @@ -30,7 +30,7 @@ object LocaleHelper { /** * The application's locale. When it's null, the system locale is used. */ - private var appLocale = getLocaleFromString(preferences.lang()) + private var appLocale = getLocaleFromString(preferences.lang() ?: "") /** * The currently applied locale. Used to avoid losing the selected language after a non locale @@ -136,9 +136,9 @@ object LocaleHelper { private fun updateConfigLocale(config: Configuration, locale: Locale): Configuration { val newConfig = Configuration(config) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - newConfig.locale = locale + newConfig.setLocale(locale) } else { - newConfig.locales = LocaleList(locale) + newConfig.setLocales(LocaleList(locale)) } return newConfig } diff --git a/build.gradle b/build.gradle index 2885a88fc1..f34faa7ebe 100644 --- a/build.gradle +++ b/build.gradle @@ -7,10 +7,10 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0' + classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.github.ben-manes:gradle-versions-plugin:0.22.0' classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2' - classpath 'com.google.gms:google-services:3.2.0' + classpath 'com.google.gms:google-services:4.3.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bccb59f891..56fac75514 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 25 08:47:56 CEST 2018 +#Sat Oct 26 14:20:49 PDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip From b94da6b3ed01933c7e820c5a0b9771d6b716238a Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 16:27:24 -0700 Subject: [PATCH 15/77] Insets for snackbar --- .../ui/catalogue/browse/BrowseCatalogueController.kt | 7 ++++++- .../eu/kanade/tachiyomi/ui/library/LibraryController.kt | 6 ++++-- .../tachiyomi/ui/manga/chapter/ChaptersController.kt | 6 +++++- .../main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt | 3 +++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 63e3125f48..9027b12433 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -210,7 +210,9 @@ open class BrowseCatalogueController(bundle: Bundle) : recycler.adapter = adapter catalogue_view.addView(recycler, 1) - + recycler.doOnApplyWindowInsets { v, insets, padding -> + v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom) + } if (oldPosition != RecyclerView.NO_POSITION) { recycler.layoutManager?.scrollToPosition(oldPosition) } @@ -367,6 +369,9 @@ open class BrowseCatalogueController(bundle: Bundle) : presenter.requestNext() } } + snack?.view?.doOnApplyWindowInsets { v, _, padding -> + v.setPadding(padding.left,0,padding.right,0) + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index a8bee9cdcc..96962297fe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -33,11 +33,13 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets +import eu.kanade.tachiyomi.ui.main.marginBottom import eu.kanade.tachiyomi.ui.main.updateLayoutParams import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.migration.MigrationController import eu.kanade.tachiyomi.util.inflate +import eu.kanade.tachiyomi.util.marginTop import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.chapters_controller.* import kotlinx.android.synthetic.main.library_controller.* @@ -200,8 +202,8 @@ class LibraryController( statusScrim.setOnApplyWindowInsetsListener(HeightTopWindowInsetsListener) view.doOnApplyWindowInsets { v, insets, padding -> view.recycler.updatePaddingRelative( - bottom = view.recycler.bottom + insets.systemWindowInsetBottom, - top = view.recycler.top + insets.systemWindowInsetTop + bottom = view.recycler.marginBottom + insets.systemWindowInsetBottom, + top = view.recycler.marginTop + insets.systemWindowInsetTop ) } return view diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index 334988a550..e5e054c38b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -381,11 +381,15 @@ class ChaptersController : NucleusController(), destroyActionModeIfNeeded() presenter.downloadChapters(chapters) if (view != null && !presenter.manga.favorite) { - recycler?.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) { + val snack = view.snack(view.context.getString(R.string.snack_add_to_library), Snackbar + .LENGTH_INDEFINITE) { setAction(R.string.action_add) { presenter.addToLibrary() } } + snack.view.doOnApplyWindowInsets { v, _, padding -> + v.setPadding(padding.left,0,padding.right,0) + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt index 5e3c94a57a..ed5027989c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -94,3 +94,6 @@ fun View.getRound(text: String, random : Boolean = true): TextDrawable { .endConfig() .buildRound(text, if (random) ColorGenerator.MATERIAL.randomColor else ColorGenerator.MATERIAL.getColor(text)) } + +inline val View.marginTop: Int + get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin ?: 0 From 8b69813f342885d9c4bc33b958d53baf524072f5 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 18:04:52 -0700 Subject: [PATCH 16/77] More stuff Cleartext (http sites) support Moved view extensions to view extensions Even more insets support --- app/src/main/AndroidManifest.xml | 3 +- .../browse/BrowseCatalogueController.kt | 18 +++- .../CatalogueSearchController.kt | 2 + .../ui/category/CategoryController.kt | 12 +++ .../ui/download/DownloadController.kt | 2 + .../ui/extension/ExtensionController.kt | 2 + .../ui/library/LibraryCategoryView.kt | 6 +- .../tachiyomi/ui/library/LibraryController.kt | 14 +-- .../kanade/tachiyomi/ui/main/MainActivity.kt | 84 +---------------- .../ui/manga/chapter/ChaptersController.kt | 10 +- .../ui/manga/info/MangaInfoController.kt | 8 +- .../ui/migration/MigrationController.kt | 2 + .../tachiyomi/ui/reader/ReaderActivity.kt | 3 - .../RecentChaptersController.kt | 2 + .../recently_read/RecentlyReadController.kt | 2 + .../ui/setting/SettingsController.kt | 7 +- .../kanade/tachiyomi/util/ViewExtensions.kt | 92 ++++++++++++++++++- .../main/res/layout/categories_controller.xml | 1 + .../main/res/layout/download_controller.xml | 1 + .../main/res/layout/extension_controller.xml | 1 + .../main/res/layout/migration_controller.xml | 3 +- .../res/layout/recent_chapters_controller.xml | 1 + .../main/res/xml/network_security_config.xml | 8 ++ 23 files changed, 157 insertions(+), 127 deletions(-) create mode 100644 app/src/main/res/xml/network_security_config.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9edb5c0c3c..ec34fc628b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,7 +22,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" android:largeHeap="true" - android:theme="@style/Theme.Tachiyomi"> + android:theme="@style/Theme.Tachiyomi" + android:networkSecurityConfig="@xml/network_security_config"> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 9027b12433..26ae3ea108 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -23,13 +23,12 @@ import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.HeightTopWindowInsetsListener -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.info.MangaWebViewController import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.widget.AutofitRecyclerView import kotlinx.android.synthetic.main.catalogue_controller.* +import kotlinx.android.synthetic.main.categories_item.view.* import kotlinx.android.synthetic.main.main_activity.* import rx.Observable import rx.Subscription @@ -155,13 +154,22 @@ open class BrowseCatalogueController(bundle: Bundle) : presenter.sourceFilters = newFilters navView.setFilters(presenter.filterItems) } + drawer.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + val statusScrim = navView.findViewById(R.id.status_bar_scrim) as View statusScrim.setOnApplyWindowInsetsListener(HeightTopWindowInsetsListener) + val titleView = navView.findViewById(R.id.title_background) as View + val titleMarginTop = titleView.marginTop navView.doOnApplyWindowInsets { v, insets, padding -> - navView.recycler.updatePaddingRelative( - bottom = padding.bottom + insets.systemWindowInsetBottom, - top = padding.top + insets.systemWindowInsetTop + v.updatePaddingRelative( + bottom = padding.bottom + insets.systemWindowInsetBottom, + end = padding.right + insets.systemWindowInsetRight ) + titleView.updateLayoutParams { + topMargin = titleMarginTop + insets.systemWindowInsetTop + } } return navView } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt index a3f7f4ca28..da76c4867c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.manga.MangaController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.catalogue_global_search_controller.* /** @@ -133,6 +134,7 @@ open class CatalogueSearchController( // Create recycler and set adapter. recycler.layoutManager = LinearLayoutManager(view.context) recycler.adapter = adapter + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt index c698c2d6e6..1eaff7f067 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt @@ -13,7 +13,11 @@ import eu.davidea.flexibleadapter.helpers.UndoHelper import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.ui.base.controller.NucleusController +import eu.kanade.tachiyomi.util.doOnApplyWindowInsets +import eu.kanade.tachiyomi.util.marginBottom import eu.kanade.tachiyomi.util.toast +import eu.kanade.tachiyomi.util.updateLayoutParams +import eu.kanade.tachiyomi.util.updatePaddingRelative import kotlinx.android.synthetic.main.categories_controller.* /** @@ -83,6 +87,14 @@ class CategoryController : NucleusController(), fab.clicks().subscribeUntilDestroy { CategoryCreateDialog(this@CategoryController).showDialog(router, null) } + + val fabBaseMarginBottom = fab?.marginBottom ?: 0 + recycler.doOnApplyWindowInsets { v, insets, padding -> + v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom) + fab?.updateLayoutParams { + bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom + } + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt index 9252374f11..9793b81830 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt @@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.base.controller.NucleusController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.download_controller.* import rx.Observable import rx.Subscription @@ -64,6 +65,7 @@ class DownloadController : NucleusController() { // Set the layout manager for the recycler and fixed size. recycler.layoutManager = LinearLayoutManager(view.context) recycler.setHasFixedSize(true) + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) // Suscribe to changes DownloadService.runningRelay diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt index 0079c6be00..b14edc78de 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.extension_controller.* @@ -58,6 +59,7 @@ open class ExtensionController : NucleusController(), ext_recycler.layoutManager = LinearLayoutManager(view.context) ext_recycler.adapter = adapter ext_recycler.addItemDecoration(ExtensionDividerItemDecoration(view.context)) + ext_recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index 691457c5db..f58f11e379 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -13,11 +13,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative -import eu.kanade.tachiyomi.util.inflate -import eu.kanade.tachiyomi.util.plusAssign -import eu.kanade.tachiyomi.util.toast +import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.widget.AutofitRecyclerView import kotlinx.android.synthetic.main.library_category.view.* import rx.subscriptions.CompositeSubscription diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 96962297fe..9d8624b523 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -32,16 +32,9 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.marginBottom -import eu.kanade.tachiyomi.ui.main.updateLayoutParams -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.migration.MigrationController -import eu.kanade.tachiyomi.util.inflate -import eu.kanade.tachiyomi.util.marginTop -import eu.kanade.tachiyomi.util.toast -import kotlinx.android.synthetic.main.chapters_controller.* +import eu.kanade.tachiyomi.util.* import kotlinx.android.synthetic.main.library_controller.* import kotlinx.android.synthetic.main.main_activity.* import rx.Subscription @@ -202,8 +195,9 @@ class LibraryController( statusScrim.setOnApplyWindowInsetsListener(HeightTopWindowInsetsListener) view.doOnApplyWindowInsets { v, insets, padding -> view.recycler.updatePaddingRelative( - bottom = view.recycler.marginBottom + insets.systemWindowInsetBottom, - top = view.recycler.marginTop + insets.systemWindowInsetTop + bottom = view.recycler.marginBottom + insets.systemWindowInsetBottom, + top = view.recycler.marginTop + insets.systemWindowInsetTop, + end = view.recycler.marginRight + insets.systemWindowInsetRight ) } return view diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 5f345e1fc8..bb4da456a2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -36,7 +36,10 @@ import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController import eu.kanade.tachiyomi.ui.setting.SettingsMainController +import eu.kanade.tachiyomi.util.NoopWindowInsetsListener +import eu.kanade.tachiyomi.util.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.openInBrowser +import eu.kanade.tachiyomi.util.updatePaddingRelative import kotlinx.android.synthetic.main.main_activity.* import uy.kohesive.injekt.injectLazy @@ -320,84 +323,3 @@ class MainActivity : BaseActivity() { } } - -object NoopWindowInsetsListener : View.OnApplyWindowInsetsListener { - override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { - v.setPadding(insets.systemWindowInsetLeft,insets.systemWindowInsetTop,insets.systemWindowInsetRight,0) - //insets.consumeSystemWindowInsets() - return insets - } -} - -object NoopWindowInsetsListener2 : View.OnApplyWindowInsetsListener { - override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { - v.setPadding(0,0,0,insets - .systemWindowInsetBottom) - insets.consumeSystemWindowInsets() - return insets - } -} - -fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) { - // Create a snapshot of the view's padding state - val paddingState = createStateForView(this) - setOnApplyWindowInsetsListener { v, insets -> - f(v, insets, paddingState) - insets - } - requestApplyInsetsWhenAttached() -} - -fun View.requestApplyInsetsWhenAttached() { - if (isAttachedToWindow) { - requestApplyInsets() - } else { - addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { - override fun onViewAttachedToWindow(v: View) { - v.requestApplyInsets() - } - - override fun onViewDetachedFromWindow(v: View) = Unit - }) - } -} - -inline fun View.updateLayoutParams(block: T.() -> Unit) { - val params = layoutParams as T - block(params) - layoutParams = params -} - -inline val View.marginBottom: Int - get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin ?: 0 - -inline fun View.updatePadding( - @Px left: Int = paddingLeft, - @Px top: Int = paddingTop, - @Px right: Int = paddingRight, - @Px bottom: Int = paddingBottom -) { - setPadding(left, top, right, bottom) -} - -private fun createStateForView(view: View) = ViewPaddingState(view.paddingLeft, - view.paddingTop, view.paddingRight, view.paddingBottom, view.paddingStart, view.paddingEnd) - -data class ViewPaddingState( - val left: Int, - val top: Int, - val right: Int, - val bottom: Int, - val start: Int, - val end: Int -) - -@RequiresApi(17) -inline fun View.updatePaddingRelative( - @Px start: Int = paddingStart, - @Px top: Int = paddingTop, - @Px end: Int = paddingEnd, - @Px bottom: Int = paddingBottom -) { - setPaddingRelative(start, top, end, bottom) -} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index e5e054c38b..3c1701e6de 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -21,17 +21,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag -import eu.kanade.tachiyomi.ui.main.NoopWindowInsetsListener2 -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.marginBottom -import eu.kanade.tachiyomi.ui.main.updateLayoutParams -import eu.kanade.tachiyomi.ui.main.updatePadding -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderActivity -import eu.kanade.tachiyomi.util.getCoordinates -import eu.kanade.tachiyomi.util.snack -import eu.kanade.tachiyomi.util.toast +import eu.kanade.tachiyomi.util.* import kotlinx.android.synthetic.main.chapters_controller.* import timber.log.Timber diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index 6e018e3d23..02d44b6a4a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -40,14 +40,8 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.manga.MangaController -import eu.kanade.tachiyomi.util.getResourceColor -import eu.kanade.tachiyomi.util.openInBrowser -import eu.kanade.tachiyomi.util.snack -import eu.kanade.tachiyomi.util.toast -import eu.kanade.tachiyomi.util.truncateCenter +import eu.kanade.tachiyomi.util.* import jp.wasabeef.glide.transformations.CropSquareTransformation import jp.wasabeef.glide.transformations.MaskTransformation import kotlinx.android.synthetic.main.manga_info_controller.* diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt index a72bcc8e5a..f670001bdf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.migration_controller.* class MigrationController : NucleusController(), @@ -43,6 +44,7 @@ class MigrationController : NucleusController(), adapter = FlexibleAdapter(null, this) migration_recycler.layoutManager = LinearLayoutManager(view.context) migration_recycler.adapter = adapter + migration_recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 1547b863fd..b21cc4ccec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -21,9 +21,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.updateLayoutParams -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt index 1b0fef7dbd..4333da5c27 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt @@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.recent_chapters_controller.* import timber.log.Timber @@ -90,6 +91,7 @@ class RecentChaptersController : NucleusController(), // It can be a very long operation, so we disable swipe refresh and show a toast. swipe_refresh.isRefreshing = false } + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt index c094c39fc0..cddd8eda1c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.recently_read_controller.* @@ -58,6 +59,7 @@ class RecentlyReadController : NucleusController(), adapter = RecentlyReadAdapter(this@RecentlyReadController) recycler.setHasFixedSize(true) recycler.adapter = adapter + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsController.kt index 21af01ca55..b4dabd1972 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsController.kt @@ -15,6 +15,9 @@ import com.bluelinelabs.conductor.ControllerChangeType import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.base.controller.BaseController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener +import eu.kanade.tachiyomi.util.doOnApplyWindowInsets +import eu.kanade.tachiyomi.util.updatePaddingRelative import rx.Observable import rx.Subscription import rx.subscriptions.CompositeSubscription @@ -32,7 +35,9 @@ abstract class SettingsController : PreferenceController() { if (untilDestroySubscriptions.isUnsubscribed) { untilDestroySubscriptions = CompositeSubscription() } - return super.onCreateView(inflater, container, savedInstanceState) + val view = super.onCreateView(inflater, container, savedInstanceState) + listView.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) + return view } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt index ed5027989c..c8dd10466d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -7,6 +7,8 @@ import android.graphics.Color import android.graphics.Point import android.graphics.Typeface import android.os.Build +import android.support.annotation.Px +import android.support.annotation.RequiresApi import android.support.design.widget.Snackbar import android.support.v4.view.ViewCompat import android.support.v4.view.WindowInsetsCompat @@ -18,10 +20,6 @@ import android.widget.TextView import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.util.ColorGenerator import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.ui.main.doOnApplyWindowInsets -import eu.kanade.tachiyomi.ui.main.marginBottom -import eu.kanade.tachiyomi.ui.main.updateLayoutParams -import eu.kanade.tachiyomi.ui.main.updatePaddingRelative /** * Returns coordinates of view. @@ -97,3 +95,89 @@ fun View.getRound(text: String, random : Boolean = true): TextDrawable { inline val View.marginTop: Int get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin ?: 0 + +inline val View.marginBottom: Int + get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin ?: 0 + +inline val View.marginRight: Int + get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.rightMargin ?: 0 + +inline val View.marginLeft: Int + get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.leftMargin ?: 0 + +object NoopWindowInsetsListener : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + v.setPadding(insets.systemWindowInsetLeft,insets.systemWindowInsetTop,insets.systemWindowInsetRight,0) + //insets.consumeSystemWindowInsets() + return insets + } +} + +object RecyclerWindowInsetsListener : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + v.setPadding(0,0,0,insets.systemWindowInsetBottom) + //v.updatePaddingRelative(bottom = v.paddingBottom + insets.systemWindowInsetBottom) + return insets + } +} + +fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) { + // Create a snapshot of the view's padding state + val paddingState = createStateForView(this) + setOnApplyWindowInsetsListener { v, insets -> + f(v, insets, paddingState) + insets + } + requestApplyInsetsWhenAttached() +} + +fun View.requestApplyInsetsWhenAttached() { + if (isAttachedToWindow) { + requestApplyInsets() + } else { + addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { + override fun onViewAttachedToWindow(v: View) { + v.requestApplyInsets() + } + + override fun onViewDetachedFromWindow(v: View) = Unit + }) + } +} + +inline fun View.updateLayoutParams(block: T.() -> Unit) { + val params = layoutParams as T + block(params) + layoutParams = params +} + +inline fun View.updatePadding( + @Px left: Int = paddingLeft, + @Px top: Int = paddingTop, + @Px right: Int = paddingRight, + @Px bottom: Int = paddingBottom +) { + setPadding(left, top, right, bottom) +} + +private fun createStateForView(view: View) = ViewPaddingState(view.paddingLeft, + view.paddingTop, view.paddingRight, view.paddingBottom, view.paddingStart, view.paddingEnd) + +data class ViewPaddingState( + val left: Int, + val top: Int, + val right: Int, + val bottom: Int, + val start: Int, + val end: Int +) + +@RequiresApi(17) +inline fun View.updatePaddingRelative( + @Px start: Int = paddingStart, + @Px top: Int = paddingTop, + @Px end: Int = paddingEnd, + @Px bottom: Int = paddingBottom +) { + setPaddingRelative(start, top, end, bottom) +} \ No newline at end of file diff --git a/app/src/main/res/layout/categories_controller.xml b/app/src/main/res/layout/categories_controller.xml index 9bc79a6c39..cc8017ed35 100644 --- a/app/src/main/res/layout/categories_controller.xml +++ b/app/src/main/res/layout/categories_controller.xml @@ -10,6 +10,7 @@ android:layout_height="match_parent" android:id="@+id/recycler" android:choiceMode="multipleChoice" + android:clipToPadding="false" tools:listitem="@layout/categories_item" /> diff --git a/app/src/main/res/layout/download_controller.xml b/app/src/main/res/layout/download_controller.xml index 8b353b1fe6..c8fe6ffb22 100644 --- a/app/src/main/res/layout/download_controller.xml +++ b/app/src/main/res/layout/download_controller.xml @@ -10,6 +10,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/recycler" + android:clipToPadding="false" tools:listitem="@layout/download_item"/> \ No newline at end of file diff --git a/app/src/main/res/layout/migration_controller.xml b/app/src/main/res/layout/migration_controller.xml index 643832cd0a..d3caebbca4 100644 --- a/app/src/main/res/layout/migration_controller.xml +++ b/app/src/main/res/layout/migration_controller.xml @@ -3,4 +3,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/migration_recycler" android:layout_width="match_parent" - android:layout_height="match_parent"/> + android:layout_height="match_parent" + android:clipToPadding="false"/> diff --git a/app/src/main/res/layout/recent_chapters_controller.xml b/app/src/main/res/layout/recent_chapters_controller.xml index 6dcca143ed..8b420b6448 100644 --- a/app/src/main/res/layout/recent_chapters_controller.xml +++ b/app/src/main/res/layout/recent_chapters_controller.xml @@ -15,6 +15,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" + android:clipToPadding="false" tools:listitem="@layout/recent_chapters_item"/> + + + + + + + \ No newline at end of file From dd25736fb9572b4775032f6665f4d29d773fc467 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 18:26:31 -0700 Subject: [PATCH 17/77] Added Notch support + removed force dark where needed Co-Authored-By: tonarii --- .../ui/reader/viewer/pager/PagerPageHolder.kt | 1 + .../main/res/layout/reader_settings_sheet.xml | 3 ++- .../main/res/values-notnight-v29/themes.xml | 2 -- app/src/main/res/values-v27/styles.xml | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) delete mode 100644 app/src/main/res/values-notnight-v29/themes.xml create mode 100644 app/src/main/res/values-v27/styles.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 892126fb31..4d1559167c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -347,6 +347,7 @@ class PagerPageHolder( }) } addView(subsamplingImageView) + subsamplingImageView?.isForceDarkAllowed = false return subsamplingImageView!! } diff --git a/app/src/main/res/layout/reader_settings_sheet.xml b/app/src/main/res/layout/reader_settings_sheet.xml index d28155d704..73933fff36 100644 --- a/app/src/main/res/layout/reader_settings_sheet.xml +++ b/app/src/main/res/layout/reader_settings_sheet.xml @@ -8,7 +8,8 @@ android:background="?android:colorBackground" android:clipToPadding="false" android:orientation="vertical" - android:padding="@dimen/material_component_dialogs_padding_around_content_area"> + android:padding="@dimen/material_component_dialogs_padding_around_content_area" + android:forceDarkAllowed="false"> diff --git a/app/src/main/res/values-notnight-v29/themes.xml b/app/src/main/res/values-notnight-v29/themes.xml deleted file mode 100644 index a6b3daec93..0000000000 --- a/app/src/main/res/values-notnight-v29/themes.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-v27/styles.xml b/app/src/main/res/values-v27/styles.xml new file mode 100644 index 0000000000..734630a9ad --- /dev/null +++ b/app/src/main/res/values-v27/styles.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file From 1f6230c5a3388ef470d35e6b31846896a7259532 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 26 Oct 2019 21:42:49 -0700 Subject: [PATCH 18/77] Fixes for older versions of android --- .../tachiyomi/ui/reader/ReaderActivity.kt | 5 +++-- .../ui/reader/ReaderSettingsSheet.kt | 8 +++++-- .../ui/reader/viewer/pager/PagerPageHolder.kt | 4 +++- app/src/main/res/values-night/colors.xml | 6 ++++++ app/src/main/res/values-night/themes.xml | 8 +++---- app/src/main/res/values-v21/themes.xml | 21 +------------------ app/src/main/res/values-v27/styles.xml | 4 ++-- app/src/main/res/values-v29/themes.xml | 15 ------------- app/src/main/res/values/colors.xml | 3 +++ app/src/main/res/values/styles.xml | 9 ++++---- app/src/main/res/values/themes.xml | 8 +++---- 11 files changed, 36 insertions(+), 55 deletions(-) create mode 100644 app/src/main/res/values-night/colors.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index b21cc4ccec..e2a61a623d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -139,8 +139,9 @@ class ReaderActivity : BaseRxActivity() { val container: ViewGroup = findViewById(R.id.reader_container) val readerBHeight = reader_menu_bottom.layoutParams.height container.doOnApplyWindowInsets { _, insets, padding -> - val bottomInset = insets.mandatorySystemGestureInsets.bottom - insets - .systemWindowInsetBottom + val bottomInset = if (Build.VERSION.SDK_INT >= 29) + (insets.mandatorySystemGestureInsets.bottom - insets.systemWindowInsetBottom) + else 0 reader_menu_bottom.updateLayoutParams { height = readerBHeight + bottomInset } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt index b798f3b49b..58810a3f0a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt @@ -58,7 +58,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia viewer.setSelection(activity.presenter.manga?.viewer ?: 0, false) rotation_mode.bindToPreference(preferences.rotation(), 1) - background_color.bindToPreference(preferences.readerTheme()) + background_color.bindToPreference(preferences.readerTheme(), 0, true) show_page_number.bindToPreference(preferences.showPageNumber()) fullscreen.bindToPreference(preferences.fullscreen()) keepscreen.bindToPreference(preferences.keepScreenOn()) @@ -95,9 +95,13 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia /** * Binds a spinner to an int preference with an optional offset for the value. */ - private fun Spinner.bindToPreference(pref: Preference, offset: Int = 0) { + private fun Spinner.bindToPreference(pref: Preference, offset: Int = 0, shouldDismiss: + Boolean + = false) { onItemSelectedListener = IgnoreFirstSpinnerListener { position -> pref.set(position + offset) + if (shouldDismiss) + dismiss() } setSelection(pref.getOrDefault() - offset, false) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 4d1559167c..1191453a76 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -6,6 +6,7 @@ import android.graphics.BitmapFactory import android.graphics.PointF import android.graphics.drawable.Drawable import android.net.Uri +import android.os.Build import android.view.GestureDetector import android.view.Gravity import android.view.MotionEvent @@ -347,7 +348,8 @@ class PagerPageHolder( }) } addView(subsamplingImageView) - subsamplingImageView?.isForceDarkAllowed = false + if (Build.VERSION.SDK_INT >= 29) + subsamplingImageView?.isForceDarkAllowed = false return subsamplingImageView!! } diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000000..d55305f50a --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,6 @@ + + + @color/md_grey_800 + @color/colorAccentDark + #B3000000 + \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index a34d096b05..1071a9864f 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -25,7 +25,7 @@ - @style/Theme.Widget.NavigationView.Dark + @style/Theme.Widget.NavigationView @drawable/list_item_selector_dark @drawable/library_item_selector_dark @color/textColorPrimaryDark @@ -33,13 +33,13 @@ @color/iconColorDark - - @@ -47,7 +47,7 @@ - - - - - - - - diff --git a/app/src/main/res/values-v27/styles.xml b/app/src/main/res/values-v27/styles.xml index 734630a9ad..4c335fdaad 100644 --- a/app/src/main/res/values-v27/styles.xml +++ b/app/src/main/res/values-v27/styles.xml @@ -1,6 +1,6 @@ - + --> \ No newline at end of file diff --git a/app/src/main/res/values-v29/themes.xml b/app/src/main/res/values-v29/themes.xml index 54e5d44548..3cd718a156 100644 --- a/app/src/main/res/values-v29/themes.xml +++ b/app/src/main/res/values-v29/themes.xml @@ -6,19 +6,4 @@ @android:color/transparent @android:color/transparent - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9ff1db179d..617870a145 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,6 +3,8 @@ #54759E #54759E + @color/md_black_1000_12 + @color/colorPrimary #212121 #212121 @@ -15,6 +17,7 @@ @color/md_black_1000_38 @color/md_black_1000_12 @color/md_black_1000_12 + #B3FFFFFF @color/colorAccentLight diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 585e0e7ddf..6d29eb4692 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -35,13 +35,12 @@ - + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index bea8fc13d6..d4f136e705 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -32,6 +32,7 @@ + @style/Theme.Widget.NavigationView @drawable/list_item_selector_light @drawable/library_item_selector_light @color/textColorPrimaryLight @@ -39,10 +40,9 @@ @color/iconColorLight - - + - diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml deleted file mode 100644 index c49d72e6d8..0000000000 --- a/app/src/main/res/values-v21/themes.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values-v29/themes.xml b/app/src/main/res/values-v29/themes.xml index 3cd718a156..056509289b 100644 --- a/app/src/main/res/values-v29/themes.xml +++ b/app/src/main/res/values-v29/themes.xml @@ -1,8 +1,8 @@ + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index d4f136e705..d08a8b1de2 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -6,10 +6,9 @@ + + - From 2ec46a70981f2f5b8e7147843a1dae99ebe43444 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 27 Oct 2019 20:23:15 -0700 Subject: [PATCH 26/77] Insets for webview and tracking tab With this all controllers insets should be handled --- .../ui/manga/info/MangaWebViewController.kt | 13 +++++++++++++ .../tachiyomi/ui/manga/track/TrackController.kt | 2 ++ 2 files changed, 15 insertions(+) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt index 8d7d9687a0..5cef0d4677 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.manga.info +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -9,7 +10,11 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.controller.BaseController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.WebViewClientCompat +import eu.kanade.tachiyomi.util.doOnApplyWindowInsets +import eu.kanade.tachiyomi.util.marginBottom +import eu.kanade.tachiyomi.util.updateLayoutParams import uy.kohesive.injekt.injectLazy class MangaWebViewController(bundle: Bundle? = null) : BaseController(bundle) { @@ -38,6 +43,14 @@ class MangaWebViewController(bundle: Bundle? = null) : BaseController(bundle) { return true } } + val marginB = view.marginBottom + view.doOnApplyWindowInsets{ v, insets, _ -> + val bottomInset = if (Build.VERSION.SDK_INT >= 29) insets.tappableElementInsets.bottom + else insets.systemWindowInsetBottom + v.updateLayoutParams { + bottomMargin = marginB + bottomInset + } + } web.settings.javaScriptEnabled = true web.settings.userAgentString = source.headers["User-Agent"] web.loadUrl(url, headers) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt index 0acf3381d0..cff67f9c17 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.manga.MangaController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.track_controller.* import timber.log.Timber @@ -44,6 +45,7 @@ class TrackController : NucleusController(), with(view) { track_recycler.layoutManager = LinearLayoutManager(context) track_recycler.adapter = adapter + track_recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) swipe_refresh.isEnabled = false swipe_refresh.refreshes().subscribeUntilDestroy { presenter.refresh() } } From 1d7d40ba8ca17b8a08d96701976c11d4a72c7a26 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 27 Oct 2019 22:46:26 -0700 Subject: [PATCH 27/77] Cleanup + fixes to preference category --- .../extension/util/ExtensionInstallReceiver.kt | 5 ----- .../tachiyomi/ui/reader/PageIndicatorTextView.kt | 10 ---------- .../eu/kanade/tachiyomi/ui/setting/PreferenceDSL.kt | 4 +++- .../main/res/values-sw360dp-v13/values-preference.xml | 6 ++++++ 4 files changed, 9 insertions(+), 16 deletions(-) create mode 100644 app/src/main/res/values-sw360dp-v13/values-preference.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallReceiver.kt index d94768dd43..f1d50ce4c3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallReceiver.kt @@ -7,7 +7,6 @@ import android.content.IntentFilter import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.LoadResult import eu.kanade.tachiyomi.util.launchNow -import kotlinx.coroutines.async /** * Broadcast receiver that listens for the system's packages installed, updated or removed, and only @@ -91,10 +90,6 @@ internal class ExtensionInstallReceiver(private val listener: Listener) : private suspend fun getExtensionFromIntent(context: Context, intent: Intent?): LoadResult { val pkgName = getPackageNameFromIntent(intent) ?: return LoadResult.Error("Package name not found") - /*var result:LoadResult = LoadResult.Error("") - launchNow { - result = async { ExtensionLoader.loadExtensionFromPkgName(context, pkgName) }.await() - }*/ return ExtensionLoader.loadExtensionFromPkgName(context, pkgName) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt index 028ec48488..600ed691de 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt @@ -25,13 +25,11 @@ class PageIndicatorTextView( override fun onDraw(canvas: Canvas) { setTextColor(strokeColor) - //textColorField.set(this, strokeColor) paint.strokeWidth = 4f paint.style = Paint.Style.STROKE super.onDraw(canvas) setTextColor(fillColor) - //textColorField.set(this, fillColor) paint.strokeWidth = 0f paint.style = Paint.Style.FILL super.onDraw(canvas) @@ -52,12 +50,4 @@ class PageIndicatorTextView( super.setText(finalText, TextView.BufferType.SPANNABLE) } - - private companion object { - // We need to use reflection to set the text color instead of using [setTextColor], - // otherwise the view is invalidated inside [onDraw] and there's an infinite loop - /* val textColorField = TextView::class.java.getDeclaredField("mCurTextColor").apply { - isAccessible = true - }!!*/ - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/PreferenceDSL.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/PreferenceDSL.kt index 6fc05d1af7..5d74a00f76 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/PreferenceDSL.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/PreferenceDSL.kt @@ -42,7 +42,9 @@ inline fun PreferenceGroup.multiSelectListPreference(block: (@DSL MultiSelectLis } inline fun PreferenceScreen.preferenceCategory(block: (@DSL PreferenceCategory).() -> Unit): PreferenceCategory { - return addThenInit(PreferenceCategory(context), block) + return addThenInit(PreferenceCategory(context).apply { + isIconSpaceReserved = false + }, block) } inline fun PreferenceScreen.preferenceScreen(block: (@DSL PreferenceScreen).() -> Unit): PreferenceScreen { diff --git a/app/src/main/res/values-sw360dp-v13/values-preference.xml b/app/src/main/res/values-sw360dp-v13/values-preference.xml new file mode 100644 index 0000000000..8ed48ca096 --- /dev/null +++ b/app/src/main/res/values-sw360dp-v13/values-preference.xml @@ -0,0 +1,6 @@ + + + + false + 0dp + \ No newline at end of file From fee8ccab863e56781017d83801fc937b72976dca Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 27 Oct 2019 23:20:17 -0700 Subject: [PATCH 28/77] Theme fixes And one more inset fix for catalogue --- .../eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt | 2 ++ .../ui/catalogue/browse/BrowseCatalogueController.kt | 4 +--- app/src/main/res/drawable-v21/list_item_selector_dark.xml | 2 +- app/src/main/res/drawable/list_item_selector_dark.xml | 2 +- app/src/main/res/layout/catalogue_main_controller.xml | 1 + app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values-night/themes.xml | 2 +- app/src/main/res/values/colors.xml | 5 +++-- app/src/main/res/values/themes.xml | 2 +- 9 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt index ceed07a35d..dd8c3b1cec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt @@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController import eu.kanade.tachiyomi.ui.catalogue.latest.LatestUpdatesController import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog import kotlinx.android.synthetic.main.catalogue_main_controller.* import uy.kohesive.injekt.Injekt @@ -101,6 +102,7 @@ class CatalogueController : NucleusController(), recycler.layoutManager = LinearLayoutManager(view.context) recycler.adapter = adapter recycler.addItemDecoration(SourceDividerItemDecoration(view.context)) + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 26ae3ea108..53d36cb70a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -218,9 +218,7 @@ open class BrowseCatalogueController(bundle: Bundle) : recycler.adapter = adapter catalogue_view.addView(recycler, 1) - recycler.doOnApplyWindowInsets { v, insets, padding -> - v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom) - } + recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) if (oldPosition != RecyclerView.NO_POSITION) { recycler.layoutManager?.scrollToPosition(oldPosition) } diff --git a/app/src/main/res/drawable-v21/list_item_selector_dark.xml b/app/src/main/res/drawable-v21/list_item_selector_dark.xml index 07b9ef6d5b..c86632f6a9 100644 --- a/app/src/main/res/drawable-v21/list_item_selector_dark.xml +++ b/app/src/main/res/drawable-v21/list_item_selector_dark.xml @@ -12,7 +12,7 @@ - + diff --git a/app/src/main/res/drawable/list_item_selector_dark.xml b/app/src/main/res/drawable/list_item_selector_dark.xml index 60034f8183..c3a6245050 100644 --- a/app/src/main/res/drawable/list_item_selector_dark.xml +++ b/app/src/main/res/drawable/list_item_selector_dark.xml @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/catalogue_main_controller.xml b/app/src/main/res/layout/catalogue_main_controller.xml index 84efdf4714..df9085a1d7 100644 --- a/app/src/main/res/layout/catalogue_main_controller.xml +++ b/app/src/main/res/layout/catalogue_main_controller.xml @@ -9,6 +9,7 @@ android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="wrap_content" + android:clipToPadding="false" tools:listitem="@layout/catalogue_main_controller_card" /> \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index ae400a70c1..e08f4af761 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -3,4 +3,5 @@ @color/md_white_1000_12 @color/colorAccentDark #B3000000 + @color/colorDarkPrimary \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 7058ebd081..26d7308b7d 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -29,7 +29,7 @@ @drawable/list_item_selector_dark @drawable/library_item_selector_dark @color/textColorPrimaryDark - @color/dialogDark + @color/cardBackground @color/iconColorDark diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 617870a145..c1f38c8fb6 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,6 +5,7 @@ #54759E @color/md_black_1000_12 @color/colorPrimary + #FFFFFF #212121 #212121 @@ -39,8 +40,8 @@ @color/md_black_1000 @color/md_grey_900 - @color/colorDarkPrimaryDark - @color/colorDarkPrimary + #1C1C1D + @color/md_grey_800 @color/colorDarkPrimaryDark @color/md_blue_A200_50 diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index d08a8b1de2..ea957bbbc1 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -36,7 +36,7 @@ @drawable/list_item_selector_light @drawable/library_item_selector_light @color/textColorPrimaryLight - @color/dialogLight + @color/cardBackground @color/iconColorLight @android:color/transparent From 197b5cf6a463aa9eccfc0923d7b9073a1f3eb791 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 28 Oct 2019 02:27:01 -0700 Subject: [PATCH 29/77] Still more insets work Fixed insets for landscape manga info controller + using snackbars for adding and removing mangas --- .../data/updater/github/GithubService.kt | 2 +- .../browse/BrowseCatalogueController.kt | 3 - .../ui/manga/chapter/ChaptersController.kt | 3 - .../ui/manga/info/MangaInfoController.kt | 76 ++++++++++++++----- .../ui/setting/SettingsAboutController.kt | 2 +- .../kanade/tachiyomi/util/ViewExtensions.kt | 11 ++- .../res/layout-land/manga_info_controller.xml | 40 ++++++---- .../main/res/layout/manga_info_controller.xml | 13 ++-- app/src/main/res/values/styles.xml | 9 +++ 9 files changed, 108 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt index e19e3528d5..b32a9ff8e6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt @@ -27,7 +27,7 @@ interface GithubService { } } - @GET("/repos/inorichi/tachiyomi/releases/latest") + @GET("/repos/Jays2Kings/tachiyomi/releases/latest") fun getLatestVersion(): Observable } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 53d36cb70a..3ccd7b044d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -375,9 +375,6 @@ open class BrowseCatalogueController(bundle: Bundle) : presenter.requestNext() } } - snack?.view?.doOnApplyWindowInsets { v, _, padding -> - v.setPadding(padding.left,0,padding.right,0) - } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index 3c1701e6de..caf00088c0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -379,9 +379,6 @@ class ChaptersController : NucleusController(), presenter.addToLibrary() } } - snack.view.doOnApplyWindowInsets { v, _, padding -> - v.setPadding(padding.left,0,padding.right,0) - } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index 02d44b6a4a..1f5be44e5d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -6,12 +6,12 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.content.Intent +import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.drawable.Drawable -import android.net.Uri import android.os.Build import android.os.Bundle -import android.support.customtabs.CustomTabsIntent +import android.support.design.widget.Snackbar import android.support.v4.content.pm.ShortcutInfoCompat import android.support.v4.content.pm.ShortcutManagerCompat import android.support.v4.graphics.drawable.IconCompat @@ -49,6 +49,7 @@ import uy.kohesive.injekt.injectLazy import java.text.DateFormat import java.text.DecimalFormat import java.util.Date +import kotlin.math.max /** * Fragment that shows manga information. @@ -63,6 +64,13 @@ class MangaInfoController : NucleusController(), */ private val preferences: PreferencesHelper by injectLazy() + /** + * Snackbar containing an error message when a request fails. + */ + private var snack: Snackbar? = null + + private var container:View? = null + init { setHasOptionsMenu(true) setOptionsMenuHidden(true) @@ -85,7 +93,7 @@ class MangaInfoController : NucleusController(), fab_favorite.clicks().subscribeUntilDestroy { onFabClick() } // Set onLongClickListener to manage categories when FAB is clicked. - fab_favorite.longClicks().subscribeUntilDestroy{ onFabLongClick() } + fab_favorite.longClicks().subscribeUntilDestroy { onFabLongClick() } // Set SwipeRefresh to refresh manga data. swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() } @@ -123,10 +131,24 @@ class MangaInfoController : NucleusController(), manga_cover.longClicks().subscribeUntilDestroy { copyToClipboard(view.context.getString(R.string.title), presenter.manga.title) } - - view.doOnApplyWindowInsets { v, insets, padding -> + container = (view as ViewGroup).findViewById(R.id.manga_info_layout) as? View + val bottomM = manga_genres_tags.marginBottom + val fabBaseMarginBottom = fab_favorite.marginBottom + container?.doOnApplyWindowInsets { v, insets, padding -> + if (resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) { + fab_favorite?.updateLayoutParams { + bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom + } + } + else { + manga_genres_tags?.updateLayoutParams { + bottomMargin = bottomM + +insets.systemWindowInsetBottom + } + } + } + info_scrollview.doOnApplyWindowInsets { v, insets, padding -> v.updatePaddingRelative( - bottom = padding.bottom + insets.systemWindowInsetBottom + bottom = max(padding.bottom, insets.systemWindowInsetBottom) ) } } @@ -245,6 +267,7 @@ class MangaInfoController : NucleusController(), override fun onDestroyView(view: View) { manga_genres_tags.setOnTagClickListener(null) + snack?.dismiss() super.onDestroyView(view) } @@ -273,16 +296,7 @@ class MangaInfoController : NucleusController(), * Toggles the favorite status and asks for confirmation to delete downloaded chapters. */ private fun toggleFavorite() { - val view = view - - val isNowFavorite = presenter.toggleFavorite() - if (view != null && !isNowFavorite && presenter.hasDownloads()) { - view.snack(view.context.getString(R.string.delete_downloads_for_manga)) { - setAction(R.string.action_delete) { - presenter.deleteDownloads() - } - } - } + presenter.toggleFavorite() } /** @@ -398,9 +412,33 @@ class MangaInfoController : NucleusController(), .showDialog(router) } } - activity?.toast(activity?.getString(R.string.manga_added_library)) + showAddedSnack() } else { - activity?.toast(activity?.getString(R.string.manga_removed_library)) + showRemovedSnack() + } + } + + private fun showAddedSnack() { + val view = container + snack?.dismiss() + snack = view?.snack(view.context.getString(R.string.manga_added_library), Snackbar + .LENGTH_SHORT) + } + + private fun showRemovedSnack() { + val view = container + val hasDownloads = presenter.hasDownloads() + snack?.dismiss() + if (view != null) { + val message = view.context.getString(R.string.manga_removed_library) + + (if (hasDownloads) "\n" + view.context.getString(R.string + .delete_downloads_for_manga) else "") + snack = view.snack(message, (if (hasDownloads) Snackbar.LENGTH_INDEFINITE + else Snackbar.LENGTH_SHORT)) { + if (hasDownloads) setAction(R.string.action_delete) { + presenter.deleteDownloads() + } + } } } @@ -411,7 +449,7 @@ class MangaInfoController : NucleusController(), val manga = presenter.manga if (!manga.favorite) { toggleFavorite() - activity?.toast(activity?.getString(R.string.manga_added_library)) + showAddedSnack() } val categories = presenter.getCategories() if (categories.size <= 1) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt index b6ff16dcae..dced1cd006 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt @@ -80,7 +80,7 @@ class SettingsAboutController : SettingsController() { } preference { title = "Github" - val url = "https://github.com/inorichi/tachiyomi" + val url = "https://github.com/Jays2Kings/tachiyomi" summary = url onClick { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt index c8dd10466d..48d8bc3226 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -36,7 +36,8 @@ fun View.getCoordinates() = Point((left + right) / 2, (top + bottom) / 2) * @param length the duration of the snack. * @param f a function to execute in the snack, allowing for example to define a custom action. */ -inline fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: Snackbar.() -> Unit): Snackbar { +fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: (Snackbar.() -> +Unit)? = null): Snackbar { val snack = Snackbar.make(this, message, length) val textView: TextView = snack.view.findViewById(android.support.design.R.id.snackbar_text) textView.setTextColor(Color.WHITE) @@ -44,7 +45,12 @@ inline fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: Sn Build.VERSION.SDK_INT >= 23 -> snack.config(context, rootWindowInsets.systemWindowInsetBottom) else -> snack.config(context) } - snack.f() + if (f != null) { + snack.f() + } + snack.view.doOnApplyWindowInsets { v, _, padding -> + v.setPadding(padding.left,0,padding.right,0) + } snack.show() return snack } @@ -53,7 +59,6 @@ fun Snackbar.config(context: Context, bottomMargin: Int = 0) { val params = this.view.layoutParams as ViewGroup.MarginLayoutParams params.setMargins(12, 12, 12, 12 + bottomMargin) this.view.layoutParams = params - this.view.background = context.getDrawable(R.drawable.bg_snackbar) ViewCompat.setElevation(this.view, 6f) diff --git a/app/src/main/res/layout-land/manga_info_controller.xml b/app/src/main/res/layout-land/manga_info_controller.xml index bba645590f..0d0d778109 100644 --- a/app/src/main/res/layout-land/manga_info_controller.xml +++ b/app/src/main/res/layout-land/manga_info_controller.xml @@ -8,12 +8,25 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:orientation="vertical" + android:id="@+id/manga_info_layout"> + + + + - - + android:layout_marginEnd="16dp" + android:clipToPadding="false"> + diff --git a/app/src/main/res/layout/manga_info_controller.xml b/app/src/main/res/layout/manga_info_controller.xml index fe78d31821..8b70b06159 100644 --- a/app/src/main/res/layout/manga_info_controller.xml +++ b/app/src/main/res/layout/manga_info_controller.xml @@ -7,13 +7,15 @@ android:id="@id/swipe_refresh" android:layout_width="match_parent" android:layout_height="match_parent"> - - + android:orientation="vertical" + android:id="@+id/manga_info_layout"> + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 6d29eb4692..50e68de444 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -146,6 +146,15 @@ eu.kanade.tachiyomi.widget.FABAnimationUpDown + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 26d7308b7d..164e7300b9 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -31,6 +31,7 @@ @color/textColorPrimaryDark @color/cardBackground @color/iconColorDark + @color/oldNavBarBackground + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index ea957bbbc1..a57d6a680b 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -40,7 +40,7 @@ @color/iconColorLight @android:color/transparent - @color/oldNavBarBackground + @color/colorPrimary --> + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2d22ad2ebd..d8ab319da5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,7 +50,7 @@ Remove bookmark Delete Update - Update library + Updating library Edit Add Add category From d263f03cc7bd7691d7f7d1f21694bb775fc895f1 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 2 Nov 2019 21:43:15 -0700 Subject: [PATCH 42/77] Reader seekbar back to ignoring gestures Sharesheet update: Now shows a preview of images shared, a preview of the manga you're sharing on android 10 Sharing via the saved image notification now shows the share sheet --- .../data/notification/NotificationReceiver.kt | 14 ++++--- .../ui/manga/info/MangaInfoController.kt | 37 ++++++++++++++++-- .../ui/manga/info/MangaInfoPresenter.kt | 38 +++++++++++++++++++ .../tachiyomi/ui/reader/ReaderActivity.kt | 22 ++++------- .../tachiyomi/ui/reader/ReaderSeekBar.kt | 12 ++++++ 5 files changed, 100 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index d5110055a3..c97a94acad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.notification import android.app.Notification import android.app.PendingIntent import android.content.BroadcastReceiver +import android.content.ClipData import android.content.Context import android.content.Intent import android.os.Handler @@ -86,12 +87,16 @@ class NotificationReceiver : BroadcastReceiver() { val uri = File(path).getUriCompat(context) putExtra(Intent.EXTRA_STREAM, uri) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION + clipData = ClipData.newRawUri(null, uri) type = "image/*" } - // Dismiss notification - dismissNotification(context, notificationId) + // Close Navigation Shade + context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) // Launch share activity - context.startActivity(intent) + val shareIntent = Intent.createChooser(intent, context.getString(R.string + .action_share)) + shareIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION + context.startActivity(shareIntent) } /** @@ -106,8 +111,7 @@ class NotificationReceiver : BroadcastReceiver() { val db = DatabaseHelper(context) val manga = db.getManga(mangaId).executeAsBlocking() val chapter = db.getChapter(chapterId).executeAsBlocking() - val it = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) - context.sendBroadcast(it) + context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) if (manga != null && chapter != null) { val intent = ReaderActivity.newIntent(context, manga, chapter).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index 7ebb33c770..aa17339f45 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -20,6 +20,7 @@ import android.widget.Toast import com.afollestad.materialdialogs.MaterialDialog import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.transition.Transition import com.jakewharton.rxbinding.support.v4.widget.refreshes @@ -46,6 +47,7 @@ import jp.wasabeef.glide.transformations.CropSquareTransformation import jp.wasabeef.glide.transformations.MaskTransformation import kotlinx.android.synthetic.main.manga_info_controller.* import uy.kohesive.injekt.injectLazy +import java.io.File import java.text.DateFormat import java.text.DecimalFormat import java.util.Date @@ -161,7 +163,7 @@ class MangaInfoController : NucleusController(), when (item.itemId) { R.id.action_open_in_browser -> openInBrowser() R.id.action_open_in_web_view -> openInWebView() - R.id.action_share -> shareManga() + R.id.action_share -> prepareToShareManga() R.id.action_add_to_home_screen -> addToHomeScreen() else -> return super.onOptionsItemSelected(item) } @@ -325,15 +327,40 @@ class MangaInfoController : NucleusController(), /** * Called to run Intent with [Intent.ACTION_SEND], which show share dialog. */ - private fun shareManga() { + private fun prepareToShareManga() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) + GlideApp.with(activity!!).asBitmap().load(presenter.manga).into(object : + CustomTarget() { + override fun onResourceReady(resource: Bitmap, transition: Transition?) { + presenter.shareManga(resource) + } + override fun onLoadCleared(placeholder: Drawable?) {} + + override fun onLoadFailed(errorDrawable: Drawable?) { + shareManga() + } + }) + else shareManga() + } + + /** + * Called to run Intent with [Intent.ACTION_SEND], which show share dialog. + */ + fun shareManga(cover: File? = null) { val context = view?.context ?: return val source = presenter.source as? HttpSource ?: return + val stream = cover?.getUriCompat(context) try { val url = source.mangaDetailsRequest(presenter.manga).url.toString() val intent = Intent(Intent.ACTION_SEND).apply { - type = "text/plain" + type = "text/*" putExtra(Intent.EXTRA_TEXT, url) + putExtra(Intent.EXTRA_TITLE, presenter.manga.title) + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + if (stream != null) { + clipData = ClipData.newRawUri(null, stream) + } } startActivity(Intent.createChooser(intent, context.getString(R.string.action_share))) } catch (e: Exception) { @@ -523,11 +550,13 @@ class MangaInfoController : NucleusController(), 3 -> centerCrop().transform(MaskTransformation(R.drawable.mask_star)) } } - .into(object : SimpleTarget(96, 96) { + .into(object : CustomTarget(96, 96) { override fun onResourceReady(resource: Bitmap, transition: Transition?) { createShortcut(resource) } + override fun onLoadCleared(placeholder: Drawable?) { } + override fun onLoadFailed(errorDrawable: Drawable?) { activity?.toast(R.string.icon_creation_fail) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt index 5e389d2e31..572d152a9c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt @@ -1,5 +1,7 @@ package eu.kanade.tachiyomi.ui.manga.info +import android.app.Application +import android.graphics.Bitmap import android.os.Bundle import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.PublishRelay @@ -11,6 +13,8 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.util.DiskUtil +import eu.kanade.tachiyomi.util.ImageUtil import eu.kanade.tachiyomi.util.isNullOrUnsubscribed import rx.Observable import rx.Subscription @@ -18,6 +22,11 @@ import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.InputStream +import java.io.OutputStream import java.util.* /** @@ -116,6 +125,35 @@ class MangaInfoPresenter( toggleFavorite() } + fun shareManga(cover:Bitmap) { + val context = Injekt.get() + + val destDir = File(context.cacheDir, "shared_image") + + Observable.fromCallable { destDir.deleteRecursively() } // Keep only the last shared file + .map { saveImage(cover, destDir, manga) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeFirst( + { view, file -> view.shareManga(file) }, + { view, error -> view.shareManga() } + ) + } + + private fun saveImage(cover:Bitmap, directory: File, manga: Manga): File? { + directory.mkdirs() + + // Build destination file. + val filename = DiskUtil.buildValidFilename("${manga.title} - Cover.jpg") + + val destFile = File(directory, filename) + val stream: OutputStream = FileOutputStream(destFile) + cover.compress(Bitmap.CompressFormat.JPEG,75,stream) + stream.flush() + stream.close() + return destFile + } + /** * Get the default, and user categories. * diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index f7711fc6a7..cf1ef64ba8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader import android.annotation.SuppressLint import android.app.ProgressDialog +import android.content.ClipData import android.content.Context import android.content.Intent import android.content.pm.ActivityInfo @@ -156,17 +157,6 @@ class ReaderActivity : BaseRxActivity(), config = ReaderConfig() initializeMenu() - val container: ViewGroup = findViewById(R.id.reader_container) - val readerBHeight = reader_menu_bottom.layoutParams.height - container.doOnApplyWindowInsets { _, insets, padding -> - val bottomInset = if (Build.VERSION.SDK_INT >= 29) - (insets.mandatorySystemGestureInsets.bottom - insets.systemWindowInsetBottom) - else 0 - reader_menu_bottom.updateLayoutParams { - height = readerBHeight + bottomInset - } - reader_menu_bottom.updatePaddingRelative(bottom = padding.bottom + bottomInset) - } } /** @@ -312,6 +302,9 @@ class ReaderActivity : BaseRxActivity(), systemUi?.show() reader_menu.visibility = View.VISIBLE reader_menu_bottom.visibility = View.VISIBLE + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + window.navigationBarColor = getResourceColor(R.attr.colorPrimaryDark) + } if (animate) { if (!menuStickyVisible) { val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_top) @@ -513,6 +506,7 @@ class ReaderActivity : BaseRxActivity(), val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, stream) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION + clipData = ClipData.newRawUri(null, stream) type = "image/*" } startActivity(Intent.createChooser(intent, getString(R.string.action_share))) @@ -570,6 +564,9 @@ class ReaderActivity : BaseRxActivity(), setMenuVisibility(false) menuStickyVisible = false } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + window.navigationBarColor = getColor(android.R.color.transparent) + } reader_menu_bottom.visibility = View.GONE reader_menu.visibility = View.VISIBLE val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_top) @@ -579,9 +576,6 @@ class ReaderActivity : BaseRxActivity(), } }) toolbar.startAnimation(toolbarAnimation) - /*val bottomAnimation = AnimationUtils.loadAnimation(this, R.anim - .enter_from_bottom) - reader_menu_bottom.startAnimation(bottomAnimation)*/ } } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSeekBar.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSeekBar.kt index 255367d3c4..48aeb56d32 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSeekBar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSeekBar.kt @@ -20,6 +20,8 @@ class ReaderSeekBar @JvmOverloads constructor( * Whether the seekbar should draw from right to left. */ var isRTL = false + private val boundingBox: Rect = Rect() + private val exclusions = listOf(boundingBox) /** * Draws the seekbar, translating the canvas if using a right to left reader. @@ -43,4 +45,14 @@ class ReaderSeekBar @JvmOverloads constructor( } return super.onTouchEvent(event) } + + override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + super.onLayout(changed, left, top, right, bottom) + if (Build.VERSION.SDK_INT >= 29) { + if (changed) { + boundingBox.set(left, top, right, bottom) + systemGestureExclusionRects = exclusions + } + } + } } From 6da8c368fa9ee3c2d6c53cf18304e168998ea053 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 2 Nov 2019 23:07:07 -0700 Subject: [PATCH 43/77] Fixes to android lollipop Notification icons now has color Coping title or other text in manga info is now a snackbar, shows the type of text copied --- .../data/download/DownloadNotifier.kt | 3 ++- .../data/library/LibraryUpdateService.kt | 5 +++-- .../tachiyomi/data/updater/UpdaterJob.kt | 3 ++- .../tachiyomi/data/updater/UpdaterNotifier.kt | 3 ++- .../ui/manga/info/MangaInfoController.kt | 20 +++++++++++-------- .../kanade/tachiyomi/util/ViewExtensions.kt | 8 ++++---- app/src/main/res/values/themes.xml | 2 +- 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt index bedcd43a54..e20f5b2a28 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.download import android.content.Context import android.graphics.BitmapFactory import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.DownloadQueue @@ -219,7 +220,7 @@ internal class DownloadNotifier(private val context: Context) { clearActions() setAutoCancel(true) setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) - color = context.getResourceColor(R.attr.colorAccent) + color = ContextCompat.getColor(context, R.color.colorAccentLight) setProgress(0, 0, false) } notification.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index dd2fbe4006..969879be4d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -10,6 +10,7 @@ import android.os.Build import android.os.IBinder import android.os.PowerManager import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category @@ -90,7 +91,7 @@ class LibraryUpdateService( .setLargeIcon(notificationBitmap) .setOngoing(true) .setOnlyAlertOnce(true) - .setColor(getResourceColor(R.attr.colorAccent)) + .setColor(ContextCompat.getColor(this, R.color.colorAccentLight)) .addAction(R.drawable.ic_clear_grey_24dp_img, getString(android.R.string.cancel), cancelIntent) } @@ -463,7 +464,7 @@ class LibraryUpdateService( setSmallIcon(R.drawable.ic_book_white_24dp) setLargeIcon(notificationBitmap) setContentTitle(getString(R.string.notification_new_chapters)) - color = getResourceColor(R.attr.colorAccent) + color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight) if (newUpdates.size > 1) { setContentText(getString(R.string.notification_new_chapters_text, newUpdates.size)) setStyle(NotificationCompat.BigTextStyle().bigText(newUpdates.joinToString("\n"))) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt index 6b69afabb5..deda43a7a9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.updater import android.app.PendingIntent import android.content.Intent import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import com.evernote.android.job.Job import com.evernote.android.job.JobManager import com.evernote.android.job.JobRequest @@ -28,7 +29,7 @@ class UpdaterJob : Job() { setContentTitle(context.getString(R.string.app_name)) setContentText(context.getString(R.string.update_check_notification_update_available)) setSmallIcon(android.R.drawable.stat_sys_download_done) - color = context.getResourceColor(R.attr.colorAccent) + color = ContextCompat.getColor(context, R.color.colorAccentLight) // Download action addAction(android.R.drawable.stat_sys_download_done, context.getString(R.string.action_download), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterNotifier.kt index 18575f8fa1..81023f6096 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterNotifier.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.updater import android.content.Context import android.net.Uri import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver @@ -96,7 +97,7 @@ internal class UpdaterNotifier(private val context: Context) { setSmallIcon(android.R.drawable.stat_sys_warning) setOnlyAlertOnce(false) setProgress(0, 0, false) - color = context.getResourceColor(R.attr.colorAccent) + color = ContextCompat.getColor(context, R.color.colorAccentLight) // Retry action addAction(R.drawable.ic_refresh_grey_24dp_img, context.getString(R.string.action_retry), diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index aa17339f45..5aefb15c03 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -101,7 +101,8 @@ class MangaInfoController : NucleusController(), swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() } manga_full_title.longClicks().subscribeUntilDestroy { - copyToClipboard(view.context.getString(R.string.title), manga_full_title.text.toString()) + copyToClipboard(view.context.getString(R.string.title), manga_full_title.text + .toString(), R.string.manga_info_full_title_label) } manga_full_title.clicks().subscribeUntilDestroy { @@ -109,7 +110,8 @@ class MangaInfoController : NucleusController(), } manga_artist.longClicks().subscribeUntilDestroy { - copyToClipboard(manga_artist_label.text.toString(), manga_artist.text.toString()) + copyToClipboard(manga_artist_label.text.toString(), manga_artist.text.toString(), R + .string.manga_info_artist_label) } manga_artist.clicks().subscribeUntilDestroy { @@ -117,7 +119,8 @@ class MangaInfoController : NucleusController(), } manga_author.longClicks().subscribeUntilDestroy { - copyToClipboard(manga_author.text.toString(), manga_author.text.toString()) + copyToClipboard(manga_author.text.toString(), manga_author.text.toString(), R.string + .manga_info_author_label) } manga_author.clicks().subscribeUntilDestroy { @@ -125,13 +128,14 @@ class MangaInfoController : NucleusController(), } manga_summary.longClicks().subscribeUntilDestroy { - copyToClipboard(view.context.getString(R.string.description), manga_summary.text.toString()) + copyToClipboard(view.context.getString(R.string.description), manga_summary.text + .toString(), R.string.description) } //manga_genres_tags.setOnTagClickListener { tag -> performGlobalSearch(tag) } manga_cover.longClicks().subscribeUntilDestroy { - copyToClipboard(view.context.getString(R.string.title), presenter.manga.title) + copyToClipboard(view.context.getString(R.string.title), presenter.manga.title, R.string.manga_info_full_title_label) } container = (view as ViewGroup).findViewById(R.id.manga_info_layout) as? View val bottomM = manga_genres_tags.marginBottom @@ -569,7 +573,7 @@ class MangaInfoController : NucleusController(), * @param label Label to show to the user describing the content * @param content the actual text to copy to the board */ - private fun copyToClipboard(label: String, content: String) { + private fun copyToClipboard(label: String, content: String, resId: Int) { if (content.isBlank()) return val activity = activity ?: return @@ -578,8 +582,8 @@ class MangaInfoController : NucleusController(), val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager clipboard.setPrimaryClip(ClipData.newPlainText(label, content)) - activity.toast(view.context.getString(R.string.copied_to_clipboard, content.truncateCenter(20)), - Toast.LENGTH_SHORT) + snack = container?.snack(view.context.getString(R.string.copied_to_clipboard, view.context + .getString(resId))) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt index 8558cf1ccc..7b8009e7ab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -55,10 +55,10 @@ Unit)? = null): Snackbar { if (f != null) { snack.f() } - snack.view.doOnApplyWindowInsets { v, insets, padding -> - //v.setPadding(padding.left, 0, padding.right, 0) - v.updateLayoutParams { - if (Build.VERSION.SDK_INT < 23) { + if (Build.VERSION.SDK_INT < 23) { + val view = if (this !is CoordinatorLayout) this else snack.view + view.doOnApplyWindowInsets { _, insets, _ -> + snack.view.updateLayoutParams { bottomMargin = 12 + insets.systemWindowInsetBottom } } diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index d6084bfebc..ce52db94c8 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -40,7 +40,7 @@ @color/iconColorLight @android:color/transparent - @color/colorPrimary + #B3000000