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