diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 599d95613..133dd6ca6 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -372,4 +372,6 @@ object PreferenceKeys { const val leftVerticalSeekbar = "pref_left_handed_vertical_seekbar" const val forceHorizontalSeekbar = "pref_force_horz_seekbar" + + const val readerBottomButtons = "reader_bottom_buttons" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index f88a425f4..5ddee87f9 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.ui.reader.setting.OrientationType +import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.widget.ExtendedNavigationView import kotlinx.coroutines.flow.Flow @@ -488,4 +489,6 @@ class PreferencesHelper(val context: Context) { fun landscapeVerticalSeekbar() = flowPrefs.getBoolean(Keys.landscapeVerticalSeekbar, false) fun leftVerticalSeekbar() = flowPrefs.getBoolean(Keys.leftVerticalSeekbar, false) + + fun readerBottomButtons() = flowPrefs.getStringSet(Keys.readerBottomButtons, ReaderBottomButton.BUTTONS_DEFAULTS) } 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 1dfe2053b..3835c454b 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 @@ -54,6 +54,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.ui.reader.setting.OrientationType +import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsSheet import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer @@ -70,6 +71,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 @@ -441,28 +443,12 @@ class ReaderActivity : BaseRxActivity() } // SY <-- - /*binding.actionRotation.setOnClickListener { - val newOrientation = OrientationType.getNextOrientation(preferences.rotation().get(), resources) - - preferences.rotation().set(newOrientation.prefValue) - setOrientation(newOrientation.flag) - - rotationToast?.cancel() - rotationToast = toast(newOrientation.stringRes) - } - preferences.rotation().asImmediateFlow { updateRotationShortcut(it) } - .onEach { - updateRotationShortcut(it) - } - .launchIn(lifecycleScope) - */ - binding.actionSettings.setOnClickListener { ReaderSettingsSheet(this).show() } // Reading mode - /*with(binding.actionReadingMode) { + with(binding.actionReadingMode) { setTooltip(R.string.viewer) setOnClickListener { @@ -502,7 +488,7 @@ class ReaderActivity : BaseRxActivity() menuToggleToast = toast(newOrientation.stringRes) } } - }*/ + } // Crop borders with(binding.actionCropBorders) { @@ -721,6 +707,8 @@ class ReaderActivity : BaseRxActivity() .launchIn(lifecycleScope) chapterBottomSheet = ReaderChapterSheet(this) + + updateBottomButtons() // <-- EH // Set initial visibility @@ -736,12 +724,39 @@ class ReaderActivity : BaseRxActivity() val currentPage = (((viewer as? PagerViewer)?.currentPage ?: (viewer as? WebtoonViewer)?.currentPage) as? ReaderPage)?.index return currentPage?.let { presenter.viewerChaptersRelay.value.currChapter.pages?.getOrNull(it) } } + + fun updateBottomButtons() { + val enabledButtons = preferences.readerBottomButtons().get() + with(binding) { + actionReadingMode.isVisible = ReaderBottomButton.ReadingMode.isIn(enabledButtons) + actionRotation.isVisible = + ReaderBottomButton.Rotation.isIn(enabledButtons) + // doublePage.isVisible = viewer is PagerViewer && ReaderBottomButton.PageLayout.isIn(enabledButtons) + actionCropBorders.isVisible = + if (viewer is PagerViewer) { + ReaderBottomButton.CropBordersPager.isIn(enabledButtons) + } else { + val continuous = (viewer as? WebtoonViewer)?.isContinuous ?: false + if (continuous) { + ReaderBottomButton.CropBordersWebtoon.isIn(enabledButtons) + } else { + ReaderBottomButton.CropBordersContinuesVertical.isIn(enabledButtons) + } + } + actionWebView.isVisible = + ReaderBottomButton.WebView.isIn(enabledButtons) + actionChapterList.isVisible = + ReaderBottomButton.ViewChapters.isIn(enabledButtons) + // shiftPageButton.isVisible = ((viewer as? PagerViewer)?.config?.doublePages ?: false) && ReaderBottomButton.ShiftDoublePage.isIn(enabledButtons) + // binding.toolbar.menu.findItem(R.id.action_shift_double_page)?.isVisible = ((viewer as? PagerViewer)?.config?.doublePages ?: false) && !ReaderBottomButton.ShiftDoublePage.isIn(enabledButtons) + } + } // EXH <-- - /*private fun updateOrientationShortcut(preference: Int) { + private fun updateOrientationShortcut(preference: Int) { val orientation = OrientationType.fromPreference(preference) binding.actionRotation.setImageResource(orientation.iconRes) - }*/ + } private fun updateCropBordersShortcut() { val mangaViewer = presenter.getMangaReadingMode() @@ -950,6 +965,7 @@ class ReaderActivity : BaseRxActivity() // <-- Left-handed vertical seekbar + updateBottomButtons() // SY <-- binding.toolbar.title = manga.title diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderBottomButton.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderBottomButton.kt new file mode 100644 index 000000000..354ec28fa --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderBottomButton.kt @@ -0,0 +1,28 @@ +package eu.kanade.tachiyomi.ui.reader.setting + +import androidx.annotation.StringRes +import eu.kanade.tachiyomi.R + +enum class ReaderBottomButton(val value: String, @StringRes val stringRes: Int) { + ViewChapters("vc", R.string.action_view_chapters), + WebView("wb", R.string.action_open_in_web_view), + ReadingMode("rm", R.string.viewer), + Rotation("rot", R.string.rotation_type), + CropBordersPager("cbp", R.string.pref_crop_borders_pager), + CropBordersContinuesVertical("cbc", R.string.pref_crop_borders_continues_vertical), + CropBordersWebtoon("cbw", R.string.pref_crop_borders_webtoon), + // PageLayout("pl", R.string.page_layout), + // ShiftDoublePage("sdp", R.string.shift_double_pages) + ; + + fun isIn(buttons: Collection) = value in buttons + + companion object { + val BUTTONS_DEFAULTS = setOf( + ViewChapters, + WebView, + CropBordersPager, + CropBordersContinuesVertical + ).map { it.value }.toSet() + } +} 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 d9e833a6c..adf072dc9 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 @@ -1,22 +1,33 @@ package eu.kanade.tachiyomi.ui.setting +import android.app.Dialog import android.os.Build +import android.os.Bundle import androidx.preference.PreferenceScreen +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.list.listItemsMultiChoice import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceValues.TappingInvertMode +import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow +import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.reader.setting.OrientationType +import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.intListPreference import eu.kanade.tachiyomi.util.preference.listPreference +import eu.kanade.tachiyomi.util.preference.onClick +import eu.kanade.tachiyomi.util.preference.preference import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.summaryRes import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.hasDisplayCutout import kotlinx.coroutines.flow.launchIn +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys class SettingsReaderController : SettingsController() { @@ -494,7 +505,46 @@ class SettingsReaderController : SettingsController() { summaryRes = R.string.auto_webtoon_mode_summary defaultValue = true } + + preference { + key = "reader_bottom_buttons_pref" + titleRes = R.string.reader_bottom_buttons + summaryRes = R.string.reader_bottom_buttons_summary + + onClick { + ReaderBottomButtonsDialog().showDialog(router) + } + } } // EXH <-- } + + class ReaderBottomButtonsDialog : DialogController() { + + private val preferences: PreferencesHelper = Injekt.get() + + override fun onCreateDialog(savedViewState: Bundle?): Dialog { + val selected = preferences.readerBottomButtons().get() + val values = ReaderBottomButton.values() + val items = values.map { it.value } + + val preselected = selected.mapNotNull { selection -> items.indexOf(selection).takeUnless { it == -1 } } + .toIntArray() + + return MaterialDialog(activity!!) + .title(R.string.reader_bottom_buttons) + .listItemsMultiChoice( + items = values.map { activity!!.getString(it.stringRes) }, + initialSelection = preselected + ) { _, selections: IntArray, _ -> + val included = selections + .map { values[it].value } + .toSet() + + preferences.readerBottomButtons().set(included) + } + .positiveButton(android.R.string.ok) + .negativeButton(android.R.string.cancel) + } + } } diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index fd74f67aa..9e14353d4 100755 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -387,6 +387,7 @@ app:layout_constraintEnd_toStartOf="@+id/action_web_view" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" + app:layout_constraintHorizontal_chainStyle="spread" app:srcCompat="@drawable/ic_format_list_numbered_24dp" app:tint="?attr/colorOnPrimary" /> @@ -397,12 +398,27 @@ android:background="?selectableItemBackgroundBorderless" android:contentDescription="@string/custom_filter" android:padding="@dimen/material_layout_keylines_screen_edge_margin" - app:layout_constraintEnd_toStartOf="@id/action_crop_borders" + app:layout_constraintEnd_toStartOf="@id/action_reading_mode" app:layout_constraintStart_toEndOf="@+id/action_chapter_list" app:layout_constraintTop_toTopOf="parent" + app:layout_constraintHorizontal_chainStyle="spread" app:srcCompat="@drawable/ic_public_24dp" app:tint="?attr/colorOnPrimary" /> + + + + diff --git a/app/src/main/res/values/strings_sy.xml b/app/src/main/res/values/strings_sy.xml index c03bf0550..82947dcb1 100644 --- a/app/src/main/res/values/strings_sy.xml +++ b/app/src/main/res/values/strings_sy.xml @@ -217,6 +217,7 @@ Invalid time selected + Page Downloading Download threads Higher values can speed up image downloading significantly, but can also trigger bans. Recommended value is 2 or 3. Current value is: %s Aggressively load pages @@ -244,6 +245,8 @@ Smart (based on page and theme) Tap scroll by page Tapping will scroll by page instead of screen size when this option is enabled + Reader Bottom Buttons + Customize what buttons appear at the bottom of the reader Show vertical seekbar in landscape Enables vertical seekbar when in landscape @@ -263,6 +266,9 @@ Re-add all failed pages to the download queue. Boost page help Normally the downloader can only download a specific amount of pages at the same time. This means you can be waiting for a page to download but the downloader will not start downloading the page until it has a free download slot. Pressing \'Boost page\' will force the downloader to begin downloading the current page, regardless of whether or not there is an available slot. + Crop borders Pager + Crop borders Continues Vertical + Crop borders Webtoon Reading webtoon style