Warn the user on links that dont match their text (#1573)

* Add link warning modal when URLs do not match their text

* Simplify the misleading link case for clarity

* Fix typecheck

* fix dark mode

* Give a stronger visual indication of the root domain in the link warning

* More rigorous URL mismatch logic

* Remove debug

---------

Co-authored-by: Ansh Nanda <anshnanda10@gmail.com>
This commit is contained in:
Paul Frazee 2023-10-02 14:47:39 -07:00 committed by GitHub
parent 2f157c152a
commit fd5bbb2769
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 357 additions and 3 deletions

View file

@ -23,7 +23,11 @@ import {TypographyVariant} from 'lib/ThemeContext'
import {NavigationProp} from 'lib/routes/types'
import {router} from '../../../routes'
import {useStores, RootStoreModel} from 'state/index'
import {convertBskyAppUrlIfNeeded, isExternalUrl} from 'lib/strings/url-helpers'
import {
convertBskyAppUrlIfNeeded,
isExternalUrl,
linkRequiresWarning,
} from 'lib/strings/url-helpers'
import {isAndroid} from 'platform/detection'
import {sanitizeUrl} from '@braintree/sanitize-url'
import {PressableWithHover} from './PressableWithHover'
@ -143,6 +147,7 @@ export const TextLink = observer(function TextLink({
dataSet,
title,
onPress,
warnOnMismatchingLabel,
...orgProps
}: {
testID?: string
@ -154,13 +159,29 @@ export const TextLink = observer(function TextLink({
lineHeight?: number
dataSet?: any
title?: string
warnOnMismatchingLabel?: boolean
} & TextProps) {
const {...props} = useLinkProps({to: sanitizeUrl(href)})
const store = useStores()
const navigation = useNavigation<NavigationProp>()
if (warnOnMismatchingLabel && typeof text !== 'string') {
console.error('Unable to detect mismatching label')
}
props.onPress = React.useCallback(
(e?: Event) => {
const requiresWarning =
warnOnMismatchingLabel &&
linkRequiresWarning(href, typeof text === 'string' ? text : '')
if (requiresWarning) {
e?.preventDefault?.()
store.shell.openModal({
name: 'link-warning',
text: typeof text === 'string' ? text : '',
href,
})
}
if (onPress) {
e?.preventDefault?.()
// @ts-ignore function signature differs by platform -prf
@ -168,7 +189,7 @@ export const TextLink = observer(function TextLink({
}
return onPressInner(store, navigation, sanitizeUrl(href), e)
},
[onPress, store, navigation, href],
[onPress, store, navigation, href, text, warnOnMismatchingLabel],
)
const hrefAttrs = useMemo(() => {
const isExternal = isExternalUrl(href)

View file

@ -89,6 +89,7 @@ export function RichText({
href={link.uri}
style={[style, lineHeightStyle, pal.link]}
dataSet={WORD_WRAP}
warnOnMismatchingLabel
/>,
)
} else {