From d0516143423afaf6fe9c6db71ee67e5aef99b013 Mon Sep 17 00:00:00 2001 From: Hailey Date: Thu, 23 May 2024 08:45:24 -0700 Subject: [PATCH] implement a safari hack for ime (#4186) remove debug logs use a better hack implement a safari hack extract `isSafari` and `isFirefox` to a global variable --- src/lib/browser.native.ts | 2 ++ src/lib/browser.ts | 6 ++++++ src/lib/strings/embed-player.ts | 5 +---- .../Conversation/MessageInput.web.tsx | 20 +++++++++++++++++++ src/view/com/util/List.web.tsx | 3 +-- 5 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/lib/browser.native.ts create mode 100644 src/lib/browser.ts diff --git a/src/lib/browser.native.ts b/src/lib/browser.native.ts new file mode 100644 index 00000000..3ac238b9 --- /dev/null +++ b/src/lib/browser.native.ts @@ -0,0 +1,2 @@ +export const isSafari = false +export const isFirefox = false diff --git a/src/lib/browser.ts b/src/lib/browser.ts new file mode 100644 index 00000000..d5ecb4e8 --- /dev/null +++ b/src/lib/browser.ts @@ -0,0 +1,6 @@ +// https://stackoverflow.com/questions/7944460/detect-safari-browser +export const isSafari = /^((?!chrome|android).)*safari/i.test( + navigator.userAgent, +) + +export const isFirefox = /firefox|fxios/i.test(navigator.userAgent) diff --git a/src/lib/strings/embed-player.ts b/src/lib/strings/embed-player.ts index d84ccc72..54649f14 100644 --- a/src/lib/strings/embed-player.ts +++ b/src/lib/strings/embed-player.ts @@ -1,5 +1,6 @@ import {Dimensions, Platform} from 'react-native' +import {isSafari} from 'lib/browser' import {isWeb} from 'platform/detection' const {height: SCREEN_HEIGHT} = Dimensions.get('window') @@ -353,10 +354,6 @@ export function parseEmbedPlayerFromUrl( if (id && filename && dimensions && id.includes('AAAAC')) { if (Platform.OS === 'web') { - const isSafari = /^((?!chrome|android).)*safari/i.test( - navigator.userAgent, - ) - if (isSafari) { id = id.replace('AAAAC', 'AAAP1') filename = filename.replace('.gif', '.mp4') diff --git a/src/screens/Messages/Conversation/MessageInput.web.tsx b/src/screens/Messages/Conversation/MessageInput.web.tsx index 3e78608a..55599bed 100644 --- a/src/screens/Messages/Conversation/MessageInput.web.tsx +++ b/src/screens/Messages/Conversation/MessageInput.web.tsx @@ -10,6 +10,7 @@ import { useMessageDraft, useSaveMessageDraft, } from '#/state/messages/message-drafts' +import {isSafari} from 'lib/browser' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {useSharedInputStyles} from '#/components/forms/TextField' @@ -47,6 +48,25 @@ export function MessageInput({ (e: React.KeyboardEvent) => { // Don't submit the form when the Japanese or any other IME is composing if (isComposing.current) return + + // see https://github.com/bluesky-social/social-app/issues/4178 + // see https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/ + // see https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html + // + // On Safari, the final keydown event to dismiss the IME - which is the enter key - is also "Enter" below. + // Obviously, this causes problems because the final dismissal should _not_ submit the text, but should just + // stop the IME editing. This is the behavior of Chrome and Firefox, but not Safari. + // + // Keycode is deprecated, however the alternative seems to only be to compare the timestamp from the + // onCompositionEnd event to the timestamp of the keydown event, which is not reliable. For example, this hack + // uses that method: https://github.com/ProseMirror/prosemirror-view/pull/44. However, from my 500ms resulted in + // far too long of a delay, and a subsequent enter press would often just end up doing nothing. A shorter time + // frame was also not great, since it was too short to be reliable (i.e. an older system might have a larger + // time gap between the two events firing. + if (isSafari && e.key === 'Enter' && e.keyCode === 229) { + return + } + if (e.key === 'Enter') { if (e.shiftKey) return e.preventDefault() diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index 7f192686..9d8ddeda 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -5,6 +5,7 @@ import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/rean import {batchedUpdates} from '#/lib/batchedUpdates' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useScrollHandlers} from '#/lib/ScrollContext' +import {isFirefox, isSafari} from 'lib/browser' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {addStyle} from 'lib/styles' @@ -503,8 +504,6 @@ export const List = memo(React.forwardRef(ListImpl)) as ( ) => React.ReactElement // https://stackoverflow.com/questions/7944460/detect-safari-browser -const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) -const isFirefox = /firefox|fxios/i.test(navigator.userAgent) const styles = StyleSheet.create({ sideBorders: {