forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useCallback} from 'react'
2import {Linking} from 'react-native'
3import * as WebBrowser from 'expo-web-browser'
4
5import {logEvent} from '#/lib/statsig/statsig'
6import {
7 createBskyAppAbsoluteUrl,
8 createProxiedUrl,
9 isBskyAppUrl,
10 isBskyRSSUrl,
11 isRelativeUrl,
12 toNiceDomain,
13} from '#/lib/strings/url-helpers'
14import {logger} from '#/logger'
15import {isNative} from '#/platform/detection'
16import {useInAppBrowser} from '#/state/preferences/in-app-browser'
17import {useTheme} from '#/alf'
18import {useDialogContext} from '#/components/Dialog'
19import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
20
21export function useOpenLink() {
22 const enabled = useInAppBrowser()
23 const t = useTheme()
24 const dialogContext = useDialogContext()
25 const {inAppBrowserConsentControl} = useGlobalDialogsControlContext()
26
27 const openLink = useCallback(
28 async (url: string, override?: boolean, shouldProxy?: boolean) => {
29 if (isBskyRSSUrl(url) && isRelativeUrl(url)) {
30 url = createBskyAppAbsoluteUrl(url)
31 }
32
33 if (!isBskyAppUrl(url)) {
34 logEvent('link:clicked', {
35 domain: toNiceDomain(url),
36 url,
37 })
38
39 if (shouldProxy) {
40 url = createProxiedUrl(url)
41 }
42 }
43
44 if (isNative && !url.startsWith('mailto:')) {
45 if (override === undefined && enabled === undefined) {
46 // consent dialog is a global dialog, and while it's possible to nest dialogs,
47 // the actual components need to be nested. sibling dialogs on iOS are not supported.
48 // thus, check if we're in a dialog, and if so, close the existing dialog before opening the
49 // consent dialog -sfn
50 if (dialogContext.isWithinDialog) {
51 dialogContext.close(() => {
52 inAppBrowserConsentControl.open(url)
53 })
54 } else {
55 inAppBrowserConsentControl.open(url)
56 }
57 return
58 } else if (override ?? enabled) {
59 WebBrowser.openBrowserAsync(url, {
60 presentationStyle:
61 WebBrowser.WebBrowserPresentationStyle.FULL_SCREEN,
62 toolbarColor: t.atoms.bg.backgroundColor,
63 controlsColor: t.palette.primary_500,
64 createTask: false,
65 }).catch(err => {
66 if (__DEV__)
67 logger.error('Could not open web browser', {message: err})
68 Linking.openURL(url)
69 })
70 return
71 }
72 }
73 Linking.openURL(url)
74 },
75 [enabled, inAppBrowserConsentControl, t, dialogContext],
76 )
77
78 return openLink
79}