diff options
author | Paul Frazee <pfrazee@gmail.com> | 2024-01-12 10:19:56 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-12 10:19:56 -0800 |
commit | 998ee2998657e82395fe4462809c376ffbd03ed8 (patch) | |
tree | 4eb3930734b939c0cfaa36f39a84fd27ca3a831c /src/state/preferences | |
parent | b147f7ae8a5c8c3a1ec9981132b4c6447034963f (diff) | |
download | voidsky-998ee2998657e82395fe4462809c376ffbd03ed8.tar.zst |
(optional) In app browser (#2490)
* add expo web browser + modal * add in app browser option to settings * don't show toggle on web * Tweak browser-choice UIs --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/state/preferences')
-rw-r--r-- | src/state/preferences/in-app-browser.tsx | 79 | ||||
-rw-r--r-- | src/state/preferences/index.tsx | 5 |
2 files changed, 83 insertions, 1 deletions
diff --git a/src/state/preferences/in-app-browser.tsx b/src/state/preferences/in-app-browser.tsx new file mode 100644 index 000000000..628663af4 --- /dev/null +++ b/src/state/preferences/in-app-browser.tsx @@ -0,0 +1,79 @@ +import React from 'react' +import * as persisted from '#/state/persisted' +import {Linking} from 'react-native' +import * as WebBrowser from 'expo-web-browser' +import {isNative} from '#/platform/detection' +import {useModalControls} from '../modals' + +type StateContext = persisted.Schema['useInAppBrowser'] +type SetContext = (v: persisted.Schema['useInAppBrowser']) => void + +const stateContext = React.createContext<StateContext>( + persisted.defaults.useInAppBrowser, +) +const setContext = React.createContext<SetContext>( + (_: persisted.Schema['useInAppBrowser']) => {}, +) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState(persisted.get('useInAppBrowser')) + + const setStateWrapped = React.useCallback( + (inAppBrowser: persisted.Schema['useInAppBrowser']) => { + setState(inAppBrowser) + persisted.write('useInAppBrowser', inAppBrowser) + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate(() => { + setState(persisted.get('useInAppBrowser')) + }) + }, [setStateWrapped]) + + return ( + <stateContext.Provider value={state}> + <setContext.Provider value={setStateWrapped}> + {children} + </setContext.Provider> + </stateContext.Provider> + ) +} + +export function useInAppBrowser() { + return React.useContext(stateContext) +} + +export function useSetInAppBrowser() { + return React.useContext(setContext) +} + +export function useOpenLink() { + const {openModal} = useModalControls() + const enabled = useInAppBrowser() + + const openLink = React.useCallback( + (url: string, override?: boolean) => { + if (isNative && !url.startsWith('mailto:')) { + if (override === undefined && enabled === undefined) { + openModal({ + name: 'in-app-browser-consent', + href: url, + }) + return + } else if (override ?? enabled) { + WebBrowser.openBrowserAsync(url, { + presentationStyle: + WebBrowser.WebBrowserPresentationStyle.FULL_SCREEN, + }) + return + } + } + Linking.openURL(url) + }, + [enabled, openModal], + ) + + return openLink +} diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index cc2d9244c..a442b763a 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -3,6 +3,7 @@ import {Provider as LanguagesProvider} from './languages' import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-required' import {Provider as HiddenPostsProvider} from '../preferences/hidden-posts' import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs' +import {Provider as InAppBrowserProvider} from './in-app-browser' export {useLanguagePrefs, useLanguagePrefsApi} from './languages' export { @@ -20,7 +21,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { <LanguagesProvider> <AltTextRequiredProvider> <ExternalEmbedsProvider> - <HiddenPostsProvider>{children}</HiddenPostsProvider> + <HiddenPostsProvider> + <InAppBrowserProvider>{children}</InAppBrowserProvider> + </HiddenPostsProvider> </ExternalEmbedsProvider> </AltTextRequiredProvider> </LanguagesProvider> |