Present in-app browser as sheet (#5718)

* use page sheet presentation

* move to its own file rather than sitting in prefs

* whoops, missed one
This commit is contained in:
Samuel Newman
2024-10-12 02:42:58 +03:00
committed by GitHub
parent 8e16427497
commit d6322477fe
9 changed files with 71 additions and 65 deletions
+1 -1
View File
@@ -10,6 +10,7 @@ import {StackActions, useLinkProps} from '@react-navigation/native'
import {BSKY_DOWNLOAD_URL} from '#/lib/constants' import {BSKY_DOWNLOAD_URL} from '#/lib/constants'
import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped' import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {AllNavigatorParams} from '#/lib/routes/types' import {AllNavigatorParams} from '#/lib/routes/types'
import {shareUrl} from '#/lib/sharing' import {shareUrl} from '#/lib/sharing'
import { import {
@@ -21,7 +22,6 @@ import {
import {isNative, isWeb} from '#/platform/detection' import {isNative, isWeb} from '#/platform/detection'
import {shouldClickOpenNewTab} from '#/platform/urls' import {shouldClickOpenNewTab} from '#/platform/urls'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf' import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf'
import {Button, ButtonProps} from '#/components/Button' import {Button, ButtonProps} from '#/components/Button'
import {useInteractionState} from '#/components/hooks/useInteractionState' import {useInteractionState} from '#/components/hooks/useInteractionState'
+1 -1
View File
@@ -5,12 +5,12 @@ import {ChatBskyConvoDefs, RichText} from '@atproto/api'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {richTextToString} from '#/lib/strings/rich-text-helpers' import {richTextToString} from '#/lib/strings/rich-text-helpers'
import {getTranslatorLink} from '#/locale/helpers' import {getTranslatorLink} from '#/locale/helpers'
import {isWeb} from '#/platform/detection' import {isWeb} from '#/platform/detection'
import {useConvoActive} from '#/state/messages/convo' import {useConvoActive} from '#/state/messages/convo'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
+54
View File
@@ -0,0 +1,54 @@
import {useCallback} from 'react'
import {Linking} from 'react-native'
import * as WebBrowser from 'expo-web-browser'
import {
createBskyAppAbsoluteUrl,
isBskyRSSUrl,
isRelativeUrl,
} from '#/lib/strings/url-helpers'
import {isNative} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {useInAppBrowser} from '#/state/preferences/in-app-browser'
import {useTheme} from '#/alf'
import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper'
export function useOpenLink() {
const {openModal} = useModalControls()
const enabled = useInAppBrowser()
const t = useTheme()
const sheetWrapper = useSheetWrapper()
const openLink = useCallback(
async (url: string, override?: boolean) => {
if (isBskyRSSUrl(url) && isRelativeUrl(url)) {
url = createBskyAppAbsoluteUrl(url)
}
if (isNative && !url.startsWith('mailto:')) {
if (override === undefined && enabled === undefined) {
openModal({
name: 'in-app-browser-consent',
href: url,
})
return
} else if (override ?? enabled) {
await sheetWrapper(
WebBrowser.openBrowserAsync(url, {
presentationStyle:
WebBrowser.WebBrowserPresentationStyle.PAGE_SHEET,
toolbarColor: t.atoms.bg.backgroundColor,
controlsColor: t.palette.primary_500,
createTask: false,
}),
)
return
}
}
Linking.openURL(url)
},
[enabled, openModal, t, sheetWrapper],
)
return openLink
}
-46
View File
@@ -1,16 +1,6 @@
import React from 'react' import React from 'react'
import {Linking} from 'react-native'
import * as WebBrowser from 'expo-web-browser'
import {usePalette} from '#/lib/hooks/usePalette'
import {
createBskyAppAbsoluteUrl,
isBskyRSSUrl,
isRelativeUrl,
} from '#/lib/strings/url-helpers'
import {isNative} from '#/platform/detection'
import * as persisted from '#/state/persisted' import * as persisted from '#/state/persisted'
import {useModalControls} from '../modals'
type StateContext = persisted.Schema['useInAppBrowser'] type StateContext = persisted.Schema['useInAppBrowser']
type SetContext = (v: persisted.Schema['useInAppBrowser']) => void type SetContext = (v: persisted.Schema['useInAppBrowser']) => void
@@ -55,39 +45,3 @@ export function useInAppBrowser() {
export function useSetInAppBrowser() { export function useSetInAppBrowser() {
return React.useContext(setContext) return React.useContext(setContext)
} }
export function useOpenLink() {
const {openModal} = useModalControls()
const enabled = useInAppBrowser()
const pal = usePalette('default')
const openLink = React.useCallback(
async (url: string, override?: boolean) => {
if (isBskyRSSUrl(url) && isRelativeUrl(url)) {
url = createBskyAppAbsoluteUrl(url)
}
if (isNative && !url.startsWith('mailto:')) {
if (override === undefined && enabled === undefined) {
openModal({
name: 'in-app-browser-consent',
href: url,
})
return
} else if (override ?? enabled) {
await WebBrowser.openBrowserAsync(url, {
presentationStyle:
WebBrowser.WebBrowserPresentationStyle.FULL_SCREEN,
toolbarColor: pal.colors.backgroundLight,
createTask: false,
})
return
}
}
Linking.openURL(url)
},
[enabled, openModal, pal.colors.backgroundLight],
)
return openLink
}
+5 -7
View File
@@ -3,16 +3,14 @@ import {StyleSheet, View} from 'react-native'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import { import {useSetInAppBrowser} from '#/state/preferences/in-app-browser'
useOpenLink, import {ScrollView} from '#/view/com/modals/util'
useSetInAppBrowser, import {Button} from '#/view/com/util/forms/Button'
} from '#/state/preferences/in-app-browser' import {Text} from '#/view/com/util/text/Text'
import {Button} from '../util/forms/Button'
import {Text} from '../util/text/Text'
import {ScrollView} from './util'
export const snapPoints = [350] export const snapPoints = [350]
+1 -1
View File
@@ -4,6 +4,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {shareUrl} from '#/lib/sharing' import {shareUrl} from '#/lib/sharing'
@@ -11,7 +12,6 @@ import {isPossiblyAUrl, splitApexDomain} from '#/lib/strings/url-helpers'
import {colors, s} from '#/lib/styles' import {colors, s} from '#/lib/styles'
import {isWeb} from '#/platform/detection' import {isWeb} from '#/platform/detection'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {Button} from '#/view/com/util/forms/Button' import {Button} from '#/view/com/util/forms/Button'
import {Text} from '#/view/com/util/text/Text' import {Text} from '#/view/com/util/text/Text'
import {ScrollView} from './util' import {ScrollView} from './util'
+1 -1
View File
@@ -13,6 +13,7 @@ import {msg, Plural, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {MAX_POST_LINES} from '#/lib/constants' import {MAX_POST_LINES} from '#/lib/constants'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
@@ -22,7 +23,6 @@ import {niceDate} from '#/lib/strings/time'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow' import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {ThreadPost} from '#/state/queries/post-thread' import {ThreadPost} from '#/state/queries/post-thread'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useComposerControls} from '#/state/shell/composer' import {useComposerControls} from '#/state/shell/composer'
+7 -7
View File
@@ -13,20 +13,20 @@ import {
import {sanitizeUrl} from '@braintree/sanitize-url' import {sanitizeUrl} from '@braintree/sanitize-url'
import {StackActions, useLinkProps} from '@react-navigation/native' import {StackActions, useLinkProps} from '@react-navigation/native'
import {useModalControls} from '#/state/modals'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import { import {
DebouncedNavigationProp, DebouncedNavigationProp,
useNavigationDeduped, useNavigationDeduped,
} from 'lib/hooks/useNavigationDeduped' } from '#/lib/hooks/useNavigationDeduped'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import { import {
convertBskyAppUrlIfNeeded, convertBskyAppUrlIfNeeded,
isExternalUrl, isExternalUrl,
linkRequiresWarning, linkRequiresWarning,
} from 'lib/strings/url-helpers' } from '#/lib/strings/url-helpers'
import {TypographyVariant} from 'lib/ThemeContext' import {TypographyVariant} from '#/lib/ThemeContext'
import {isAndroid, isWeb} from 'platform/detection' import {isAndroid, isWeb} from '#/platform/detection'
import {WebAuxClickWrapper} from 'view/com/util/WebAuxClickWrapper' import {useModalControls} from '#/state/modals'
import {WebAuxClickWrapper} from '#/view/com/util/WebAuxClickWrapper'
import {useTheme} from '#/alf' import {useTheme} from '#/alf'
import {router} from '../../../routes' import {router} from '../../../routes'
import {PressableWithHover} from './PressableWithHover' import {PressableWithHover} from './PressableWithHover'
+1 -1
View File
@@ -18,6 +18,7 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {getCurrentRoute} from '#/lib/routes/helpers' import {getCurrentRoute} from '#/lib/routes/helpers'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
@@ -33,7 +34,6 @@ import {Shadow} from '#/state/cache/post-shadow'
import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useFeedFeedbackContext} from '#/state/feed-feedback'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences' import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {usePinnedPostMutation} from '#/state/queries/pinned-post' import {usePinnedPostMutation} from '#/state/queries/pinned-post'
import { import {
usePostDeleteMutation, usePostDeleteMutation,