An ATproto social media client -- with an independent Appview.
6
fork

Configure Feed

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

Add support for new-tab clicks on feeds (#4462)

authored by

Paul Frazee and committed by
GitHub
90ec22a6 59f49bef

+48 -22
+3 -11
src/components/Link.tsx
··· 12 12 isExternalUrl, 13 13 linkRequiresWarning, 14 14 } from '#/lib/strings/url-helpers' 15 - import {isNative, isWeb} from '#/platform/detection' 15 + import {isNative} from '#/platform/detection' 16 + import {shouldClickOpenNewTab} from '#/platform/urls' 16 17 import {useModalControls} from '#/state/modals' 17 18 import {useOpenLink} from '#/state/preferences/in-app-browser' 18 19 import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped' ··· 116 117 if (isExternal) { 117 118 openLink(href) 118 119 } else { 119 - /** 120 - * A `GestureResponderEvent`, but cast to `any` to avoid using a bunch 121 - * of @ts-ignore below. 122 - */ 123 - const event = e as any 124 - const isMiddleClick = isWeb && event.button === 1 125 - const isMetaKey = 126 - isWeb && 127 - (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) 128 - const shouldOpenInNewTab = isMetaKey || isMiddleClick 120 + const shouldOpenInNewTab = shouldClickOpenNewTab(e) 129 121 130 122 if (isBskyDownloadUrl(href)) { 131 123 shareUrl(BSKY_DOWNLOAD_URL)
+14 -1
src/platform/urls.tsx
··· 1 - import {Linking} from 'react-native' 1 + import {GestureResponderEvent, Linking} from 'react-native' 2 + 2 3 import {isNative, isWeb} from './detection' 3 4 4 5 export async function getInitialURL(): Promise<string | undefined> { ··· 23 24 window.location.hash = '' 24 25 } 25 26 } 27 + 28 + export function shouldClickOpenNewTab(e: GestureResponderEvent) { 29 + /** 30 + * A `GestureResponderEvent`, but cast to `any` to avoid using a bunch 31 + * of @ts-ignore below. 32 + */ 33 + const event = e as any 34 + const isMiddleClick = isWeb && event.button === 1 35 + const isMetaKey = 36 + isWeb && (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) 37 + return isMetaKey || isMiddleClick 38 + }
+31 -10
src/view/com/feeds/FeedSourceCard.tsx
··· 1 1 import React from 'react' 2 - import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native' 2 + import { 3 + Linking, 4 + Pressable, 5 + StyleProp, 6 + StyleSheet, 7 + View, 8 + ViewStyle, 9 + } from 'react-native' 3 10 import {AtUri} from '@atproto/api' 4 11 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 12 import {msg, Plural, Trans} from '@lingui/macro' ··· 26 33 import {Text} from '../util/text/Text' 27 34 import {UserAvatar} from '../util/UserAvatar' 28 35 import hairlineWidth = StyleSheet.hairlineWidth 36 + import {shouldClickOpenNewTab} from '#/platform/urls' 29 37 30 38 export function FeedSourceCard({ 31 39 feedUri, ··· 203 211 style, 204 212 {borderTopWidth: hideTopBorder ? 0 : hairlineWidth}, 205 213 ]} 206 - onPress={() => { 214 + onPress={e => { 215 + const shouldOpenInNewTab = shouldClickOpenNewTab(e) 207 216 if (feed.type === 'feed') { 208 - navigation.push('ProfileFeed', { 209 - name: feed.creatorDid, 210 - rkey: new AtUri(feed.uri).rkey, 211 - }) 217 + if (shouldOpenInNewTab) { 218 + Linking.openURL( 219 + `/profile/${feed.creatorDid}/feed/${new AtUri(feed.uri).rkey}`, 220 + ) 221 + } else { 222 + navigation.push('ProfileFeed', { 223 + name: feed.creatorDid, 224 + rkey: new AtUri(feed.uri).rkey, 225 + }) 226 + } 212 227 } else if (feed.type === 'list') { 213 - navigation.push('ProfileList', { 214 - name: feed.creatorDid, 215 - rkey: new AtUri(feed.uri).rkey, 216 - }) 228 + if (shouldOpenInNewTab) { 229 + Linking.openURL( 230 + `/profile/${feed.creatorDid}/lists/${new AtUri(feed.uri).rkey}`, 231 + ) 232 + } else { 233 + navigation.push('ProfileList', { 234 + name: feed.creatorDid, 235 + rkey: new AtUri(feed.uri).rkey, 236 + }) 237 + } 217 238 } 218 239 }} 219 240 key={feed.uri}>