From fe2543b9d5da176b1dbb95058d1bfc54400fd47a Mon Sep 17 00:00:00 2001 From: Jays2Kings Date: Wed, 24 Mar 2021 17:10:31 -0400 Subject: [PATCH] Reworking Reader Activity Menus Reader settings sheet now in a tabbed layout Reader settings sheet also contains filter options Reader menu now holds the long tap options (Share, Save, Set as cover) Reader menu also has option to go to manga details (was on toolbar tap) Also has the option to jump straight to reader settings Removing long tap gesture on Reader since no longer needed --- .../data/preference/PreferenceKeys.kt | 2 - .../data/preference/PreferencesHelper.kt | 2 - .../ui/library/display/LibraryBadgesView.kt | 2 +- .../ui/library/display/LibraryCategoryView.kt | 1 + .../ui/library/display/LibraryDisplayView.kt | 1 + .../library/display/LibraryPreferenceView.kt | 38 -- .../display/TabbedLibraryDisplaySheet.kt | 2 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 1 + .../tachiyomi/ui/main/SearchActivity.kt | 19 +- .../tachiyomi/ui/reader/ReaderActivity.kt | 83 ++-- .../ui/reader/ReaderSettingsSheet.kt | 194 -------- .../reader/settings/BaseReaderSettingsView.kt | 25 + .../ReaderFilterView.kt} | 145 ++---- .../ui/reader/settings/ReaderGeneralView.kt | 46 ++ .../ui/reader/settings/ReaderPagedView.kt | 49 ++ .../reader/settings/ReaderPreferenceView.kt | 134 +++++ .../settings/TabbedReaderSettingsSheet.kt | 99 ++++ .../ui/reader/viewer/ViewerConfig.kt | 4 - .../ui/reader/viewer/pager/PagerViewer.kt | 10 - .../ui/reader/viewer/webtoon/WebtoonViewer.kt | 14 - .../ui/setting/SettingsReaderController.kt | 5 - .../tachiyomi/util/PreferenceExtensions.kt | 74 +++ .../tachiyomi/widget/TabbedBottomSheet.kt | 28 +- app/src/main/res/drawable/filter_mock.webp | Bin 77344 -> 0 bytes app/src/main/res/drawable/ic_book_24dp.xml | 3 +- .../layout-land/reader_color_filter_sheet.xml | 49 -- .../main/res/layout/reader_color_filter.xml | 457 +++++++++--------- .../res/layout/reader_color_filter_sheet.xml | 41 -- .../main/res/layout/reader_general_layout.xml | 86 ++++ .../main/res/layout/reader_paged_layout.xml | 104 ++++ app/src/main/res/layout/reader_preference.xml | 61 +++ .../main/res/layout/reader_settings_sheet.xml | 328 ------------- app/src/main/res/menu/reader.xml | 40 +- app/src/main/res/values/attrs.xml | 6 + app/src/main/res/values/strings.xml | 5 + 35 files changed, 1082 insertions(+), 1076 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/BaseReaderSettingsView.kt rename app/src/main/java/eu/kanade/tachiyomi/ui/reader/{ReaderColorFilterSheet.kt => settings/ReaderFilterView.kt} (63%) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderGeneralView.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPagedView.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPreferenceView.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/TabbedReaderSettingsSheet.kt delete mode 100644 app/src/main/res/drawable/filter_mock.webp delete mode 100644 app/src/main/res/layout-land/reader_color_filter_sheet.xml delete mode 100644 app/src/main/res/layout/reader_color_filter_sheet.xml create mode 100644 app/src/main/res/layout/reader_general_layout.xml create mode 100644 app/src/main/res/layout/reader_paged_layout.xml create mode 100644 app/src/main/res/layout/reader_preference.xml delete mode 100644 app/src/main/res/layout/reader_settings_sheet.xml 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 830e420501..160d6801e2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -49,8 +49,6 @@ object PreferenceKeys { const val readWithTapping = "reader_tap" - const val readWithLongTap = "reader_long_tap" - const val readWithVolumeKeys = "reader_volume_keys" const val readWithVolumeKeysInverted = "reader_volume_keys_inverted" 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 1064798ee7..16a8ab554d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -126,8 +126,6 @@ class PreferencesHelper(val context: Context) { fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true) - fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true) - fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false) fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryBadgesView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryBadgesView.kt index c5ef27e6da..cdb839d6e7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryBadgesView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryBadgesView.kt @@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display import android.content.Context import android.util.AttributeSet -import eu.kanade.tachiyomi.ui.library.LibraryController +import eu.kanade.tachiyomi.util.bindToPreference import kotlinx.android.synthetic.main.library_badges_layout.view.* class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt index b172b7e12e..6a43e3e1f3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display import android.content.Context import android.util.AttributeSet +import eu.kanade.tachiyomi.util.bindToPreference import kotlinx.android.synthetic.main.library_category_layout.view.* class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt index 45e34b96a0..841d794904 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display import android.content.Context import android.util.AttributeSet +import eu.kanade.tachiyomi.util.bindToPreference import kotlinx.android.synthetic.main.library_display_layout.view.* class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryPreferenceView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryPreferenceView.kt index 3ca80daaa9..14629dcec4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryPreferenceView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryPreferenceView.kt @@ -25,42 +25,4 @@ abstract class LibraryPreferenceView @JvmOverloads constructor(context: Context, super.onFinishInflate() initGeneralPreferences() } - - /** - * Binds a checkbox or switch view with a boolean preference. - */ - internal fun CompoundButton.bindToPreference(pref: Preference, block: (() -> Unit)? = null) { - isChecked = pref.getOrDefault() - setOnCheckedChangeListener { _, isChecked -> - pref.set(isChecked) - block?.invoke() - } - } - - /** - * Binds a checkbox or switch view with a boolean preference. - */ - internal fun CompoundButton.bindToPreference( - pref: com.tfcporciuncula.flow - .Preference, - block: ((Boolean) -> Unit)? = null - ) { - isChecked = pref.get() - setOnCheckedChangeListener { _, isChecked -> - pref.set(isChecked) - block?.invoke(isChecked) - } - } - - /** - * Binds a radio group with a int preference. - */ - internal fun RadioGroup.bindToPreference(pref: Preference, block: (() -> Unit)? = null) { - (getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true - setOnCheckedChangeListener { _, checkedId -> - val index = indexOfChild(findViewById(checkedId)) - pref.set(index) - block?.invoke() - } - } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt index 06399dbd58..4917c89967 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt @@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog import kotlinx.android.synthetic.main.tabbed_bottom_sheet.* open class TabbedLibraryDisplaySheet(controller: LibraryController): - TabbedBottomSheetDialog(controller) { + TabbedBottomSheetDialog(controller.activity!!) { private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView private val badgesView: LibraryBadgesView = inflate(controller.activity!!, R.layout.library_badges_layout, null) as LibraryBadgesView 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 7d27566344..14aad42238 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 @@ -693,6 +693,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE" const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS" const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA" + const val SHORTCUT_READER_SETTINGS = "eu.kanade.tachiyomi.READER_SETTINGS" const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS" const val INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH" diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt index 4f6b650186..78dda395c1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate +import eu.kanade.tachiyomi.ui.setting.SettingsReaderController import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.withFadeTransaction @@ -35,7 +36,7 @@ class SearchActivity : MainActivity() { } private fun popToRoot() { - if (intent.action == SHORTCUT_MANGA) { + if (intent.action == SHORTCUT_MANGA || intent.action == SHORTCUT_READER_SETTINGS) { onBackPressed() } else if (!router.handleBack()) { val intent = Intent(this, MainActivity::class.java).apply { @@ -97,6 +98,13 @@ class SearchActivity : MainActivity() { .popChangeHandler(FadeChangeHandler()) ) } + SHORTCUT_READER_SETTINGS -> { + router.replaceTopController( + RouterTransaction.with(SettingsReaderController()) + .pushChangeHandler(SimpleSwapChangeHandler()) + .popChangeHandler(FadeChangeHandler()) + ) + } else -> return false } return true @@ -112,5 +120,14 @@ class SearchActivity : MainActivity() { action = SHORTCUT_MANGA putExtra(MangaDetailsController.MANGA_EXTRA, id) } + + fun openReaderSettings(context: Context) = Intent( + context, + SearchActivity::class + .java + ) + .apply { + action = SHORTCUT_READER_SETTINGS + } } } 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 5debb8e552..f2c65b62db 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 @@ -43,6 +43,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success 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.settings.TabbedReaderSettingsSheet import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer import eu.kanade.tachiyomi.ui.reader.viewer.pager.L2RPagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer @@ -279,21 +280,46 @@ class ReaderActivity : return true } + override fun onPrepareOptionsMenu(menu: Menu?): Boolean { + val detailsItem = menu?.findItem(R.id.action_manga_details) + if (presenter.manga?.mangaType(this) != null) { + detailsItem?.title = getString(R.string._details, + presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: "") + } else { + detailsItem?.title = getString(R.string.details) + } + return super.onPrepareOptionsMenu(menu) + } + /** * Called when an item of the options menu was clicked. Used to handle clicks on our menu * entries. */ override fun onOptionsItemSelected(item: MenuItem): Boolean { coroutine?.cancel() - bottomSheet = when (item.itemId) { - R.id.action_settings -> ReaderSettingsSheet(this) - R.id.action_custom_filter -> ReaderColorFilterSheet(this) + when (item.itemId) { + R.id.action_display_settings -> TabbedReaderSettingsSheet(this).show() + R.id.action_manga_details -> { + presenter.manga?.id?.let { id -> + val intent = SearchActivity.openMangaIntent(this, id) + startActivity(intent) + } + } + R.id.action_share_page, R.id.action_set_page_as_cover, R.id.action_save_page -> { + val currentChapter = presenter.getCurrentChapter() ?: return true + val page = currentChapter.pages?.getOrNull(page_seekbar.progress) ?: return true + when (item.itemId) { + R.id.action_share_page -> shareImage(page) + R.id.action_set_page_as_cover -> showSetCoverPrompt(page) + R.id.action_save_page -> saveImage(page) + } + } + R.id.action_reader_settings -> { + val intent = SearchActivity.openReaderSettings(this) + startActivity(intent) + } else -> return super.onOptionsItemSelected(item) } - bottomSheet?.show() - if (chapters_bottom_sheet.sheetBehavior.isExpanded()) { - chapters_bottom_sheet.sheetBehavior?.collapse() - } return true } @@ -357,13 +383,6 @@ class ReaderActivity : popToMain() } - toolbar.setOnClickListener { - presenter.manga?.id?.let { id -> - val intent = SearchActivity.openMangaIntent(this, id) - startActivity(intent) - } - } - // Init listeners on bottom menu page_seekbar.setOnSeekBarChangeListener( object : SimpleSeekBarListener() { @@ -477,6 +496,7 @@ class ReaderActivity : val prevViewer = viewer val noDefault = manga.viewer == -1 val mangaViewer = presenter.getMangaViewer() + invalidateOptionsMenu() val newViewer = when (mangaViewer) { RIGHT_TO_LEFT -> R2LPagerViewer(this) VERTICAL -> VerticalPagerViewer(this) @@ -615,41 +635,6 @@ class ReaderActivity : page_seekbar.progress = page.index } - /** - * Called from the viewer whenever a [page] is long clicked. A bottom sheet with a list of - * actions to perform is shown. - */ - fun onPageLongTap(page: ReaderPage) { - val items = listOf( - MaterialMenuSheet.MenuSheetItem( - 0, - R.drawable.ic_photo_24dp, - R.string.set_as_cover - ), - MaterialMenuSheet.MenuSheetItem( - 1, - R.drawable.ic_share_24dp, - R.string.share - ), - MaterialMenuSheet.MenuSheetItem( - 2, - R.drawable.ic_save_24dp, - R.string.save - ) - ) - MaterialMenuSheet(this, items) { _, item -> - when (item) { - 0 -> showSetCoverPrompt(page) - 1 -> shareImage(page) - 2 -> saveImage(page) - } - true - }.show() - if (chapters_bottom_sheet.sheetBehavior.isExpanded()) { - chapters_bottom_sheet.sheetBehavior?.collapse() - } - } - /** * Called from the viewer when the given [chapter] should be preloaded. It should be called when * the viewer is reaching the beginning or end of a chapter or the transition page is active. 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 deleted file mode 100644 index ce19647924..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt +++ /dev/null @@ -1,194 +0,0 @@ -package eu.kanade.tachiyomi.ui.reader - -import android.content.res.Configuration -import android.graphics.Color -import android.os.Build -import android.os.Bundle -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Spinner -import androidx.annotation.ArrayRes -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import com.tfcporciuncula.flow.Preference -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer -import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer -import eu.kanade.tachiyomi.util.system.dpToPx -import eu.kanade.tachiyomi.util.system.hasSideNavBar -import eu.kanade.tachiyomi.util.system.isInNightMode -import eu.kanade.tachiyomi.util.view.gone -import eu.kanade.tachiyomi.util.view.setBottomEdge -import eu.kanade.tachiyomi.util.view.setEdgeToEdge -import eu.kanade.tachiyomi.util.view.visible -import eu.kanade.tachiyomi.util.view.visibleIf -import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener -import kotlinx.android.synthetic.main.reader_settings_sheet.* -import uy.kohesive.injekt.injectLazy -import kotlin.math.max - -/** - * Sheet to show reader and viewer preferences. - */ -class ReaderSettingsSheet(private val activity: ReaderActivity) : - BottomSheetDialog(activity, R.style.BottomSheetDialogTheme) { - - /** - * Preferences helper. - */ - private val preferences by injectLazy() - - private var sheetBehavior: BottomSheetBehavior<*> - - init { - // Use activity theme for this layout - val view = activity.layoutInflater.inflate(R.layout.reader_settings_sheet, null) - setContentView(view) - - sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup) - setEdgeToEdge( - activity, - view, - if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) - 0 else -1 - ) - window?.navigationBarColor = Color.TRANSPARENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - !context.isInNightMode() && - !activity.window.decorView.rootWindowInsets.hasSideNavBar() - ) { - window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR - } - - val height = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom - sheetBehavior.peekHeight = 550.dpToPx + height - - sheetBehavior.addBottomSheetCallback( - object : BottomSheetBehavior.BottomSheetCallback() { - override fun onSlide(bottomSheet: View, progress: Float) { - if (progress.isNaN()) - pill.alpha = 0f - else - pill.alpha = (1 - max(0f, progress)) * 0.25f - } - - override fun onStateChanged(p0: View, state: Int) { - if (state == BottomSheetBehavior.STATE_EXPANDED) { - sheetBehavior.skipCollapsed = true - } - } - } - ) - } - - /** - * Called when the sheet is created. It initializes the listeners and values of the preferences. - */ - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - initGeneralPreferences() - - when (val view = activity.viewer) { - is PagerViewer -> initPagerPreferences() - is WebtoonViewer -> initWebtoonPreferences(view.hasMargins) - } - - setBottomEdge(constraint_layout, activity) - - close_button.setOnClickListener { - dismiss() - } - settings_scroll_view.viewTreeObserver.addOnGlobalLayoutListener { - val isScrollable = - settings_scroll_view.height < constraint_layout.height + - settings_scroll_view.paddingTop + settings_scroll_view.paddingBottom - close_button.visibleIf(isScrollable) - pill.visibleIf(!isScrollable) - } - } - - /** - * Init general reader preferences. - */ - private fun initGeneralPreferences() { - viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> - activity.presenter.setMangaViewer(position) - - val mangaViewer = activity.presenter.getMangaViewer() - if (mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS) { - initWebtoonPreferences(mangaViewer == ReaderActivity.VERTICAL_PLUS) - } else { - initPagerPreferences() - } - } - viewer.setSelection(activity.presenter.manga?.viewer ?: 0, false) - - rotation_mode.bindToPreference(preferences.rotation(), 1) - background_color.bindToPreference(preferences.readerTheme(), 0) - show_page_number.bindToPreference(preferences.showPageNumber()) - fullscreen.bindToPreference(preferences.fullscreen()) - keepscreen.bindToPreference(preferences.keepScreenOn()) - always_show_chapter_transition.bindToPreference(preferences.alwaysShowChapterTransition()) - } - - /** - * Init the preferences for the pager reader. - */ - private fun initPagerPreferences() { - pager_prefs_group.visible() - webtoon_prefs_group.gone() - scale_type.bindToPreference(preferences.imageScaleType(), 1) - zoom_start.bindToPreference(preferences.zoomStart(), 1) - crop_borders.bindToPreference(preferences.cropBorders()) - page_transitions.bindToPreference(preferences.pageTransitions()) - } - - /** - * Init the preferences for the webtoon reader. - */ - private fun initWebtoonPreferences(hasMargins: Boolean) { - webtoon_prefs_group.visible() - pager_prefs_group.gone() - crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon()) - webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) - webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut()) - } - - /** - * Binds a checkbox or switch view with a boolean preference. - */ - private fun CompoundButton.bindToPreference(pref: Preference) { - setOnCheckedChangeListener(null) - isChecked = pref.get() - setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) } - } - - /** - * Binds a spinner to an int preference with an optional offset for the value. - */ - private fun Spinner.bindToPreference( - pref: Preference, - offset: Int = 0 - ) { - onItemSelectedListener = IgnoreFirstSpinnerListener { position -> - pref.set(position + offset) - } - setSelection(pref.get() - offset, false) - } - - /** - * Binds a spinner to an int preference. The position of the spinner item must - * correlate with the [intValues] resource item (in arrays.xml), which is a - * of int values that will be parsed here and applied to the preference. - */ - private fun Spinner.bindToIntPreference(pref: Preference, @ArrayRes intValuesResource: Int) { - val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() } - onItemSelectedListener = IgnoreFirstSpinnerListener { position -> - pref.set(intValues[position] ?: 0) - } - setSelection(intValues.indexOf(pref.get()), false) - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/BaseReaderSettingsView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/BaseReaderSettingsView.kt new file mode 100644 index 0000000000..a0bd99060b --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/BaseReaderSettingsView.kt @@ -0,0 +1,25 @@ +package eu.kanade.tachiyomi.ui.reader.settings + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.google.android.material.tabs.TabLayout +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.ui.library.LibraryController +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import uy.kohesive.injekt.injectLazy + +abstract class BaseReaderSettingsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + FrameLayout(context, attrs) { + + internal val preferences by injectLazy() + lateinit var activity: ReaderActivity + + abstract fun initGeneralPreferences() + + override fun onFinishInflate() { + super.onFinishInflate() + initGeneralPreferences() + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderFilterView.kt similarity index 63% rename from app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt rename to app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderFilterView.kt index c8b13807cf..902e7b0382 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderFilterView.kt @@ -1,74 +1,44 @@ -package eu.kanade.tachiyomi.ui.reader +package eu.kanade.tachiyomi.ui.reader.settings -import android.graphics.Color -import android.os.Build -import android.view.View -import android.view.ViewGroup +import android.content.Context +import android.util.AttributeSet import android.widget.SeekBar import androidx.annotation.ColorInt -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.util.system.hasSideNavBar -import eu.kanade.tachiyomi.util.system.isInNightMode -import eu.kanade.tachiyomi.util.view.expand -import eu.kanade.tachiyomi.util.view.gone -import eu.kanade.tachiyomi.util.view.setBottomEdge -import eu.kanade.tachiyomi.util.view.setEdgeToEdge -import eu.kanade.tachiyomi.util.view.visible +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import eu.kanade.tachiyomi.widget.SimpleSeekBarListener import kotlinx.android.synthetic.main.reader_color_filter.* -import kotlinx.android.synthetic.main.reader_color_filter_sheet.* +import kotlinx.android.synthetic.main.reader_color_filter.view.* +import kotlinx.android.synthetic.main.reader_color_filter.view.settings_scroll_view +import kotlinx.android.synthetic.main.reader_general_layout.view.* import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.sample -import uy.kohesive.injekt.injectLazy -import kotlin.math.abs -/** - * Color filter sheet to toggle custom filter and brightness overlay. - */ -class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheetDialog -(activity, R.style.BottomSheetDialogTheme) { - - private val preferences by injectLazy() - - private var sheetBehavior: BottomSheetBehavior<*>? = null - - init { - val view = activity.layoutInflater.inflate(R.layout.reader_color_filter_sheet, null) - setContentView(view) - - setEdgeToEdge(activity, view, 0) - window?.navigationBarColor = Color.TRANSPARENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - !context.isInNightMode() && - !activity.window.decorView.rootWindowInsets.hasSideNavBar() - ) - window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR - setBottomEdge(brightness_seekbar, activity) - - sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup) +class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + BaseReaderSettingsView(context, attrs) { + override fun initGeneralPreferences() { + activity = context as ReaderActivity + settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) preferences.colorFilter().asFlow() - .onEach { setColorFilter(it, view) } + .onEach { setColorFilter(it) } .launchIn(activity.scope) preferences.colorFilterMode().asFlow() - .onEach { setColorFilter(preferences.colorFilter().get(), view) } + .onEach { setColorFilter(preferences.colorFilter().get()) } .launchIn(activity.scope) preferences.customBrightness().asFlow() - .onEach { setCustomBrightness(it, view) } + .onEach { setCustomBrightness(it) } .launchIn(activity.scope) // Get color and update values val color = preferences.colorFilterValue().get() val brightness = preferences.customBrightnessValue().get() - val argb = setValues(color, view) + val argb = setValues(color) // Set brightness value txt_brightness_seekbar_value.text = brightness.toString() @@ -91,14 +61,13 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet preferences.customBrightness().set(isChecked) } - color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> - preferences.colorFilterMode().set(position) - } - color_filter_mode.setSelection(preferences.colorFilterMode().get(), false) - + color_filter_mode.bindToPreference(preferences.colorFilterMode()) seekbar_color_filter_alpha.setOnSeekBarChangeListener( object : SimpleSeekBarListener() { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { + seekbar_color_filter_red.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled + seekbar_color_filter_green.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled + seekbar_color_filter_blue.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled if (fromUser) { setColorValue(value, ALPHA_MASK, 24) } @@ -147,39 +116,31 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet ) } - override fun onStart() { - super.onStart() - sheetBehavior?.skipCollapsed = true - sheetBehavior?.expand() - } /** * Set enabled status of seekBars belonging to color filter * @param enabled determines if seekBar gets enabled - * @param view view of the dialog */ - private fun setColorFilterSeekBar(enabled: Boolean, view: View) = with(view) { - seekbar_color_filter_red.isEnabled = enabled - seekbar_color_filter_green.isEnabled = enabled - seekbar_color_filter_blue.isEnabled = enabled + private fun setColorFilterSeekBar(enabled: Boolean) { + seekbar_color_filter_red.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled + seekbar_color_filter_green.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled + seekbar_color_filter_blue.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled seekbar_color_filter_alpha.isEnabled = enabled } /** * Set enabled status of seekBars belonging to custom brightness * @param enabled value which determines if seekBar gets enabled - * @param view view of the dialog */ - private fun setCustomBrightnessSeekBar(enabled: Boolean, view: View) = with(view) { + private fun setCustomBrightnessSeekBar(enabled: Boolean) { brightness_seekbar.isEnabled = enabled } /** * Set the text value's of color filter * @param color integer containing color information - * @param view view of the dialog */ - fun setValues(color: Int, view: View): Array { + private fun setValues(color: Int): Array { val alpha = getAlphaFromColor(color) val red = getRedFromColor(color) val green = getGreenFromColor(color) @@ -197,18 +158,17 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet /** * Manages the custom brightness value subscription * @param enabled determines if the subscription get (un)subscribed - * @param view view of the dialog */ - private fun setCustomBrightness(enabled: Boolean, view: View) { + private fun setCustomBrightness(enabled: Boolean) { if (enabled) { preferences.customBrightnessValue().asFlow() .sample(100) - .onEach { setCustomBrightnessValue(it, view) } + .onEach { setCustomBrightnessValue(it) } .launchIn(activity.scope) } else { - setCustomBrightnessValue(0, view, true) + setCustomBrightnessValue(0, true) } - setCustomBrightnessSeekBar(enabled, view) + setCustomBrightnessSeekBar(enabled) } /** @@ -217,16 +177,8 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet * From 1 to 100 it sets that value as brightness. * 0 sets system brightness and hides the overlay. */ - private fun setCustomBrightnessValue(value: Int, view: View, isDisabled: Boolean = false) = with(view) { + private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) { // Set black overlay visibility. - if (value < 0) { - brightness_overlay.visible() - val alpha = (abs(value) * 2.56).toInt() - brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0)) - } else { - brightness_overlay.gone() - } - if (!isDisabled) { txt_brightness_seekbar_value.text = value.toString() } @@ -237,27 +189,22 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet * @param enabled determines if the subscription get (un)subscribed * @param view view of the dialog */ - private fun setColorFilter(enabled: Boolean, view: View) { + private fun setColorFilter(enabled: Boolean) { if (enabled) { preferences.colorFilterValue().asFlow() .sample(100) - .onEach { setColorFilterValue(it, view) } + .onEach { setColorFilterValue(it) } .launchIn(activity.scope) - } else { - color_overlay.gone() } - setColorFilterSeekBar(enabled, view) + setColorFilterSeekBar(enabled) } /** * Sets the color filter overlay of the screen. Determined by HEX of integer * @param color hex of color. - * @param view view of the dialog */ - private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) { - color_overlay.visible() - color_overlay.setFilterColor(color, preferences.colorFilterMode().get()) - setValues(color, view) + private fun setColorFilterValue(@ColorInt color: Int) { + setValues(color) } /** @@ -290,15 +237,6 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet return color shr 16 and 0xFF } - /** - * Returns the green value from the Color Hex - * @param color color hex as int - * @return green of color - */ - fun getGreenFromColor(color: Int): Int { - return color shr 8 and 0xFF - } - /** * Returns the blue value from the Color Hex * @param color color hex as int @@ -322,3 +260,12 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet const val BLUE_MASK: Long = 0x000000FF } } + +/** + * Returns the green value from the Color Hex + * @param color color hex as int + * @return green of color + */ +fun ReaderFilterView.getGreenFromColor(color: Int): Int { + return color shr 8 and 0xFF +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderGeneralView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderGeneralView.kt new file mode 100644 index 0000000000..3db90555e4 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderGeneralView.kt @@ -0,0 +1,46 @@ +package eu.kanade.tachiyomi.ui.reader.settings + +import android.content.Context +import android.util.AttributeSet +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.bindToPreference +import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener +import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener +import kotlinx.android.synthetic.main.reader_general_layout.view.* + +class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + BaseReaderSettingsView(context, attrs) { + + lateinit var sheet: TabbedReaderSettingsSheet + override fun initGeneralPreferences() { + settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) + viewer_series.onItemSelectedListener = { position -> + activity.presenter.setMangaViewer(position) + + val mangaViewer = activity.presenter.getMangaViewer() + if (mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS) { + initWebtoonPreferences() + } else { + initPagerPreferences() + } + } + viewer_series.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0) + rotation_mode.bindToPreference(preferences.rotation(), 1) + background_color.bindToPreference(preferences.readerTheme(), 0) + show_page_number.bindToPreference(preferences.showPageNumber()) + fullscreen.bindToPreference(preferences.fullscreen()) + keepscreen.bindToPreference(preferences.keepScreenOn()) + always_show_chapter_transition.bindToPreference(preferences.alwaysShowChapterTransition()) + } + + /** + * Init the preferences for the webtoon reader. + */ + private fun initWebtoonPreferences() { + sheet.updateTabs(true) + } + + private fun initPagerPreferences() { + sheet.updateTabs(false) + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPagedView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPagedView.kt new file mode 100644 index 0000000000..df82b91950 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPagedView.kt @@ -0,0 +1,49 @@ +package eu.kanade.tachiyomi.ui.reader.settings + +import android.content.Context +import android.util.AttributeSet +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.bindToIntPreference +import eu.kanade.tachiyomi.util.bindToPreference +import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener +import eu.kanade.tachiyomi.util.view.visibleIf +import kotlinx.android.synthetic.main.reader_paged_layout.view.* +import kotlinx.android.synthetic.main.reader_paged_layout.view.crop_borders_webtoon +import kotlinx.android.synthetic.main.reader_paged_layout.view.settings_scroll_view +import kotlinx.android.synthetic.main.reader_paged_layout.view.webtoon_enable_zoom_out +import kotlinx.android.synthetic.main.reader_paged_layout.view.webtoon_side_padding + +class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + BaseReaderSettingsView(context, attrs) { + + override fun initGeneralPreferences() { + scale_type.bindToPreference(preferences.imageScaleType(), 1) + zoom_start.bindToPreference(preferences.zoomStart(), 1) + crop_borders.bindToPreference(preferences.cropBorders()) + page_transitions.bindToPreference(preferences.pageTransitions()) + + settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) + val mangaViewer = (context as ReaderActivity).presenter.getMangaViewer() + val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS + val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS + crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon()) + webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) + webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut()) + + updatePagedGroup(!isWebtoonView) + } + + fun updatePrefs() { + val mangaViewer = activity.presenter.getMangaViewer() + val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS + val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS + crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon()) + updatePagedGroup(!isWebtoonView) + } + + fun updatePagedGroup(show: Boolean) { + listOf(scale_type, zoom_start, crop_borders, page_transitions).forEach { it.visibleIf(show) } + listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out).forEach { it.visibleIf(!show) } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPreferenceView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPreferenceView.kt new file mode 100644 index 0000000000..de7b413100 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/ReaderPreferenceView.kt @@ -0,0 +1,134 @@ +package eu.kanade.tachiyomi.ui.reader.settings + +import android.content.Context +import android.util.AttributeSet +import android.view.Gravity +import android.view.MenuItem +import android.widget.FrameLayout +import androidx.annotation.ArrayRes +import androidx.appcompat.widget.PopupMenu +import androidx.core.view.get +import com.tfcporciuncula.flow.Preference +import eu.kanade.tachiyomi.R +import kotlinx.android.synthetic.main.reader_preference.view.* + + +class ReaderPreferenceView @JvmOverloads constructor(context: Context, attrs: AttributeSet?) : + FrameLayout(context, attrs) { + + + private var entries = emptyList() + private var selectedPosition = 0 + private var pref: Preference? = null + private var prefOffset = 0 + var onItemSelectedListener: ((Int) -> Unit)? = null + set(value) { + field = value + if (value != null) { + val popup = makeSettingsPopup() + setOnTouchListener(popup.dragToOpenListener) + setOnClickListener { + popup.show() + } + } + } + + init { + inflate(context, R.layout.reader_preference, this) + val a = context.obtainStyledAttributes(attrs, R.styleable.ReaderPreferenceView, 0, 0) + + val str = a.getString(R.styleable.ReaderPreferenceView_title) ?: "" + title_view.text = str + + val entries = (a.getTextArray(R.styleable.ReaderPreferenceView_android_entries) ?: emptyArray()).map { it.toString() } + this.entries = entries + + detail_view.text = entries.firstOrNull().orEmpty() + + a.recycle() + } + + fun setSelection(selection: Int) { + selectedPosition = selection + detail_view.text = entries.getOrNull(selection).orEmpty() + } + + fun bindToPreference(pref: Preference, offset: Int = 0, block: ((Int) -> Unit)? = null) { + setSelection(pref.get() - offset) + this.pref = pref + prefOffset = offset + val popup = makeSettingsPopup(pref, prefOffset, block) + setOnTouchListener(popup.dragToOpenListener) + setOnClickListener { + popup.show() + } + } + + fun bindToIntPreference(pref: Preference, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) { + setSelection(pref.get()) + this.pref = pref + prefOffset = 0 + val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() } + val popup = makeSettingsPopup(pref, intValues, block) + setOnTouchListener(popup.dragToOpenListener) + setOnClickListener { + popup.show() + } + } + + private fun makeSettingsPopup(preference: Preference, intValues: List, block: ((Int) -> Unit)? = null): PopupMenu { + val popup = popup() + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { menuItem -> + val pos = popup.menuClicked(menuItem) + preference.set(intValues[pos] ?: 0) + block?.invoke(pos) + true + } + return popup + } + + private fun makeSettingsPopup(preference: Preference, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu { + val popup = popup() + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { menuItem -> + val pos = popup.menuClicked(menuItem) + preference.set(pos + offset) + block?.invoke(pos) + true + } + return popup + } + + private fun makeSettingsPopup(): PopupMenu { + val popup = popup() + + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { menuItem -> + val pos = popup.menuClicked(menuItem) + onItemSelectedListener?.invoke(pos) + true + } + return popup + } + + private fun PopupMenu.menuClicked(menuItem: MenuItem): Int { + val pos = menuItem.itemId + menu[selectedPosition].isCheckable = false + menu[selectedPosition].isChecked = false + setSelection(pos) + menu[pos].isCheckable = true + menu[pos].isChecked = true + return pos + } + + private fun popup(): PopupMenu { + val popup = PopupMenu(context, this, Gravity.END) + entries.forEachIndexed { index, entry -> + popup.menu.add(0, index, 0, entry) + } + popup.menu[selectedPosition].isCheckable = true + popup.menu[selectedPosition].isChecked = true + return popup + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/TabbedReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/TabbedReaderSettingsSheet.kt new file mode 100644 index 0000000000..6405775075 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/settings/TabbedReaderSettingsSheet.kt @@ -0,0 +1,99 @@ +package eu.kanade.tachiyomi.ui.reader.settings + +import android.view.View +import com.google.android.material.tabs.TabLayout +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.ui.library.display.LibraryBadgesView +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.view.gone +import eu.kanade.tachiyomi.util.view.visInvisIf +import eu.kanade.tachiyomi.util.view.visible +import eu.kanade.tachiyomi.util.view.visibleIf +import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog +import kotlinx.android.synthetic.main.reader_activity.* +import kotlinx.android.synthetic.main.reader_color_filter.view.* +import kotlinx.android.synthetic.main.recycler_with_scroller.view.* +import kotlinx.android.synthetic.main.tabbed_bottom_sheet.* + +class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity): TabbedBottomSheetDialog( + readerActivity +) { + private val generalView: ReaderGeneralView = View.inflate( + readerActivity, + R.layout.reader_general_layout, + null + ) as ReaderGeneralView + private val pagedView: ReaderPagedView = View.inflate( + readerActivity, + R.layout.reader_paged_layout, + null + ) as ReaderPagedView + private val filterView: ReaderFilterView = View.inflate( + readerActivity, + R.layout.reader_color_filter, + null + ) as ReaderFilterView + + var showWebview: Boolean = { + val mangaViewer = readerActivity.presenter.getMangaViewer() + mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS + }() + + override var offset = 0 + + override fun getTabViews(): List = listOf( + generalView, + pagedView, + filterView + ) + + override fun getTabTitles(): List = listOf( + R.string.general, + if (showWebview) R.string.webtoon else R.string.paged, + R.string.filter + ) + + init { + generalView.activity = readerActivity + pagedView.activity = readerActivity + filterView.activity = readerActivity + generalView.sheet = this + + menu.gone() + val attrs = window?.attributes + val ogDim = attrs?.dimAmount ?: 0.25f + pager.adapter?.notifyDataSetChanged() + tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab?) { + window?.setDimAmount(if (tab?.position == 2) 0f else ogDim) + val view = getTabViews()[tab?.position ?: 0] + view.settings_scroll_view?.isNestedScrollingEnabled = true + view.settings_scroll_view?.requestLayout() + readerActivity.appbar.visInvisIf(tab?.position != 2) + } + + override fun onTabUnselected(tab: TabLayout.Tab?) { + val view = getTabViews()[tab?.position ?: 0] + view.settings_scroll_view?.isNestedScrollingEnabled = false + view.settings_scroll_view?.requestLayout() + } + + override fun onTabReselected(tab: TabLayout.Tab?) { + val view = getTabViews()[tab?.position ?: 0] + view.settings_scroll_view?.isNestedScrollingEnabled = true + view.settings_scroll_view?.requestLayout() + } + }) + } + + override fun dismiss() { + super.dismiss() + readerActivity.appbar.visible() + } + + fun updateTabs(isWebtoon: Boolean) { + showWebview = isWebtoon + pager.adapter?.notifyDataSetChanged() + pagedView.updatePrefs() + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt index fab2958314..1aeef22345 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt @@ -18,7 +18,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { var imagePropertyChangedListener: (() -> Unit)? = null var tappingEnabled = true - var longTapEnabled = true var doubleTapAnimDuration = 500 var volumeKeysEnabled = false var volumeKeysInverted = false @@ -28,9 +27,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { preferences.readWithTapping() .register({ tappingEnabled = it }) - preferences.readWithLongTap() - .register({ longTapEnabled = it }) - preferences.doubleTapAnimSpeed() .register({ doubleTapAnimDuration = it }) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index 545e7e04cc..36e48b0b21 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 @@ -89,16 +89,6 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer { else -> activity.toggleMenu() } } - pager.longTapListener = f@{ - if (activity.menuVisible || config.longTapEnabled) { - val item = adapter.items.getOrNull(pager.currentItem) - if (item is ReaderPage) { - activity.onPageLongTap(item) - return@f true - } - } - false - } config.imagePropertyChangedListener = { refreshAdapter() 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 5ad24913cb..fc380cbab9 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 @@ -106,20 +106,6 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals else -> activity.toggleMenu() } } - recycler.longTapListener = f@{ event -> - if (activity.menuVisible || config.longTapEnabled) { - val child = recycler.findChildViewUnder(event.x, event.y) - 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 - } config.imagePropertyChangedListener = { refreshAdapter() 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 d6a97b88b7..46a4eee4ef 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 @@ -188,11 +188,6 @@ class SettingsReaderController : SettingsController() { titleRes = R.string.tapping defaultValue = true } - switchPreference { - key = Keys.readWithLongTap - titleRes = R.string.long_tap_dialog - defaultValue = true - } switchPreference { key = Keys.readWithVolumeKeys titleRes = R.string.volume_keys diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/PreferenceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/PreferenceExtensions.kt index 0148d0b1cd..515c55ae7f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/PreferenceExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/PreferenceExtensions.kt @@ -1,6 +1,15 @@ package eu.kanade.tachiyomi.util import android.content.SharedPreferences +import android.widget.CompoundButton +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.Spinner +import androidx.annotation.ArrayRes +import androidx.appcompat.widget.AppCompatSpinner +import com.f2prateek.rx.preferences.Preference +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose @@ -40,3 +49,68 @@ inline fun SharedPreferences.getItem(key: String, default: T): T { else -> throw IllegalArgumentException("Generic type not handled: ${T::class.java.name}") } } + + +/** + * Binds a checkbox or switch view with a boolean preference. + */ +fun CompoundButton.bindToPreference(pref: Preference, block: (() -> Unit)? = null) { + isChecked = pref.getOrDefault() + setOnCheckedChangeListener { _, isChecked -> + pref.set(isChecked) + block?.invoke() + } +} + +/** + * Binds a checkbox or switch view with a boolean preference. + */ +fun CompoundButton.bindToPreference( + pref: com.tfcporciuncula.flow + .Preference, + block: ((Boolean) -> Unit)? = null +) { + isChecked = pref.get() + setOnCheckedChangeListener { _, isChecked -> + pref.set(isChecked) + block?.invoke(isChecked) + } +} + +/** + * Binds a radio group with a int preference. + */ +fun RadioGroup.bindToPreference(pref: Preference, block: (() -> Unit)? = null) { + (getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true + setOnCheckedChangeListener { _, checkedId -> + val index = indexOfChild(findViewById(checkedId)) + pref.set(index) + block?.invoke() + } +} + +/** + * Binds a spinner to an int preference with an optional offset for the value. + */ +fun Spinner.bindToPreference( + pref: com.tfcporciuncula.flow.Preference, + offset: Int = 0 +) { + onItemSelectedListener = IgnoreFirstSpinnerListener { position -> + pref.set(position + offset) + } + setSelection(pref.get() - offset, false) +} + +/** + * Binds a spinner to an int preference. The position of the spinner item must + * correlate with the [intValues] resource item (in arrays.xml), which is a + * of int values that will be parsed here and applied to the preference. + */ +fun Spinner.bindToIntPreference(pref: com.tfcporciuncula.flow.Preference, @ArrayRes intValuesResource: Int) { + val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() } + onItemSelectedListener = IgnoreFirstSpinnerListener { position -> + pref.set(intValues[position] ?: 0) + } + setSelection(intValues.indexOf(pref.get()), false) +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/TabbedBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/TabbedBottomSheet.kt index 3534055cb5..f71087ca51 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/TabbedBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/TabbedBottomSheet.kt @@ -1,27 +1,32 @@ package eu.kanade.tachiyomi.widget +import android.app.Activity import android.content.Context import android.util.AttributeSet +import android.view.Gravity import android.view.View import android.view.ViewGroup +import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.viewpager.widget.ViewPager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.ui.base.controller.BaseController +import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.view.expand import eu.kanade.tachiyomi.util.view.setEdgeToEdge +import eu.kanade.tachiyomi.util.view.updateLayoutParams +import kotlinx.android.synthetic.main.library_list_controller.* import kotlinx.android.synthetic.main.tabbed_bottom_sheet.* -abstract class TabbedBottomSheetDialog(private val controller: BaseController) : +abstract class TabbedBottomSheetDialog(private val activity: Activity) : BottomSheetDialog - (controller.activity!!, R.style.BottomSheetDialogTheme) { + (activity, R.style.BottomSheetDialogTheme) { private var sheetBehavior: BottomSheetBehavior<*> - val activity = controller.activity!! - + open var offset = -1 init { // Use activity theme for this layout val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null) @@ -29,7 +34,9 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) : setContentView(view) sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup) setEdgeToEdge(activity, view) - val height = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom + + val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop + pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx val adapter = TabbedSheetAdapter() pager.offscreenPageLimit = 2 @@ -41,6 +48,7 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) : super.onStart() sheetBehavior.skipCollapsed = true sheetBehavior.expand() + val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop } abstract fun getTabViews(): List @@ -64,6 +72,13 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) : } class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null): ViewPager(context, attrs) { + + var maxHeight = 0 + set(value) { + field = value + requestLayout() + } + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { var heightMeasureSpec = heightMeasureSpec super.onMeasure(widthMeasureSpec, heightMeasureSpec) @@ -84,6 +99,9 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri if (height != 0) { heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) + (rootWindowInsets?.systemWindowInsetBottom ?: 0) } + if (maxHeight < height) { + heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST) + (rootWindowInsets?.systemWindowInsetBottom ?: 0) + } super.onMeasure(widthMeasureSpec, heightMeasureSpec) } } \ No newline at end of file diff --git a/app/src/main/res/drawable/filter_mock.webp b/app/src/main/res/drawable/filter_mock.webp deleted file mode 100644 index c65b390cb6d82fafe8cede665a0f4e096554f450..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77344 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 yH~aPE=p;f6fb-l323NcbX)}DK=PbVmm<~ + android:viewportHeight="24.0" + android:tint="?attr/actionBarTintColor"> diff --git a/app/src/main/res/layout-land/reader_color_filter_sheet.xml b/app/src/main/res/layout-land/reader_color_filter_sheet.xml deleted file mode 100644 index 6df89dc7c6..0000000000 --- a/app/src/main/res/layout-land/reader_color_filter_sheet.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/reader_color_filter.xml b/app/src/main/res/layout/reader_color_filter.xml index 9aa2015202..8356768432 100644 --- a/app/src/main/res/layout/reader_color_filter.xml +++ b/app/src/main/res/layout/reader_color_filter.xml @@ -1,236 +1,245 @@ - + android:background="@drawable/bottom_sheet_rounded_background" + android:forceDarkAllowed="false"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:clipToPadding="false" + android:layout_height="wrap_content"> - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/reader_color_filter_sheet.xml b/app/src/main/res/layout/reader_color_filter_sheet.xml deleted file mode 100644 index f6c40f06d4..0000000000 --- a/app/src/main/res/layout/reader_color_filter_sheet.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/reader_general_layout.xml b/app/src/main/res/layout/reader_general_layout.xml new file mode 100644 index 0000000000..1e881e505e --- /dev/null +++ b/app/src/main/res/layout/reader_general_layout.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/reader_paged_layout.xml b/app/src/main/res/layout/reader_paged_layout.xml new file mode 100644 index 0000000000..3ff7e29e98 --- /dev/null +++ b/app/src/main/res/layout/reader_paged_layout.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/reader_preference.xml b/app/src/main/res/layout/reader_preference.xml new file mode 100644 index 0000000000..642cede686 --- /dev/null +++ b/app/src/main/res/layout/reader_preference.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/reader_settings_sheet.xml b/app/src/main/res/layout/reader_settings_sheet.xml deleted file mode 100644 index b48c8a27af..0000000000 --- a/app/src/main/res/layout/reader_settings_sheet.xml +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/reader.xml b/app/src/main/res/menu/reader.xml index b011162b48..5763d837c2 100644 --- a/app/src/main/res/menu/reader.xml +++ b/app/src/main/res/menu/reader.xml @@ -1,18 +1,42 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + + + + + + + + + + android:title="@string/reader_settings" + app:showAsAction="never" /> diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 8b7fbbe1e2..6bd1e44d86 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -15,4 +15,10 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 08970908f1..e701e10847 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -278,6 +278,11 @@ Custom filter Set as cover + Set page as cover + Share page + Save page + %1$s details + Reader settings Set as default for all Cover updated Page %1$d