diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/hooks/useAuxClick.ts | 2 | ||||
-rw-r--r-- | src/lib/hooks/useAuxClick.web.ts | 43 | ||||
-rw-r--r-- | src/view/com/util/Link.tsx | 25 | ||||
-rw-r--r-- | src/view/com/util/WebAuxClickWrapper.tsx | 30 | ||||
-rw-r--r-- | src/view/shell/index.web.tsx | 2 |
5 files changed, 44 insertions, 58 deletions
diff --git a/src/lib/hooks/useAuxClick.ts b/src/lib/hooks/useAuxClick.ts deleted file mode 100644 index ab6fd4365..000000000 --- a/src/lib/hooks/useAuxClick.ts +++ /dev/null @@ -1,2 +0,0 @@ -// does nothing in native -export const useAuxClick = () => {} diff --git a/src/lib/hooks/useAuxClick.web.ts b/src/lib/hooks/useAuxClick.web.ts deleted file mode 100644 index ca9811615..000000000 --- a/src/lib/hooks/useAuxClick.web.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {useEffect} from 'react' - -// This is the handler for the middle mouse button click on the feed. -// Normally, we would do this via `onAuxClick` handler on each link element -// However, that handler is not supported on react-native-web and there are some -// discrepancies between various browsers (i.e: safari doesn't trigger it and routes through click event) -// So, this temporary alternative is meant to bridge the gap in an efficient way until the support improves. -export const useAuxClick = () => { - const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) - useEffect(() => { - // On the web, it should always be there but in case it gets accidentally included in native builds - const wrapperEl = document?.body - - // Safari already handles auxclick event as click+metaKey so we need to avoid doing this there in case it becomes recursive - if (wrapperEl && !isSafari) { - const handleAuxClick = (e: MouseEvent & {target: HTMLElement}) => { - // Only handle the middle mouse button click - // Only handle if the clicked element itself or one of its ancestors is a link - if ( - e.button !== 1 || - e.target.closest('a') || - e.target.tagName === 'A' - ) { - return - } - - // On the original element, trigger a click event with metaKey set to true so that it triggers - // the browser's default behavior of opening the link in a new tab - e.target.dispatchEvent( - new MouseEvent('click', {metaKey: true, bubbles: true}), - ) - } - - // @ts-ignore For web only - wrapperEl.addEventListener('auxclick', handleAuxClick) - - return () => { - // @ts-ignore For web only - wrapperEl?.removeEventListener('auxclick', handleAuxClick) - } - } - }, [isSafari]) -} diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index a517ba430..afbdeb8f4 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -31,6 +31,7 @@ import {PressableWithHover} from './PressableWithHover' import FixedTouchableHighlight from '../pager/FixedTouchableHighlight' import {useModalControls} from '#/state/modals' import {useOpenLink} from '#/state/preferences/in-app-browser' +import {WebAuxClickWrapper} from 'view/com/util/WebAuxClickWrapper' type Event = | React.MouseEvent<HTMLAnchorElement, MouseEvent> @@ -104,17 +105,19 @@ export const Link = memo(function Link({ ) } return ( - <TouchableWithoutFeedback - testID={testID} - onPress={onPress} - accessible={accessible} - accessibilityRole="link" - {...props}> - {/* @ts-ignore web only -prf */} - <View style={style} href={anchorHref}> - {children ? children : <Text>{title || 'link'}</Text>} - </View> - </TouchableWithoutFeedback> + <WebAuxClickWrapper> + <TouchableWithoutFeedback + testID={testID} + onPress={onPress} + accessible={accessible} + accessibilityRole="link" + {...props}> + {/* @ts-ignore web only -prf */} + <View style={style} href={anchorHref}> + {children ? children : <Text>{title || 'link'}</Text>} + </View> + </TouchableWithoutFeedback> + </WebAuxClickWrapper> ) } diff --git a/src/view/com/util/WebAuxClickWrapper.tsx b/src/view/com/util/WebAuxClickWrapper.tsx new file mode 100644 index 000000000..8105a8518 --- /dev/null +++ b/src/view/com/util/WebAuxClickWrapper.tsx @@ -0,0 +1,30 @@ +import React from 'react' +import {Platform} from 'react-native' + +const onMouseUp = (e: React.MouseEvent & {target: HTMLElement}) => { + // Only handle whenever it is the middle button + if (e.button !== 1 || e.target.closest('a') || e.target.tagName === 'A') { + return + } + + e.target.dispatchEvent( + new MouseEvent('click', {metaKey: true, bubbles: true}), + ) +} + +const onMouseDown = (e: React.MouseEvent) => { + // Prevents the middle click scroll from enabling + if (e.button !== 1) return + e.preventDefault() +} + +export function WebAuxClickWrapper({children}: React.PropsWithChildren<{}>) { + if (Platform.OS !== 'web') return children + + return ( + // @ts-ignore web only + <div onMouseDown={onMouseDown} onMouseUp={onMouseUp}> + {children} + </div> + ) +} diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 76f4f5c9b..97c065502 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -11,7 +11,6 @@ import {DrawerContent} from './Drawer' import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries' import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' -import {useAuxClick} from 'lib/hooks/useAuxClick' import {t} from '@lingui/macro' import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell' import {useCloseAllActiveElements} from '#/state/util' @@ -26,7 +25,6 @@ function ShellInner() { const closeAllActiveElements = useCloseAllActiveElements() useWebBodyScrollLock(isDrawerOpen) - useAuxClick() useEffect(() => { const unsubscribe = navigator.addListener('state', () => { |