From 6953ca21a9ff672ace2d0c59d63c9b80299c3f62 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 3 Mar 2020 18:57:37 +0200 Subject: [PATCH] Reader settings --- app/src/main/AndroidManifest.xml | 5 +- .../kotatsu/core/prefs/AppSettings.kt | 16 +++- .../kotatsu/ui/reader/ReaderActivity.kt | 85 +++++++++++++++++-- .../ui/reader/SimpleSettingsActivity.kt | 35 ++++++++ .../ui/settings/ReaderSettingsFragment.kt | 17 ++++ .../ui/settings/utils/MultiSummaryProvider.kt | 20 +++++ .../delegates/prefs/BoolPreferenceDelegate.kt | 20 +++++ .../prefs/StringSetPreferenceDelegate.kt | 20 +++++ app/src/main/res/drawable/ic_book.xml | 12 +++ app/src/main/res/drawable/ic_information.xml | 8 ++ .../res/layout/activity_settings_simple.xml | 31 +++++++ app/src/main/res/menu/opt_reader_bottom.xml | 18 ++-- app/src/main/res/values-ru/strings.xml | 4 + app/src/main/res/values/arrays.xml | 14 +-- app/src/main/res/values/constants.xml | 8 ++ app/src/main/res/values/strings.xml | 4 + app/src/main/res/xml/pref_headers.xml | 5 ++ app/src/main/res/xml/pref_reader.xml | 14 +++ 18 files changed, 313 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/BoolPreferenceDelegate.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt create mode 100644 app/src/main/res/drawable/ic_book.xml create mode 100644 app/src/main/res/drawable/ic_information.xml create mode 100644 app/src/main/res/layout/activity_settings_simple.xml create mode 100644 app/src/main/res/xml/pref_reader.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f32d33b16..f81dfa912 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,7 +27,7 @@ android:name="android.app.default_searchable" android:value=".ui.search.SearchActivity" /> - + @@ -39,6 +39,9 @@ + diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 071526599..b3ac18313 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -6,10 +6,7 @@ import android.content.res.Resources import androidx.appcompat.app.AppCompatDelegate import androidx.preference.PreferenceManager import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.utils.delegates.prefs.EnumPreferenceDelegate -import org.koitharu.kotatsu.utils.delegates.prefs.IntPreferenceDelegate -import org.koitharu.kotatsu.utils.delegates.prefs.NullableStringPreferenceDelegate -import org.koitharu.kotatsu.utils.delegates.prefs.StringIntPreferenceDelegate +import org.koitharu.kotatsu.utils.delegates.prefs.* class AppSettings private constructor(resources: Resources, private val prefs: SharedPreferences) : SharedPreferences by prefs { @@ -35,6 +32,11 @@ class AppSettings private constructor(resources: Resources, private val prefs: S 100 ) + val readerPageSwitch by StringSetPreferenceDelegate( + resources.getString(R.string.key_reader_switchers), + setOf(PAGE_SWITCH_TAPS) + ) + private var sourcesOrderStr by NullableStringPreferenceDelegate(resources.getString(R.string.key_sources_order)) var sourcesOrder: List @@ -50,4 +52,10 @@ class AppSettings private constructor(resources: Resources, private val prefs: S fun unsubscribe(listener: SharedPreferences.OnSharedPreferenceChangeListener) { prefs.unregisterOnSharedPreferenceChangeListener(listener) } + + companion object { + + const val PAGE_SWITCH_TAPS = "taps" + const val PAGE_SWITCH_VOLUME_KEYS = "volume" + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt index 01dca2283..2b1ffd889 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt @@ -3,12 +3,10 @@ package org.koitharu.kotatsu.ui.reader import android.Manifest import android.content.Context import android.content.Intent +import android.content.SharedPreferences import android.net.Uri import android.os.Bundle -import android.view.Gravity -import android.view.Menu -import android.view.MenuItem -import android.view.MotionEvent +import android.view.* import android.widget.Toast import androidx.core.view.isVisible import androidx.core.view.updatePadding @@ -17,11 +15,13 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_reader.* import moxy.MvpDelegate import moxy.ktx.moxyPresenter +import org.koin.core.inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.ui.common.BaseFullscreenActivity import org.koitharu.kotatsu.ui.reader.standard.StandardReaderFragment @@ -35,14 +35,17 @@ import org.koitharu.kotatsu.utils.ext.* class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnChapterChangeListener, GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback, - ReaderListener { + ReaderListener, SharedPreferences.OnSharedPreferenceChangeListener { private val presenter by moxyPresenter(factory = ReaderPresenter.Companion::getInstance) + private val settings by inject() lateinit var state: ReaderState private set private lateinit var touchHelper: GridTouchHelper + private var isTapSwitchEnabled = true + private var isVolumeKeysSwitchEnabled = false private val reader get() = supportFragmentManager.findFragmentById(R.id.container) as? BaseReaderFragment @@ -74,6 +77,9 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh insets } + settings.subscribe(this) + loadSettings() + if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { presenter.loadChapter(state.manga, state.chapterId, ReaderAction.REPLACE) } @@ -95,6 +101,11 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh super.onPause() } + override fun onDestroy() { + settings.unsubscribe(this) + super.onDestroy() + } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.opt_reader_top, menu) return super.onCreateOptionsMenu(menu) @@ -106,7 +117,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh } override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { - R.id.action_settings -> { + R.id.action_reader_mode -> { ReaderConfigDialog.show( supportFragmentManager, when (reader) { is StandardReaderFragment -> ReaderMode.STANDARD @@ -116,6 +127,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh ) true } + R.id.action_settings -> { + startActivity(SimpleSettingsActivity.newReaderSettingsIntent(this)) + true + } R.id.action_chapters -> { ChaptersDialog.show( supportFragmentManager, @@ -183,11 +198,11 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh setUiIsVisible(!appbar_top.isVisible) } GridTouchHelper.AREA_TOP, - GridTouchHelper.AREA_LEFT -> { + GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) { reader?.switchPageBy(-1) } GridTouchHelper.AREA_BOTTOM, - GridTouchHelper.AREA_RIGHT -> { + GridTouchHelper.AREA_RIGHT -> if (isTapSwitchEnabled) { reader?.switchPageBy(1) } } @@ -209,6 +224,45 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh return super.dispatchTouchEvent(ev) } + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean = when (keyCode) { + KeyEvent.KEYCODE_VOLUME_UP -> if (isVolumeKeysSwitchEnabled) { + reader?.switchPageBy(-1) + true + } else { + super.onKeyDown(keyCode, event) + } + KeyEvent.KEYCODE_VOLUME_DOWN -> if (isVolumeKeysSwitchEnabled) { + reader?.switchPageBy(1) + true + } else { + super.onKeyDown(keyCode, event) + } + KeyEvent.KEYCODE_SPACE, + KeyEvent.KEYCODE_PAGE_DOWN, + KeyEvent.KEYCODE_DPAD_DOWN, + KeyEvent.KEYCODE_DPAD_RIGHT -> { + reader?.switchPageBy(1) + true + } + KeyEvent.KEYCODE_PAGE_UP, + KeyEvent.KEYCODE_DPAD_UP, + KeyEvent.KEYCODE_DPAD_LEFT -> { + reader?.switchPageBy(-1) + true + } + KeyEvent.KEYCODE_DPAD_CENTER -> { + setUiIsVisible(!appbar_top.isVisible) + true + } + else -> super.onKeyDown(keyCode, event) + } + + override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { + return (isVolumeKeysSwitchEnabled && + (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) + || super.onKeyUp(keyCode, event) + } + override fun onChapterChanged(chapter: MangaChapter) { state = state.copy( chapterId = chapter.id, @@ -262,6 +316,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh } } + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + loadSettings() + } + private fun showWaitWhileLoading() { Toast.makeText(this, R.string.wait_for_loading_finish, Toast.LENGTH_SHORT).apply { setGravity(Gravity.CENTER, 0, 0) @@ -296,6 +354,17 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh } } } + toolbar_bottom.menu.findItem(R.id.action_reader_mode).setIcon(when(mode) { + ReaderMode.WEBTOON -> R.drawable.ic_script + else -> R.drawable.ic_book_page + }) + } + + private fun loadSettings() { + settings.readerPageSwitch.let { + isTapSwitchEnabled = it.contains(AppSettings.PAGE_SWITCH_TAPS) + isVolumeKeysSwitchEnabled = it.contains(AppSettings.PAGE_SWITCH_VOLUME_KEYS) + } } companion object { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt new file mode 100644 index 000000000..756b36ffa --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt @@ -0,0 +1,35 @@ +package org.koitharu.kotatsu.ui.reader + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.commit +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.ui.common.BaseActivity +import org.koitharu.kotatsu.ui.settings.ReaderSettingsFragment +import org.koitharu.kotatsu.ui.settings.SettingsHeadersFragment + +class SimpleSettingsActivity : BaseActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_settings_simple) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + val section = intent?.getIntExtra(EXTRA_SECTION, 0) + supportFragmentManager.commit { + replace(R.id.container, when(section) { + SECTION_READER -> ReaderSettingsFragment() + else -> SettingsHeadersFragment() + }) + } + } + + companion object { + + private const val EXTRA_SECTION = "section" + private const val SECTION_READER = 1 + + fun newReaderSettingsIntent(context: Context) = Intent(context, SimpleSettingsActivity::class.java) + .putExtra(EXTRA_SECTION, SECTION_READER) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt new file mode 100644 index 000000000..db8a7a58c --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.ui.settings + +import android.os.Bundle +import androidx.preference.MultiSelectListPreference +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.ui.common.BasePreferenceFragment +import org.koitharu.kotatsu.ui.settings.utils.MultiSummaryProvider + +class ReaderSettingsFragment : BasePreferenceFragment(R.string.reader_settings) { + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.pref_reader) + findPreference(R.string.key_reader_switchers)?.let { + it.summaryProvider = MultiSummaryProvider() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt new file mode 100644 index 000000000..02f23f312 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt @@ -0,0 +1,20 @@ +package org.koitharu.kotatsu.ui.settings.utils + +import android.annotation.SuppressLint +import androidx.preference.MultiSelectListPreference +import androidx.preference.Preference + +class MultiSummaryProvider : Preference.SummaryProvider { + + @SuppressLint("PrivateResource") + override fun provideSummary(preference: MultiSelectListPreference): CharSequence { + val values = preference.values + return if (values.isEmpty()) { + return preference.context.getString(androidx.preference.R.string.not_set) + } else { + values.joinToString(", ") { + preference.entries[preference.findIndexOfValue(it)] + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/BoolPreferenceDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/BoolPreferenceDelegate.kt new file mode 100644 index 000000000..a8b6fe28e --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/BoolPreferenceDelegate.kt @@ -0,0 +1,20 @@ +package org.koitharu.kotatsu.utils.delegates.prefs + +import android.content.SharedPreferences +import androidx.core.content.edit +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +class BoolPreferenceDelegate(private val key: String, private val defValue: Boolean) : + ReadWriteProperty { + + override fun getValue(thisRef: SharedPreferences, property: KProperty<*>): Boolean { + return thisRef.getBoolean(key, defValue) + } + + override fun setValue(thisRef: SharedPreferences, property: KProperty<*>, value: Boolean) { + thisRef.edit { + putBoolean(key, value) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt new file mode 100644 index 000000000..df4af5aca --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt @@ -0,0 +1,20 @@ +package org.koitharu.kotatsu.utils.delegates.prefs + +import android.content.SharedPreferences +import androidx.core.content.edit +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +class StringSetPreferenceDelegate(private val key: String, private val defValue: Set) : + ReadWriteProperty> { + + override fun getValue(thisRef: SharedPreferences, property: KProperty<*>): Set { + return thisRef.getStringSet(key, defValue) ?: defValue + } + + override fun setValue(thisRef: SharedPreferences, property: KProperty<*>, value: Set) { + thisRef.edit { + putStringSet(key, value) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_book.xml b/app/src/main/res/drawable/ic_book.xml new file mode 100644 index 000000000..78b11ace7 --- /dev/null +++ b/app/src/main/res/drawable/ic_book.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_information.xml b/app/src/main/res/drawable/ic_information.xml new file mode 100644 index 000000000..8364044a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_information.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings_simple.xml b/app/src/main/res/layout/activity_settings_simple.xml new file mode 100644 index 000000000..ba7653fa9 --- /dev/null +++ b/app/src/main/res/layout/activity_settings_simple.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/opt_reader_bottom.xml b/app/src/main/res/menu/opt_reader_bottom.xml index 4f3d6f586..b8f4beb24 100644 --- a/app/src/main/res/menu/opt_reader_bottom.xml +++ b/app/src/main/res/menu/opt_reader_bottom.xml @@ -1,31 +1,39 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + tools:ignore="AlwaysShowAction"> + app:showAsAction="always" /> + app:showAsAction="always" /> + app:showAsAction="always" /> + + + app:showAsAction="always" /> \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ce69d55c9..49588af8a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -86,4 +86,8 @@ Результаты поиска по %s Удалить мангу Вы уверены, что хотите удалить \"%s\" с устройства? \nЭто действие нельзя будет отменить. + Настройки чтения + Листание страниц + Нажатия по краям + Кнопки громкости \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index d74093503..3b66255b6 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,8 +1,12 @@ - - @string/automatic - @string/light - @string/dark - + + @string/automatic + @string/light + @string/dark + + + @string/taps_on_edges + @string/volume_buttons + \ No newline at end of file diff --git a/app/src/main/res/values/constants.xml b/app/src/main/res/values/constants.xml index 7137d4688..458e2f298 100644 --- a/app/src/main/res/values/constants.xml +++ b/app/src/main/res/values/constants.xml @@ -5,9 +5,17 @@ sources_order pages_cache_clear grid_size + reader_switchers -1 1 2 + + taps + volume + + + taps + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74d79538c..9fed4ea23 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -87,4 +87,8 @@ Search results on %s Delete manga Are you really want to delete \"%s\" from your phone\'s local storage? \nThis operation cannot be undone. + Reader settings + Switch pages + Taps on edges + Volume buttons \ No newline at end of file diff --git a/app/src/main/res/xml/pref_headers.xml b/app/src/main/res/xml/pref_headers.xml index ec0c46027..a71f6ece5 100644 --- a/app/src/main/res/xml/pref_headers.xml +++ b/app/src/main/res/xml/pref_headers.xml @@ -12,6 +12,11 @@ android:icon="@drawable/ic_web" android:title="@string/remote_sources" /> + + + + + + + \ No newline at end of file