From 5f9574541fae585d28777ed61cb37313189d6a26 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 24 Apr 2021 19:11:23 -0400 Subject: [PATCH 1/8] Use popup menus for reader shortcuts instead of toggling through --- .../tachiyomi/ui/download/DownloadHolder.kt | 7 ++- .../ui/manga/chapter/ChaptersSettingsSheet.kt | 10 ++-- .../manga/chapter/base/BaseChapterHolder.kt | 1 - .../tachiyomi/ui/reader/ReaderActivity.kt | 33 ++++++++---- .../ui/reader/setting/OrientationType.kt | 6 --- .../ui/reader/setting/ReadingModeType.kt | 6 --- .../tachiyomi/util/lang/EnumExtensions.kt | 7 --- .../tachiyomi/util/view/ViewExtensions.kt | 52 ++++++++++++++++++- 8 files changed, 78 insertions(+), 44 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/util/lang/EnumExtensions.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadHolder.kt index aa3e7b14b..f7d76643a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadHolder.kt @@ -81,15 +81,14 @@ class DownloadHolder(private val view: View, val adapter: DownloadAdapter) : private fun showPopupMenu(view: View) { view.popupMenu( - R.menu.download_single, - { + menuRes = R.menu.download_single, + initMenu = { findItem(R.id.move_to_top).isVisible = bindingAdapterPosition != 0 findItem(R.id.move_to_bottom).isVisible = bindingAdapterPosition != adapter.itemCount - 1 }, - { + onMenuItemClick = { adapter.downloadItemListener.onMenuItemClick(bindingAdapterPosition, this) - true } ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt index 48ba1784a..4a23cad6d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt @@ -51,16 +51,12 @@ class ChaptersSettingsSheet( private fun showPopupMenu(view: View) { view.popupMenu( - R.menu.default_chapter_filter, - { - }, - { - when (this.itemId) { + menuRes = R.menu.default_chapter_filter, + onMenuItemClick = { + when (itemId) { R.id.set_as_default -> { SetChapterSettingsDialog(presenter.manga).showDialog(router) - true } - else -> true } } ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterHolder.kt index 60daf5405..4506ab59d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterHolder.kt @@ -29,7 +29,6 @@ open class BaseChapterHolder( }, onMenuItemClick = { adapter.clickListener.deleteChapter(position) - true } ) } 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 327da24c5..71ce36ef0 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 @@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.view.defaultBar import eu.kanade.tachiyomi.util.view.hideBar import eu.kanade.tachiyomi.util.view.isDefaultBar +import eu.kanade.tachiyomi.util.view.popupMenu import eu.kanade.tachiyomi.util.view.setTooltip import eu.kanade.tachiyomi.util.view.showBar import eu.kanade.tachiyomi.widget.SimpleAnimationListener @@ -356,13 +357,18 @@ class ReaderActivity : BaseRxActivity() setTooltip(R.string.viewer) setOnClickListener { - val newReadingMode = - ReadingModeType.getNextReadingMode(presenter.getMangaViewer(resolveDefault = false)) - presenter.setMangaViewer(newReadingMode.prefValue) + popupMenu( + items = ReadingModeType.values().map { it.prefValue to it.stringRes }, + selectedItemId = presenter.getMangaViewer(resolveDefault = false), + ) { + val newReadingMode = ReadingModeType.fromPreference(itemId) - menuToggleToast?.cancel() - if (!preferences.showReadingMode()) { - menuToggleToast = toast(newReadingMode.stringRes) + presenter.setMangaViewer(newReadingMode.prefValue) + + menuToggleToast?.cancel() + if (!preferences.showReadingMode()) { + menuToggleToast = toast(newReadingMode.stringRes) + } } } } @@ -372,13 +378,18 @@ class ReaderActivity : BaseRxActivity() setTooltip(R.string.pref_rotation_type) setOnClickListener { - val newOrientation = OrientationType.getNextOrientation(preferences.rotation().get()) + popupMenu( + items = OrientationType.values().map { it.prefValue to it.stringRes }, + selectedItemId = preferences.rotation().get(), + ) { + val newOrientation = OrientationType.fromPreference(itemId) - preferences.rotation().set(newOrientation.prefValue) - setOrientation(newOrientation.flag) + preferences.rotation().set(newOrientation.prefValue) + setOrientation(newOrientation.flag) - menuToggleToast?.cancel() - menuToggleToast = toast(newOrientation.stringRes) + menuToggleToast?.cancel() + menuToggleToast = toast(newOrientation.stringRes) + } } } preferences.rotation().asImmediateFlow { updateRotationShortcut(it) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt index 5f358a670..007b5e27a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt @@ -4,7 +4,6 @@ import android.content.pm.ActivityInfo import androidx.annotation.DrawableRes import androidx.annotation.StringRes import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.lang.next enum class OrientationType(val prefValue: Int, val flag: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) { FREE(1, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.rotation_free, R.drawable.ic_screen_rotation_24dp), @@ -17,10 +16,5 @@ enum class OrientationType(val prefValue: Int, val flag: Int, @StringRes val str companion object { fun fromPreference(preference: Int): OrientationType = values().find { it.prefValue == preference } ?: FREE - - fun getNextOrientation(preference: Int): OrientationType { - val current = fromPreference(preference) - return current.next() - } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt index 4f0c1a3f8..936546645 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.reader.setting import androidx.annotation.DrawableRes import androidx.annotation.StringRes import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.lang.next enum class ReadingModeType(val prefValue: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) { DEFAULT(0, R.string.default_viewer, R.drawable.ic_reader_default_24dp), @@ -17,11 +16,6 @@ enum class ReadingModeType(val prefValue: Int, @StringRes val stringRes: Int, @D companion object { fun fromPreference(preference: Int): ReadingModeType = values().find { it.prefValue == preference } ?: DEFAULT - fun getNextReadingMode(preference: Int): ReadingModeType { - val current = fromPreference(preference) - return current.next() - } - fun isPagerType(preference: Int): Boolean { val mode = fromPreference(preference) return mode == LEFT_TO_RIGHT || mode == RIGHT_TO_LEFT || mode == VERTICAL diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/lang/EnumExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/lang/EnumExtensions.kt deleted file mode 100644 index 4c9432303..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/util/lang/EnumExtensions.kt +++ /dev/null @@ -1,7 +0,0 @@ -package eu.kanade.tachiyomi.util.lang - -inline fun > T.next(): T { - val values = enumValues() - val nextOrdinal = (ordinal + 1) % values.size - return values[nextOrdinal] -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt index c50f111bf..3133f0e95 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.util.view +import android.annotation.SuppressLint import android.graphics.Point import android.view.Gravity import android.view.Menu @@ -9,14 +10,18 @@ import android.view.MenuItem import android.view.View import androidx.annotation.MenuRes import androidx.annotation.StringRes +import androidx.appcompat.view.menu.MenuBuilder import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.TooltipCompat +import androidx.core.content.ContextCompat +import androidx.core.view.forEach import androidx.recyclerview.widget.RecyclerView import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.snackbar.Snackbar import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.system.getResourceColor /** * Returns coordinates of view. @@ -63,7 +68,7 @@ inline fun View.setTooltip(@StringRes stringRes: Int) { inline fun View.popupMenu( @MenuRes menuRes: Int, noinline initMenu: (Menu.() -> Unit)? = null, - noinline onMenuItemClick: MenuItem.() -> Boolean + noinline onMenuItemClick: MenuItem.() -> Unit ): PopupMenu { val popup = PopupMenu(context, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0) popup.menuInflater.inflate(menuRes, popup.menu) @@ -71,7 +76,50 @@ inline fun View.popupMenu( if (initMenu != null) { popup.menu.initMenu() } - popup.setOnMenuItemClickListener { it.onMenuItemClick() } + popup.setOnMenuItemClickListener { + it.onMenuItemClick() + true + } + + popup.show() + return popup +} + +/** + * Shows a popup menu on top of this view. + * + * @param items menu item names to inflate the menu with. List of itemId to stringRes pairs. + * @param selectedItemId optionally show a checkmark beside an item with this itemId. + * @param onMenuItemClick function to execute when a menu item is clicked. + */ +@SuppressLint("RestrictedApi") +inline fun View.popupMenu( + items: List>, + selectedItemId: Int? = null, + noinline onMenuItemClick: MenuItem.() -> Unit +): PopupMenu { + val popup = PopupMenu(context, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0) + items.forEach { (id, stringRes) -> + popup.menu.add(0, id, 0, stringRes) + } + + if (selectedItemId != null) { + (popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true) + val emptyIcon = ContextCompat.getDrawable(context, R.drawable.ic_blank_24dp) + popup.menu.forEach { item -> + item.icon = when (item.itemId) { + selectedItemId -> ContextCompat.getDrawable(context, R.drawable.ic_check_24dp)?.mutate()?.apply { + setTint(context.getResourceColor(android.R.attr.textColorPrimary)) + } + else -> emptyIcon + } + } + } + + popup.setOnMenuItemClickListener { + it.onMenuItemClick() + true + } popup.show() return popup From 4e7b8c98f9b5fd532683eed54dd55f764bbee01d Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:42:06 +0700 Subject: [PATCH 2/8] Make the download progress status smoother (#4958) * Make the download progress status smoother * Download status icon cleanup --- .../tachiyomi/ui/manga/MangaController.kt | 3 +- .../ui/manga/chapter/ChapterDownloadView.kt | 45 +++++++++++-------- .../res/drawable/ic_error_outline_24dp.xml | 3 +- .../main/res/layout/chapter_download_view.xml | 25 +---------- 4 files changed, 31 insertions(+), 45 deletions(-) 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 c4025a6a0..2e5b3f9e9 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 @@ -727,8 +727,7 @@ class MangaController : fun onChapterDownloadUpdate(download: Download) { chaptersAdapter?.currentItems?.find { it.id == download.chapter.id }?.let { - chaptersAdapter?.updateItem(it) - chaptersAdapter?.notifyDataSetChanged() + chaptersAdapter?.updateItem(it, it.status) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt index 533deaa09..59a0c5367 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt @@ -5,23 +5,24 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.FrameLayout +import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.databinding.ChapterDownloadViewBinding class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { - private val binding: ChapterDownloadViewBinding + private val binding: ChapterDownloadViewBinding = + ChapterDownloadViewBinding.inflate(LayoutInflater.from(context), this, false) private var state = Download.State.NOT_DOWNLOADED private var progress = 0 private var downloadIconAnimator: ObjectAnimator? = null - private var isAnimating = false init { - binding = ChapterDownloadViewBinding.inflate(LayoutInflater.from(context), this, false) addView(binding.root) } @@ -37,11 +38,12 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att } private fun updateLayout() { - binding.downloadIconBorder.isVisible = state == Download.State.NOT_DOWNLOADED + binding.downloadIconBorder.isVisible = state == Download.State.NOT_DOWNLOADED || state == Download.State.QUEUE - binding.downloadIcon.isVisible = state == Download.State.NOT_DOWNLOADED || state == Download.State.DOWNLOADING - if (state == Download.State.DOWNLOADING) { - if (!isAnimating) { + binding.downloadIcon.isVisible = state == Download.State.NOT_DOWNLOADED || + state == Download.State.DOWNLOADING || state == Download.State.QUEUE + if (state == Download.State.DOWNLOADING || state == Download.State.QUEUE) { + if (downloadIconAnimator == null) { downloadIconAnimator = ObjectAnimator.ofFloat(binding.downloadIcon, "alpha", 1f, 0f).apply { duration = 1000 @@ -49,22 +51,29 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att repeatMode = ObjectAnimator.REVERSE } downloadIconAnimator?.start() - isAnimating = true } - } else { + downloadIconAnimator?.currentPlayTime = System.currentTimeMillis() % 2000 + } else if (downloadIconAnimator != null) { downloadIconAnimator?.cancel() + downloadIconAnimator = null binding.downloadIcon.alpha = 1f - isAnimating = false } - binding.downloadQueued.isVisible = state == Download.State.QUEUE + binding.downloadProgress.isVisible = state == Download.State.DOWNLOADING + binding.downloadProgress.setProgressCompat(progress, true) - binding.downloadProgress.isVisible = state == Download.State.DOWNLOADING || - (state == Download.State.QUEUE && progress > 0) - binding.downloadProgress.progress = progress - - binding.downloadedIcon.isVisible = state == Download.State.DOWNLOADED - - binding.errorIcon.isVisible = state == Download.State.ERROR + binding.downloadStatusIcon.apply { + if (state == Download.State.DOWNLOADED || state == Download.State.ERROR) { + isVisible = true + val drawable = if (state == Download.State.DOWNLOADED) { + ContextCompat.getDrawable(context, R.drawable.ic_check_circle_24dp) + } else { + ContextCompat.getDrawable(context, R.drawable.ic_error_outline_24dp) + } + setImageDrawable(drawable) + } else { + isVisible = false + } + } } } diff --git a/app/src/main/res/drawable/ic_error_outline_24dp.xml b/app/src/main/res/drawable/ic_error_outline_24dp.xml index 5ea6b9db1..74e652794 100644 --- a/app/src/main/res/drawable/ic_error_outline_24dp.xml +++ b/app/src/main/res/drawable/ic_error_outline_24dp.xml @@ -2,7 +2,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="?colorError"> diff --git a/app/src/main/res/layout/chapter_download_view.xml b/app/src/main/res/layout/chapter_download_view.xml index a0d90c790..9b5d5c6dd 100644 --- a/app/src/main/res/layout/chapter_download_view.xml +++ b/app/src/main/res/layout/chapter_download_view.xml @@ -38,36 +38,13 @@ app:indicatorSize="24dp" app:trackThickness="2dp" /> - - - - From f407e30b6e6b5c337f4c7ac5abb7ae0cce093688 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 25 Apr 2021 10:57:14 -0400 Subject: [PATCH 3/8] Reset Incognito Mode on app relaunch (closes #4928) --- app/src/main/java/eu/kanade/tachiyomi/App.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index e7cacadb3..6f236a0d7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -52,6 +52,9 @@ open class App : Application(), LifecycleObserver { LocaleHelper.updateConfiguration(this, resources.configuration) ProcessLifecycleOwner.get().lifecycle.addObserver(this) + + // Reset Incognito Mode on relaunch + preferences.incognitoMode().set(false) } override fun attachBaseContext(base: Context) { From 6ba82da02991d8496cfbc37ab28ae5dce26e38c8 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 25 Apr 2021 10:59:53 -0400 Subject: [PATCH 4/8] Don't automatically go to HALF_EXPANDED state for color filter tab (closes #4913) --- .../tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt index f5d5648cd..c1bad95cb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt @@ -22,7 +22,7 @@ class ReaderSettingsSheet( init { val sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup) sheetBehavior.isFitToContents = false - sheetBehavior.halfExpandedRatio = 0.5f + sheetBehavior.halfExpandedRatio = 0.25f val filterTabIndex = getTabViews().indexOf(colorFilterSettings) binding.tabs.addOnTabSelectedListener(object : SimpleTabSelectedListener() { @@ -36,11 +36,6 @@ class ReaderSettingsSheet( if (activity.menuVisible != !isFilterTab) { activity.setMenuVisibility(!isFilterTab) } - - // Partially collapse the sheet for better preview - if (isFilterTab) { - sheetBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED - } } }) From f608cb55ebc3a1ecaf26258113489b6ca91a3503 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 25 Apr 2021 11:01:12 -0400 Subject: [PATCH 5/8] Minor cleanup to updating download status in Updates --- .../eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index 6b427d0a6..33077968a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -242,8 +242,7 @@ class UpdatesController : adapter?.currentItems ?.filterIsInstance() ?.find { it.chapter.id == download.chapter.id }?.let { - adapter?.updateItem(it) - adapter?.notifyDataSetChanged() + adapter?.updateItem(it, it.status) } } From 662b71436eea6ddda4d15d18ec0946e946c6e4e9 Mon Sep 17 00:00:00 2001 From: Andreas Date: Sun, 25 Apr 2021 17:08:51 +0200 Subject: [PATCH 6/8] Cleanup dual page split (#4956) * Cleanup Dual Page Split * Move where images is processed * Change parameter name to imageStream * Use available instead of Int.MAX_VALUE * Update JavaDoc --- .../ui/reader/viewer/pager/PagerPageHolder.kt | 39 ++++++++++--------- .../ui/reader/viewer/pager/PagerViewer.kt | 5 ++- .../viewer/webtoon/WebtoonPageHolder.kt | 25 +++++++----- .../kanade/tachiyomi/util/system/ImageUtil.kt | 11 ++++-- 4 files changed, 48 insertions(+), 32 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 633e7af31..2a9cf6635 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 @@ -235,16 +235,13 @@ class PagerPageHolder( readImageHeaderSubscription = Observable .fromCallable { val stream = streamFn().buffered(16) - openStream = stream + openStream = process(stream) ImageUtil.findImageType(stream) == ImageUtil.ImageType.GIF } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { isAnimated -> - if (viewer.config.dualPageSplit) { - openStream = processDualPageSplit(openStream!!) - } if (!isAnimated) { initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) } else { @@ -257,21 +254,31 @@ class PagerPageHolder( .subscribe({}, {}) } - private fun processDualPageSplit(openStream: InputStream): InputStream { - var inputStream = openStream - val (isDoublePage, stream) = when (page) { - is InsertPage -> Pair(true, inputStream) - else -> ImageUtil.isDoublePage(inputStream) + private fun process(imageStream: InputStream): InputStream { + if (!viewer.config.dualPageSplit) { + return imageStream } - inputStream = stream - if (!isDoublePage) return inputStream + if (page is InsertPage) { + return splitInHalf(imageStream) + } + val isDoublePage = ImageUtil.isDoublePage(imageStream) + if (!isDoublePage) { + return imageStream + } + + onPageSplit() + + return splitInHalf(imageStream) + } + + private fun splitInHalf(imageStream: InputStream): InputStream { var side = when { viewer is L2RPagerViewer && page is InsertPage -> ImageUtil.Side.RIGHT - (viewer is R2LPagerViewer || viewer is VerticalPagerViewer) && page is InsertPage -> ImageUtil.Side.LEFT + viewer !is L2RPagerViewer && page is InsertPage -> ImageUtil.Side.LEFT viewer is L2RPagerViewer && page !is InsertPage -> ImageUtil.Side.LEFT - (viewer is R2LPagerViewer || viewer is VerticalPagerViewer) && page !is InsertPage -> ImageUtil.Side.RIGHT + viewer !is L2RPagerViewer && page !is InsertPage -> ImageUtil.Side.RIGHT else -> error("We should choose a side!") } @@ -282,11 +289,7 @@ class PagerPageHolder( } } - if (page !is InsertPage) { - onPageSplit() - } - - return ImageUtil.splitInHalf(inputStream, side) + return ImageUtil.splitInHalf(imageStream, side) } private fun onPageSplit() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index 0ca303bf4..b5808f4bf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt @@ -385,7 +385,10 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer { } fun onPageSplit(currentPage: ReaderPage, newPage: InsertPage) { - adapter.onPageSplit(currentPage, newPage, this::class.java) + activity.runOnUiThread { + // Need to insert on UI thread else images will go blank + adapter.onPageSplit(currentPage, newPage, this::class.java) + } } private fun cleanupPageSplit() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index a66c0bba4..fc72f0974 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt @@ -281,22 +281,13 @@ class WebtoonPageHolder( readImageHeaderSubscription = Observable .fromCallable { val stream = streamFn().buffered(16) - openStream = stream + openStream = process(stream) ImageUtil.findImageType(stream) == ImageUtil.ImageType.GIF } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { isAnimated -> - if (viewer.config.dualPageSplit) { - val (isDoublePage, stream) = ImageUtil.isDoublePage(openStream!!) - openStream = if (!isDoublePage) { - stream - } else { - val upperSide = if (viewer.config.dualPageInvert) ImageUtil.Side.LEFT else ImageUtil.Side.RIGHT - ImageUtil.splitAndMerge(stream, upperSide) - } - } if (!isAnimated) { val subsamplingView = initSubsamplingImageView() subsamplingView.isVisible = true @@ -315,6 +306,20 @@ class WebtoonPageHolder( addSubscription(readImageHeaderSubscription) } + private fun process(imageStream: InputStream): InputStream { + if (!viewer.config.dualPageSplit) { + return imageStream + } + + val isDoublePage = ImageUtil.isDoublePage(imageStream) + if (!isDoublePage) { + return imageStream + } + + val upperSide = if (viewer.config.dualPageInvert) ImageUtil.Side.LEFT else ImageUtil.Side.RIGHT + return ImageUtil.splitAndMerge(imageStream, upperSide) + } + /** * Called when the page has an error. */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt index 61fdee35d..b21efff0b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt @@ -77,15 +77,20 @@ object ImageUtil { } /** - * Check whether the image is a double image (width > height), return the result and original stream + * Check whether the image is a double-page spread + * @return true if the width is greater than the height */ - fun isDoublePage(imageStream: InputStream): Pair { + fun isDoublePage(imageStream: InputStream): Boolean { + imageStream.mark(imageStream.available() + 1) + val imageBytes = imageStream.readBytes() val options = BitmapFactory.Options().apply { inJustDecodeBounds = true } BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size, options) - return Pair(options.outWidth > options.outHeight, ByteArrayInputStream(imageBytes)) + imageStream.reset() + + return options.outWidth > options.outHeight } /** From bf80dd622c9ebbdd27500f210858231a74ac3f4f Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sun, 25 Apr 2021 22:36:13 +0700 Subject: [PATCH 7/8] Fix download error icon color tint (#4959) * Fix download error color tint * Use progress indicator as download icon border * Resolve feedback * Use extension function to set tinted drawable --- .../ui/manga/chapter/ChapterDownloadView.kt | 31 ++++++++++--------- app/src/main/res/drawable/border_circle.xml | 12 ------- .../res/drawable/ic_error_outline_24dp.xml | 3 +- .../main/res/layout/chapter_download_view.xml | 14 +-------- 4 files changed, 18 insertions(+), 42 deletions(-) delete mode 100644 app/src/main/res/drawable/border_circle.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt index 59a0c5367..e53ab627e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt @@ -5,11 +5,11 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.FrameLayout -import androidx.core.content.ContextCompat import androidx.core.view.isVisible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.databinding.ChapterDownloadViewBinding +import eu.kanade.tachiyomi.util.view.setVectorCompat class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { @@ -28,18 +28,12 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att fun setState(state: Download.State, progress: Int = 0) { val isDirty = this.state.value != state.value || this.progress != progress - - this.state = state - this.progress = progress - if (isDirty) { - updateLayout() + updateLayout(state, progress) } } - private fun updateLayout() { - binding.downloadIconBorder.isVisible = state == Download.State.NOT_DOWNLOADED || state == Download.State.QUEUE - + private fun updateLayout(state: Download.State, progress: Int) { binding.downloadIcon.isVisible = state == Download.State.NOT_DOWNLOADED || state == Download.State.DOWNLOADING || state == Download.State.QUEUE if (state == Download.State.DOWNLOADING || state == Download.State.QUEUE) { @@ -59,21 +53,28 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att binding.downloadIcon.alpha = 1f } - binding.downloadProgress.isVisible = state == Download.State.DOWNLOADING - binding.downloadProgress.setProgressCompat(progress, true) + binding.downloadProgress.isVisible = state == Download.State.DOWNLOADING || + state == Download.State.NOT_DOWNLOADED || state == Download.State.QUEUE + if (state == Download.State.DOWNLOADING) { + binding.downloadProgress.setProgressCompat(progress, true) + } else { + binding.downloadProgress.setProgressCompat(100, true) + } binding.downloadStatusIcon.apply { if (state == Download.State.DOWNLOADED || state == Download.State.ERROR) { isVisible = true - val drawable = if (state == Download.State.DOWNLOADED) { - ContextCompat.getDrawable(context, R.drawable.ic_check_circle_24dp) + if (state == Download.State.DOWNLOADED) { + setVectorCompat(R.drawable.ic_check_circle_24dp, android.R.attr.textColorPrimary) } else { - ContextCompat.getDrawable(context, R.drawable.ic_error_outline_24dp) + setVectorCompat(R.drawable.ic_error_outline_24dp, R.attr.colorError) } - setImageDrawable(drawable) } else { isVisible = false } } + + this.state = state + this.progress = progress } } diff --git a/app/src/main/res/drawable/border_circle.xml b/app/src/main/res/drawable/border_circle.xml deleted file mode 100644 index 4dbe8c7bd..000000000 --- a/app/src/main/res/drawable/border_circle.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/ic_error_outline_24dp.xml b/app/src/main/res/drawable/ic_error_outline_24dp.xml index 74e652794..5ea6b9db1 100644 --- a/app/src/main/res/drawable/ic_error_outline_24dp.xml +++ b/app/src/main/res/drawable/ic_error_outline_24dp.xml @@ -2,8 +2,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?colorError"> + android:viewportHeight="24"> diff --git a/app/src/main/res/layout/chapter_download_view.xml b/app/src/main/res/layout/chapter_download_view.xml index 9b5d5c6dd..f1bb020d9 100644 --- a/app/src/main/res/layout/chapter_download_view.xml +++ b/app/src/main/res/layout/chapter_download_view.xml @@ -7,16 +7,6 @@ android:padding="8dp" android:background="?selectableItemBackgroundBorderless"> - - From 523683491192207872a89da0ecf273c9d301ad13 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 25 Apr 2021 15:33:15 -0400 Subject: [PATCH 8/8] [SKIP CI] Update issue-closer-action --- .github/workflows/issue_closer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue_closer.yml b/.github/workflows/issue_closer.yml index 617120eb3..bd64df5d3 100644 --- a/.github/workflows/issue_closer.yml +++ b/.github/workflows/issue_closer.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Autoclose issues - uses: arkon/issue-closer-action@v3.0 + uses: arkon/issue-closer-action@v3.1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} rules: |