Reader control direction depends on mode #214
This commit is contained in:
@@ -65,6 +65,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
|||||||
val readerPageSwitch: Set<String>
|
val readerPageSwitch: Set<String>
|
||||||
get() = prefs.getStringSet(KEY_READER_SWITCHERS, null) ?: setOf(PAGE_SWITCH_TAPS)
|
get() = prefs.getStringSet(KEY_READER_SWITCHERS, null) ?: setOf(PAGE_SWITCH_TAPS)
|
||||||
|
|
||||||
|
val isReaderTapsAdaptive: Boolean
|
||||||
|
get() = !prefs.getBoolean(KEY_READER_TAPS_LTR, false)
|
||||||
|
|
||||||
var isTrafficWarningEnabled: Boolean
|
var isTrafficWarningEnabled: Boolean
|
||||||
get() = prefs.getBoolean(KEY_TRAFFIC_WARNING, true)
|
get() = prefs.getBoolean(KEY_TRAFFIC_WARNING, true)
|
||||||
set(value) = prefs.edit { putBoolean(KEY_TRAFFIC_WARNING, value) }
|
set(value) = prefs.edit { putBoolean(KEY_TRAFFIC_WARNING, value) }
|
||||||
@@ -321,6 +324,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
|||||||
const val KEY_SYNC = "sync"
|
const val KEY_SYNC = "sync"
|
||||||
const val KEY_READER_BAR = "reader_bar"
|
const val KEY_READER_BAR = "reader_bar"
|
||||||
const val KEY_SHORTCUTS = "dynamic_shortcuts"
|
const val KEY_SHORTCUTS = "dynamic_shortcuts"
|
||||||
|
const val KEY_READER_TAPS_LTR = "reader_taps_ltr"
|
||||||
|
|
||||||
// About
|
// About
|
||||||
const val KEY_APP_UPDATE = "app_update"
|
const val KEY_APP_UPDATE = "app_update"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import org.acra.dialog.CrashReportDialog
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -14,7 +15,7 @@ class AppProtectHelper @Inject constructor(private val settings: AppSettings) :
|
|||||||
private var isUnlocked = settings.appPassword.isNullOrEmpty()
|
private var isUnlocked = settings.appPassword.isNullOrEmpty()
|
||||||
|
|
||||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||||
if (activity !is ProtectActivity && !isUnlocked) {
|
if (!isUnlocked && activity !is ProtectActivity && activity !is CrashReportDialog) {
|
||||||
val sourceIntent = Intent(activity, activity.javaClass)
|
val sourceIntent = Intent(activity, activity.javaClass)
|
||||||
activity.intent?.let {
|
activity.intent?.let {
|
||||||
sourceIntent.putExtras(it)
|
sourceIntent.putExtras(it)
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ class ReaderActivity :
|
|||||||
pageSwitchTimer.delaySec = value
|
pageSwitchTimer.delaySec = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val readerMode: ReaderMode?
|
||||||
|
get() = readerManager.currentMode
|
||||||
|
|
||||||
private lateinit var pageSwitchTimer: PageSwitchTimer
|
private lateinit var pageSwitchTimer: PageSwitchTimer
|
||||||
private lateinit var touchHelper: GridTouchHelper
|
private lateinit var touchHelper: GridTouchHelper
|
||||||
private lateinit var controlDelegate: ReaderControlDelegate
|
private lateinit var controlDelegate: ReaderControlDelegate
|
||||||
@@ -88,7 +91,7 @@ class ReaderActivity :
|
|||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
touchHelper = GridTouchHelper(this, this)
|
touchHelper = GridTouchHelper(this, this)
|
||||||
pageSwitchTimer = PageSwitchTimer(this, this)
|
pageSwitchTimer = PageSwitchTimer(this, this)
|
||||||
controlDelegate = ReaderControlDelegate(lifecycleScope, settings, this)
|
controlDelegate = ReaderControlDelegate(settings, this, this)
|
||||||
binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected)
|
binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected)
|
||||||
binding.slider.setLabelFormatter(PageLabelFormatter())
|
binding.slider.setLabelFormatter(PageLabelFormatter())
|
||||||
ReaderSliderListener(this, viewModel).attachToSlider(binding.slider)
|
ReaderSliderListener(this, viewModel).attachToSlider(binding.slider)
|
||||||
|
|||||||
@@ -1,33 +1,39 @@
|
|||||||
package org.koitharu.kotatsu.reader.ui
|
package org.koitharu.kotatsu.reader.ui
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.SoundEffectConstants
|
import android.view.SoundEffectConstants
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import kotlinx.coroutines.Dispatchers
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||||
import org.koitharu.kotatsu.utils.GridTouchHelper
|
import org.koitharu.kotatsu.utils.GridTouchHelper
|
||||||
|
|
||||||
class ReaderControlDelegate(
|
class ReaderControlDelegate(
|
||||||
scope: LifecycleCoroutineScope,
|
private val settings: AppSettings,
|
||||||
settings: AppSettings,
|
|
||||||
private val listener: OnInteractionListener,
|
private val listener: OnInteractionListener,
|
||||||
) {
|
owner: LifecycleOwner,
|
||||||
|
) : DefaultLifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private var isTapSwitchEnabled: Boolean = true
|
private var isTapSwitchEnabled: Boolean = true
|
||||||
private var isVolumeKeysSwitchEnabled: Boolean = false
|
private var isVolumeKeysSwitchEnabled: Boolean = false
|
||||||
|
private var isReaderTapsAdaptive: Boolean = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
settings.observeAsFlow(AppSettings.KEY_READER_SWITCHERS) { readerPageSwitch }
|
owner.lifecycle.addObserver(this)
|
||||||
.flowOn(Dispatchers.Default)
|
settings.subscribe(this)
|
||||||
.onEach {
|
updateSettings()
|
||||||
isTapSwitchEnabled = AppSettings.PAGE_SWITCH_TAPS in it
|
}
|
||||||
isVolumeKeysSwitchEnabled = AppSettings.PAGE_SWITCH_VOLUME_KEYS in it
|
|
||||||
}.launchIn(scope)
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
|
settings.unsubscribe(this)
|
||||||
|
owner.lifecycle.removeObserver(this)
|
||||||
|
super.onDestroy(owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
|
updateSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onGridTouch(area: Int, view: View) {
|
fun onGridTouch(area: Int, view: View) {
|
||||||
@@ -41,7 +47,7 @@ class ReaderControlDelegate(
|
|||||||
view.playSoundEffect(SoundEffectConstants.NAVIGATION_UP)
|
view.playSoundEffect(SoundEffectConstants.NAVIGATION_UP)
|
||||||
}
|
}
|
||||||
GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) {
|
GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) {
|
||||||
listener.switchPageBy(-1)
|
listener.switchPageBy(if (isReaderTapsReversed()) 1 else -1)
|
||||||
view.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT)
|
view.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT)
|
||||||
}
|
}
|
||||||
GridTouchHelper.AREA_BOTTOM -> if (isTapSwitchEnabled) {
|
GridTouchHelper.AREA_BOTTOM -> if (isTapSwitchEnabled) {
|
||||||
@@ -49,7 +55,7 @@ class ReaderControlDelegate(
|
|||||||
view.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN)
|
view.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN)
|
||||||
}
|
}
|
||||||
GridTouchHelper.AREA_RIGHT -> if (isTapSwitchEnabled) {
|
GridTouchHelper.AREA_RIGHT -> if (isTapSwitchEnabled) {
|
||||||
listener.switchPageBy(1)
|
listener.switchPageBy(if (isReaderTapsReversed()) -1 else 1)
|
||||||
view.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT)
|
view.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,19 +78,25 @@ class ReaderControlDelegate(
|
|||||||
KeyEvent.KEYCODE_PAGE_DOWN,
|
KeyEvent.KEYCODE_PAGE_DOWN,
|
||||||
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN,
|
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN,
|
||||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||||
KeyEvent.KEYCODE_DPAD_RIGHT,
|
|
||||||
-> {
|
-> {
|
||||||
listener.switchPageBy(1)
|
listener.switchPageBy(1)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||||
|
listener.switchPageBy(if (isReaderTapsReversed()) -1 else 1)
|
||||||
|
true
|
||||||
|
}
|
||||||
KeyEvent.KEYCODE_PAGE_UP,
|
KeyEvent.KEYCODE_PAGE_UP,
|
||||||
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP,
|
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP,
|
||||||
KeyEvent.KEYCODE_DPAD_UP,
|
KeyEvent.KEYCODE_DPAD_UP,
|
||||||
KeyEvent.KEYCODE_DPAD_LEFT,
|
|
||||||
-> {
|
-> {
|
||||||
listener.switchPageBy(-1)
|
listener.switchPageBy(-1)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
KeyEvent.KEYCODE_DPAD_LEFT -> {
|
||||||
|
listener.switchPageBy(if (isReaderTapsReversed()) 1 else -1)
|
||||||
|
true
|
||||||
|
}
|
||||||
KeyEvent.KEYCODE_DPAD_CENTER -> {
|
KeyEvent.KEYCODE_DPAD_CENTER -> {
|
||||||
listener.toggleUiVisibility()
|
listener.toggleUiVisibility()
|
||||||
true
|
true
|
||||||
@@ -99,8 +111,21 @@ class ReaderControlDelegate(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateSettings() {
|
||||||
|
val switch = settings.readerPageSwitch
|
||||||
|
isTapSwitchEnabled = AppSettings.PAGE_SWITCH_TAPS in switch
|
||||||
|
isVolumeKeysSwitchEnabled = AppSettings.PAGE_SWITCH_VOLUME_KEYS in switch
|
||||||
|
isReaderTapsAdaptive = settings.isReaderTapsAdaptive
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isReaderTapsReversed(): Boolean {
|
||||||
|
return isReaderTapsAdaptive && listener.readerMode == ReaderMode.REVERSED
|
||||||
|
}
|
||||||
|
|
||||||
interface OnInteractionListener {
|
interface OnInteractionListener {
|
||||||
|
|
||||||
|
val readerMode: ReaderMode?
|
||||||
|
|
||||||
fun switchPageBy(delta: Int)
|
fun switchPageBy(delta: Int)
|
||||||
|
|
||||||
fun toggleUiVisibility()
|
fun toggleUiVisibility()
|
||||||
|
|||||||
@@ -379,4 +379,6 @@
|
|||||||
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. If it is available, send an error report to the developers.</string>
|
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. If it is available, send an error report to the developers.</string>
|
||||||
<string name="history_shortcuts">Show recent manga shortcuts</string>
|
<string name="history_shortcuts">Show recent manga shortcuts</string>
|
||||||
<string name="history_shortcuts_summary">Make recent manga available by long pressing on application icon</string>
|
<string name="history_shortcuts_summary">Make recent manga available by long pressing on application icon</string>
|
||||||
|
<string name="reader_control_ltr_summary">Tap on the right edge or pressing the right key always switches to the next page</string>
|
||||||
|
<string name="reader_control_ltr">Ergonomic reader control</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -29,6 +29,12 @@
|
|||||||
android:title="@string/switch_pages"
|
android:title="@string/switch_pages"
|
||||||
app:allowDividerAbove="true" />
|
app:allowDividerAbove="true" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="reader_taps_ltr"
|
||||||
|
android:summary="@string/reader_control_ltr_summary"
|
||||||
|
android:title="@string/reader_control_ltr" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="reader_animation"
|
android:key="reader_animation"
|
||||||
|
|||||||
Reference in New Issue
Block a user