diff --git a/src-tauri/gen/android/app/src/main/java/moe/sable/client/MainActivity.kt b/src-tauri/gen/android/app/src/main/java/moe/sable/client/MainActivity.kt index c0f8e8251..84c23e6a4 100644 --- a/src-tauri/gen/android/app/src/main/java/moe/sable/client/MainActivity.kt +++ b/src-tauri/gen/android/app/src/main/java/moe/sable/client/MainActivity.kt @@ -22,6 +22,7 @@ class MainActivity : TauriActivity() { // Route the hardware back button through the web app (see onWebViewCreate). override val handleBackNavigation: Boolean = false private var webView: WebView? = null + private var handlingBack = false override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() @@ -121,15 +122,18 @@ class MainActivity : TauriActivity() { this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { + if (handlingBack) return val wv = this@MainActivity.webView if (wv == null) { moveTaskToBack(true) return } + handlingBack = true // If the web app didn't consume the back press, background the app. wv.evaluateJavascript( "(typeof window.__sableAndroidBack === 'function' && window.__sableAndroidBack() === true)" ) { result -> + handlingBack = false if (result != "true") moveTaskToBack(true) } } diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index e8975b78e..ab6e7f3ff 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -116,6 +116,7 @@ export const CustomEditor = forwardRef( ]); const rootRef = useRef(null); const editableRef = useRef(null); + const focusScrollTimerRef = useRef(); const rowRef = useRef(null); const beforeRef = useRef(null); const afterRef = useRef(null); @@ -317,6 +318,12 @@ export const CustomEditor = forwardRef( [] ); + const cancelFocusScroll = useCallback(() => { + window.clearTimeout(focusScrollTimerRef.current); + }, []); + + useEffect(() => cancelFocusScroll, [cancelFocusScroll]); + const queueMultilineMeasurement = useCallback( (resetRetry = true) => { if (multilineMeasureFrameRef.current !== null) { @@ -456,6 +463,7 @@ export const CustomEditor = forwardRef( enterKeyHint={enterKeyHint} // keeps focus after pressing send, but yields to another editor. onBlur={(evt) => { + cancelFocusScroll(); if (!mobileOrTablet()) return; if (suppressBlurRefocusRef?.current) return; const next = evt.relatedTarget as HTMLElement | null; @@ -466,9 +474,14 @@ export const CustomEditor = forwardRef( // not left hidden behind it. onFocus={() => { if (!mobileOrTablet()) return; - const scrollIn = () => rootRef.current?.scrollIntoView({ block: 'nearest' }); + cancelFocusScroll(); + const scrollIn = () => { + if (editableRef.current?.contains(document.activeElement)) { + rootRef.current?.scrollIntoView({ block: 'nearest' }); + } + }; window.visualViewport?.addEventListener('resize', scrollIn, { once: true }); - window.setTimeout(scrollIn, 500); + focusScrollTimerRef.current = window.setTimeout(scrollIn, 500); }} style={{ boxShadow: 'none' }} />