Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

:bug: Handle middle mouse click on feed list items (#1469)

* :bug: Handle middle mouse click on feed list items

* :recycle: Refactor the event listener and turn it into a dedicated hook for web

* :broom: Cleanup unnecessary Link changes

* Fix import

* Create native version of useAuxClick

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

authored by

Foysal Ahamed
Paul Frazee
and committed by
GitHub
3c4899b3 255beb0c

+50 -2
+2
src/lib/hooks/useAuxClick.ts
··· 1 + // does nothing in native 2 + export const useAuxClick = () => {}
+43
src/lib/hooks/useAuxClick.web.ts
··· 1 + import {useEffect} from 'react' 2 + 3 + // This is the handler for the middle mouse button click on the feed. 4 + // Normally, we would do this via `onAuxClick` handler on each link element 5 + // However, that handler is not supported on react-native-web and there are some 6 + // discrepancies between various browsers (i.e: safari doesn't trigger it and routes through click event) 7 + // So, this temporary alternative is meant to bridge the gap in an efficient way until the support improves. 8 + export const useAuxClick = () => { 9 + const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) 10 + useEffect(() => { 11 + // On the web, it should always be there but in case it gets accidentally included in native builds 12 + const wrapperEl = document?.body 13 + 14 + // Safari already handles auxclick event as click+metaKey so we need to avoid doing this there in case it becomes recursive 15 + if (wrapperEl && !isSafari) { 16 + const handleAuxClick = (e: MouseEvent & {target: HTMLElement}) => { 17 + // Only handle the middle mouse button click 18 + // Only handle if the clicked element itself or one of its ancestors is a link 19 + if ( 20 + e.button !== 1 || 21 + e.target.closest('a') || 22 + e.target.tagName === 'A' 23 + ) { 24 + return 25 + } 26 + 27 + // On the original element, trigger a click event with metaKey set to true so that it triggers 28 + // the browser's default behavior of opening the link in a new tab 29 + e.target.dispatchEvent( 30 + new MouseEvent('click', {metaKey: true, bubbles: true}), 31 + ) 32 + } 33 + 34 + // @ts-ignore For web only 35 + wrapperEl.addEventListener('auxclick', handleAuxClick) 36 + 37 + return () => { 38 + // @ts-ignore For web only 39 + wrapperEl?.removeEventListener('auxclick', handleAuxClick) 40 + } 41 + } 42 + }, [isSafari]) 43 + }
+3 -2
src/view/com/util/Link.tsx
··· 59 59 }: Props) { 60 60 const store = useStores() 61 61 const navigation = useNavigation<NavigationProp>() 62 + const anchorHref = asAnchor ? sanitizeUrl(href) : undefined 62 63 63 64 const onPress = React.useCallback( 64 65 (e?: Event) => { ··· 96 97 accessibilityRole="link" 97 98 {...props}> 98 99 {/* @ts-ignore web only -prf */} 99 - <View style={style} href={asAnchor ? sanitizeUrl(href) : undefined}> 100 + <View style={style} href={anchorHref}> 100 101 {children ? children : <Text>{title || 'link'}</Text>} 101 102 </View> 102 103 </TouchableWithoutFeedback> ··· 123 124 accessible={accessible} 124 125 accessibilityRole="link" 125 126 // @ts-ignore web only -prf 126 - href={asAnchor ? sanitizeUrl(href) : undefined} 127 + href={anchorHref} 127 128 {...props}> 128 129 {children ? children : <Text>{title || 'link'}</Text>} 129 130 </Com>
+2
src/view/shell/index.web.tsx
··· 16 16 import {BottomBarWeb} from './bottom-bar/BottomBarWeb' 17 17 import {useNavigation} from '@react-navigation/native' 18 18 import {NavigationProp} from 'lib/routes/types' 19 + import {useAuxClick} from 'lib/hooks/useAuxClick' 19 20 20 21 const ShellInner = observer(function ShellInnerImpl() { 21 22 const store = useStores() 22 23 const {isDesktop, isMobile} = useWebMediaQueries() 23 24 const navigator = useNavigation<NavigationProp>() 25 + useAuxClick() 24 26 25 27 useEffect(() => { 26 28 navigator.addListener('state', () => {