Add an opt out for sending utm
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useInAppBrowser} from '#/state/preferences/in-app-browser'
|
||||
import {useOptOutOfUtm} from '#/state/preferences/opt-out-of-utm'
|
||||
import {useTheme} from '#/alf'
|
||||
import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper'
|
||||
|
||||
@@ -18,6 +19,7 @@ export function useOpenLink() {
|
||||
const enabled = useInAppBrowser()
|
||||
const t = useTheme()
|
||||
const sheetWrapper = useSheetWrapper()
|
||||
const optOutOfUtm = useOptOutOfUtm()
|
||||
|
||||
const openLink = useCallback(
|
||||
async (url: string, override?: boolean) => {
|
||||
@@ -26,6 +28,9 @@ export function useOpenLink() {
|
||||
}
|
||||
|
||||
if (isNative && !url.startsWith('mailto:')) {
|
||||
if (!optOutOfUtm) {
|
||||
url = addUtmSource(url)
|
||||
}
|
||||
if (override === undefined && enabled === undefined) {
|
||||
openModal({
|
||||
name: 'in-app-browser-consent',
|
||||
@@ -33,7 +38,6 @@ export function useOpenLink() {
|
||||
})
|
||||
return
|
||||
} else if (override ?? enabled) {
|
||||
url = addUtmSource(url)
|
||||
await sheetWrapper(
|
||||
WebBrowser.openBrowserAsync(url, {
|
||||
presentationStyle:
|
||||
@@ -48,7 +52,7 @@ export function useOpenLink() {
|
||||
}
|
||||
Linking.openURL(url)
|
||||
},
|
||||
[enabled, openModal, t, sheetWrapper],
|
||||
[enabled, openModal, t, sheetWrapper, optOutOfUtm],
|
||||
)
|
||||
|
||||
return openLink
|
||||
|
||||
@@ -9,9 +9,16 @@ import {
|
||||
useInAppBrowser,
|
||||
useSetInAppBrowser,
|
||||
} from '#/state/preferences/in-app-browser'
|
||||
import {
|
||||
useOptOutOfUtm,
|
||||
useSetOptOutOfUtm,
|
||||
} from '#/state/preferences/opt-out-of-utm'
|
||||
import * as SettingsList from '#/screens/Settings/components/SettingsList'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import {Bubbles_Stroke2_Corner2_Rounded as BubblesIcon} from '#/components/icons/Bubble'
|
||||
import {ChainLink3_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
|
||||
import {Hashtag_Stroke2_Corner0_Rounded as HashtagIcon} from '#/components/icons/Hashtag'
|
||||
import {Home_Stroke2_Corner2_Rounded as HomeIcon} from '#/components/icons/Home'
|
||||
import {Macintosh_Stroke2_Corner2_Rounded as MacintoshIcon} from '#/components/icons/Macintosh'
|
||||
@@ -29,6 +36,8 @@ export function ContentAndMediaSettingsScreen({}: Props) {
|
||||
const setAutoplayDisabledPref = useSetAutoplayDisabled()
|
||||
const inAppBrowserPref = useInAppBrowser()
|
||||
const setUseInAppBrowser = useSetInAppBrowser()
|
||||
const optOutOfUtm = useOptOutOfUtm()
|
||||
const setOptOutOfUtm = useSetOptOutOfUtm()
|
||||
|
||||
return (
|
||||
<Layout.Screen>
|
||||
@@ -68,6 +77,19 @@ export function ContentAndMediaSettingsScreen({}: Props) {
|
||||
</SettingsList.ItemText>
|
||||
</SettingsList.LinkItem>
|
||||
<SettingsList.Divider />
|
||||
<Toggle.Item
|
||||
name="disable_autoplay"
|
||||
label={_(msg`Autoplay videos and GIFs`)}
|
||||
value={!autoplayDisabledPref}
|
||||
onChange={value => setAutoplayDisabledPref(!value)}>
|
||||
<SettingsList.Item>
|
||||
<SettingsList.ItemIcon icon={PlayIcon} />
|
||||
<SettingsList.ItemText>
|
||||
<Trans>Autoplay videos and GIFs</Trans>
|
||||
</SettingsList.ItemText>
|
||||
<Toggle.Platform />
|
||||
</SettingsList.Item>
|
||||
</Toggle.Item>
|
||||
{isNative && (
|
||||
<Toggle.Item
|
||||
name="use_in_app_browser"
|
||||
@@ -83,19 +105,31 @@ export function ContentAndMediaSettingsScreen({}: Props) {
|
||||
</SettingsList.Item>
|
||||
</Toggle.Item>
|
||||
)}
|
||||
<Toggle.Item
|
||||
name="disable_autoplay"
|
||||
label={_(msg`Autoplay videos and GIFs`)}
|
||||
value={!autoplayDisabledPref}
|
||||
onChange={value => setAutoplayDisabledPref(!value)}>
|
||||
{isNative && <SettingsList.Divider />}
|
||||
{isNative && (
|
||||
<Toggle.Item
|
||||
name="allow_utm"
|
||||
label={_(msg`Specify Bluesky as a referer`)}
|
||||
value={!(optOutOfUtm ?? false)}
|
||||
onChange={value => setOptOutOfUtm(!value)}>
|
||||
<SettingsList.Item>
|
||||
<SettingsList.ItemIcon icon={ChainLinkIcon} />
|
||||
<SettingsList.ItemText>
|
||||
<Trans>Send Bluesky referrer</Trans>
|
||||
</SettingsList.ItemText>
|
||||
<Toggle.Platform />
|
||||
</SettingsList.Item>
|
||||
</Toggle.Item>
|
||||
)}
|
||||
{isNative && (
|
||||
<SettingsList.Item>
|
||||
<SettingsList.ItemIcon icon={PlayIcon} />
|
||||
<SettingsList.ItemText>
|
||||
<Trans>Autoplay videos and GIFs</Trans>
|
||||
</SettingsList.ItemText>
|
||||
<Toggle.Platform />
|
||||
<Admonition type="info" style={[a.flex_1]}>
|
||||
<Trans>
|
||||
Helps external sites estimate traffic from Bluesky.
|
||||
</Trans>
|
||||
</Admonition>
|
||||
</SettingsList.Item>
|
||||
</Toggle.Item>
|
||||
)}
|
||||
</SettingsList.Container>
|
||||
</Layout.Content>
|
||||
</Layout.Screen>
|
||||
|
||||
@@ -124,6 +124,7 @@ const schema = z.object({
|
||||
subtitlesEnabled: z.boolean().optional(),
|
||||
/** @deprecated */
|
||||
mutedThreads: z.array(z.string()),
|
||||
optOutOfUtm: z.boolean().optional(),
|
||||
})
|
||||
export type Schema = z.infer<typeof schema>
|
||||
|
||||
@@ -169,6 +170,7 @@ export const defaults: Schema = {
|
||||
kawaii: false,
|
||||
hasCheckedForStarterPack: false,
|
||||
subtitlesEnabled: true,
|
||||
optOutOfUtm: false,
|
||||
}
|
||||
|
||||
export function tryParse(rawData: string): Schema | undefined {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {Provider as InAppBrowserProvider} from './in-app-browser'
|
||||
import {Provider as KawaiiProvider} from './kawaii'
|
||||
import {Provider as LanguagesProvider} from './languages'
|
||||
import {Provider as LargeAltBadgeProvider} from './large-alt-badge'
|
||||
import {Provider as OutOutOfUtmProvider} from './opt-out-of-utm'
|
||||
import {Provider as SubtitlesProvider} from './subtitles'
|
||||
import {Provider as UsedStarterPacksProvider} from './used-starter-packs'
|
||||
|
||||
@@ -39,7 +40,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
<AutoplayProvider>
|
||||
<UsedStarterPacksProvider>
|
||||
<SubtitlesProvider>
|
||||
<KawaiiProvider>{children}</KawaiiProvider>
|
||||
<OutOutOfUtmProvider>
|
||||
<KawaiiProvider>{children}</KawaiiProvider>
|
||||
</OutOutOfUtmProvider>
|
||||
</SubtitlesProvider>
|
||||
</UsedStarterPacksProvider>
|
||||
</AutoplayProvider>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
|
||||
import * as persisted from '#/state/persisted'
|
||||
|
||||
type StateContext = boolean
|
||||
type SetContext = (v: boolean) => void
|
||||
|
||||
const stateContext = React.createContext<StateContext>(
|
||||
Boolean(persisted.defaults.optOutOfUtm),
|
||||
)
|
||||
const setContext = React.createContext<SetContext>((_: boolean) => {})
|
||||
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
const [state, setState] = React.useState(
|
||||
Boolean(persisted.get('optOutOfUtm')),
|
||||
)
|
||||
|
||||
const setStateWrapped = React.useCallback(
|
||||
(optOutOfUtm: persisted.Schema['optOutOfUtm']) => {
|
||||
setState(Boolean(optOutOfUtm))
|
||||
persisted.write('optOutOfUtm', optOutOfUtm)
|
||||
},
|
||||
[setState],
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
return persisted.onUpdate('optOutOfUtm', nextOptOutOfUtm => {
|
||||
setState(Boolean(nextOptOutOfUtm))
|
||||
})
|
||||
}, [setStateWrapped])
|
||||
|
||||
return (
|
||||
<stateContext.Provider value={state}>
|
||||
<setContext.Provider value={setStateWrapped}>
|
||||
{children}
|
||||
</setContext.Provider>
|
||||
</stateContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useOptOutOfUtm = () => React.useContext(stateContext)
|
||||
export const useSetOptOutOfUtm = () => React.useContext(setContext)
|
||||
Reference in New Issue
Block a user