feat(reader): custom hardware-button page turning (#4177)
* feat(reader): add custom hardware-button page turning (#4139) Lets users bind hardware remote keys (media keys, D-pad/arrow keys) to previous/next page via a learn-mode capture UI in reader settings — an accessibility feature for page-turner remotes. - New global hardwarePageTurner system setting (enabled + key bindings). - hardwareKeys.ts: key normalization, matching, and page-turn resolution. - deviceStore: reference-counted media-key interception + learn mode. - usePagination: flips pages from bound media keys (native bridge) and D-pad/keyboard keys (DOM keydown), scoped to the active book and suppressed while the toolbar is visible. - Page Turner settings section on all platforms; web/desktop bind keys via DOM keydown only, native media-key interception stays mobile-only. - Android: intercept media + learn-mode keys in dispatchKeyEvent. - iOS: forward media keys via MPRemoteCommandCenter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(i18n): add and translate hardware page turner strings (#4139) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(reader): refine hardware page turner (#4139) - Handle book-iframe key events (iframe-keydown messages) so custom bindings work as soon as a book is open, not only after the settings panel has been shown. - Add Previous/Next Section bindings alongside the page bindings. - Rename the hardwareKeys util to keybinding. - Wire the Page Turner section into the settings Reset action. - Drop the focus ring on the capture buttons; BoxedList gains an optional description. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(i18n): translate page turner section and key strings (#4139) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+9
-10
@@ -66,6 +66,8 @@ class SetSystemUIVisibilityRequestArgs {
|
||||
class InterceptKeysRequestArgs {
|
||||
var volumeKeys: Boolean? = null
|
||||
var backKey: Boolean? = null
|
||||
var pageTurnerKeys: Boolean? = null
|
||||
var learnMode: Boolean? = null
|
||||
}
|
||||
|
||||
@InvokeArg
|
||||
@@ -115,6 +117,8 @@ data class PurchaseData(
|
||||
interface KeyDownInterceptor {
|
||||
fun interceptVolumeKeys(enabled: Boolean)
|
||||
fun interceptBackKey(enabled: Boolean)
|
||||
fun interceptPageTurnerKeys(enabled: Boolean)
|
||||
fun setKeyLearnMode(enabled: Boolean)
|
||||
}
|
||||
|
||||
@TauriPlugin(
|
||||
@@ -401,16 +405,11 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
|
||||
fun intercept_keys(invoke: Invoke) {
|
||||
val args = invoke.parseArgs(InterceptKeysRequestArgs::class.java)
|
||||
if (activity is KeyDownInterceptor) {
|
||||
when (args.backKey) {
|
||||
true -> (activity as KeyDownInterceptor).interceptBackKey(true)
|
||||
false -> (activity as KeyDownInterceptor).interceptBackKey(false)
|
||||
else -> {}
|
||||
}
|
||||
when (args.volumeKeys) {
|
||||
true -> (activity as KeyDownInterceptor).interceptVolumeKeys(true)
|
||||
false -> (activity as KeyDownInterceptor).interceptVolumeKeys(false)
|
||||
else -> {}
|
||||
}
|
||||
val interceptor = activity as KeyDownInterceptor
|
||||
args.backKey?.let { interceptor.interceptBackKey(it) }
|
||||
args.volumeKeys?.let { interceptor.interceptVolumeKeys(it) }
|
||||
args.pageTurnerKeys?.let { interceptor.interceptPageTurnerKeys(it) }
|
||||
args.learnMode?.let { interceptor.setKeyLearnMode(it) }
|
||||
} else {
|
||||
Log.e("NativeBridgePlugin", "Activity does not implement KeyDownInterceptor")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user