diff --git a/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx b/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx index fb939b9926..9f2224b4e7 100644 --- a/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx +++ b/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx @@ -6,13 +6,14 @@ import shim from '@joplin/lib/shim'; import { themeStyle } from '@joplin/lib/theme'; import { Theme } from '@joplin/lib/themes/type'; import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; -import { BackHandler, Platform } from 'react-native'; +import { Platform } from 'react-native'; import ExtendedWebView from '../../ExtendedWebView'; import { OnMessageEvent, WebViewControl } from '../../ExtendedWebView/types'; import { clearAutosave } from './autosave'; import { LocalizedStrings } from './js-draw/types'; import { DialogContext } from '../../DialogManager'; import useEditorMessenger from './utils/useEditorMessenger'; +import BackButtonService from '../../../services/BackButtonService'; const logger = Logger.create('ImageEditor'); @@ -124,10 +125,10 @@ const ImageEditor = (props: Props) => { onRequestCloseEditor(true); return true; }; - const handle = BackHandler.addEventListener('hardwareBackPress', hardwareBackPressListener); + BackButtonService.addHandler(hardwareBackPressListener); return () => { - handle.remove(); + BackButtonService.removeHandler(hardwareBackPressListener); }; }, [onRequestCloseEditor]); diff --git a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx index 84d1cc0695..bae59572be 100644 --- a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx +++ b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx @@ -5,11 +5,12 @@ import { useMemo, useState, useEffect } from 'react'; import { EditorSettings } from './types'; import { _ } from '@joplin/lib/locale'; -import { BackHandler, TextInput, View, Text, StyleSheet, ViewStyle } from 'react-native'; +import { TextInput, View, Text, StyleSheet, ViewStyle } from 'react-native'; import { Theme } from '@joplin/lib/themes/type'; import IconButton from '../IconButton'; import { SearchState } from '@joplin/editor/types'; import { SearchControl } from './types'; +import BackButtonService from '../../services/BackButtonService'; const buttonSize = 48; @@ -181,14 +182,14 @@ export const SearchPanel = (props: SearchPanelProps) => { return () => {}; } - const backListener = BackHandler.addEventListener('hardwareBackPress', () => { + const handler = () => { control.hideSearch(); return true; - }); + }; - return () => backListener.remove(); - // eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied - }, [state.dialogVisible]); + BackButtonService.addHandler(handler); + return () => BackButtonService.removeHandler(handler); + }, [state.dialogVisible, control]); const themeId = props.editorSettings.themeId; diff --git a/packages/app-mobile/services/BackButtonService.ts b/packages/app-mobile/services/BackButtonService.ts index ea6463dde3..e7bc6090ee 100644 --- a/packages/app-mobile/services/BackButtonService.ts +++ b/packages/app-mobile/services/BackButtonService.ts @@ -1,4 +1,4 @@ -import { BackHandler } from 'react-native'; +import { BackHandler, Platform } from 'react-native'; export type BackButtonHandler = ()=> boolean|Promise; @@ -9,10 +9,13 @@ export default class BackButtonService { public static initialize(defaultHandler: BackButtonHandler) { this.defaultHandler_ = defaultHandler; - BackHandler.addEventListener('hardwareBackPress', () => { - void this.back(); - return true; - }); + // On web, `BackHandler.addEventListener` fails with warning "BackHandler is not supported on web and should not be used." + if (Platform.OS !== 'web') { + BackHandler.addEventListener('hardwareBackPress', () => { + void this.back(); + return true; + }); + } } public static async back() {