diff options
author | Paul Frazee <pfrazee@gmail.com> | 2024-01-04 17:37:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-04 17:37:36 -0800 |
commit | 0dae24e78ffe0b2d69349a03f669949e4d5afc21 (patch) | |
tree | f2895aebae675d0c5d6c9213626a37a98a53f724 /src/state | |
parent | db62f272412df2c34e1a57200291b53fa1cd07aa (diff) | |
download | voidsky-0dae24e78ffe0b2d69349a03f669949e4d5afc21.tar.zst |
Additional embed sources and external-media consent controls (#2424)
* add apple music embed * add vimeo embed * add logic for tenor and giphy embeds * keep it simple, use playerUri for images too * add gif embed player * lint, fix tests * remove links that can't produce a thumb * Revert "remove links that can't produce a thumb" This reverts commit 985b92b4e622db936bb0c79fdf324099b9c8fcd8. * Revert "Revert "remove links that can't produce a thumb"" This reverts commit 4895ded8b5120c4fc52b43ae85c9a01ea0b1a733. * Revert "Revert "Revert "remove links that can't produce a thumb""" This reverts commit 36d04b517ba5139e1639f2eda28d7f9aaa2dbfb6. * properly obtain giphy metadata regardless of used url * test fixes * adjust gif player * add all twitch embed types * support m.youtube links * few logic adjustments * adjust spotify player height * prefetch gif before showing * use memory-disk cache policy on gifs * use `disk` cachePolicy on ios - can't start/stop animation * support pause/play on web * onLoad fix * remove extra pressable, add accessibility, fix scale issues * improve size of embed * add settings * fix(?) settings * add source to embed player params * update tests * better naming and settings options * consent modal * fix test id * why is webstorm adding .tsx * web modal * simplify types * adjust snap points * remove unnecessary yt embed library. just use the webview always * remove now useless WebGifStill 😠* more type cleanup * more type cleanup * combine parse and prefs check in one memo * improve dimensions of youtube shorts * oops didn't commit the test 🫥 * add shorts as separate embed type * fix up schema * shorts modal * hide gif details * support localized spotify embeds * more cleanup * improve look and accessibility of gif embeds * Update routing for the external embeds settings page * Update and simplify the external embed preferences screen * Update copy in embedconsent modal and add 'allow all' button --------- Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/modals/index.tsx | 8 | ||||
-rw-r--r-- | src/state/persisted/legacy.ts | 1 | ||||
-rw-r--r-- | src/state/persisted/schema.ts | 16 | ||||
-rw-r--r-- | src/state/preferences/external-embeds-prefs.tsx | 54 | ||||
-rw-r--r-- | src/state/preferences/index.tsx | 9 |
5 files changed, 87 insertions, 1 deletions
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index 81a220d1b..8c32c472a 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -6,6 +6,7 @@ import {Image as RNImage} from 'react-native-image-crop-picker' import {ImageModel} from '#/state/models/media/image' import {GalleryModel} from '#/state/models/media/gallery' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' +import {EmbedPlayerSource} from '#/lib/strings/embed-player.ts' import {ThreadgateSetting} from '../queries/threadgate' export interface ConfirmModal { @@ -180,6 +181,12 @@ export interface LinkWarningModal { href: string } +export interface EmbedConsentModal { + name: 'embed-consent' + source: EmbedPlayerSource + onAccept: () => void +} + export type Modal = // Account | AddAppPasswordModal @@ -223,6 +230,7 @@ export type Modal = // Generic | ConfirmModal | LinkWarningModal + | EmbedConsentModal const ModalContext = React.createContext<{ isModalActive: boolean diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index cdb542f5a..334ef1d92 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -109,6 +109,7 @@ export function transform(legacy: Partial<LegacySchema>): Schema { step: legacy.onboarding?.step || defaults.onboarding.step, }, hiddenPosts: defaults.hiddenPosts, + externalEmbeds: defaults.externalEmbeds, } } diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 27b1f26bd..6a26cedae 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -1,6 +1,8 @@ import {z} from 'zod' import {deviceLocales} from '#/platform/detection' +const externalEmbedOptions = ['show', 'hide'] as const + // only data needed for rendering account page const accountSchema = z.object({ service: z.string(), @@ -30,6 +32,19 @@ export const schema = z.object({ appLanguage: z.string(), }), requireAltTextEnabled: z.boolean(), // should move to server + externalEmbeds: z + .object({ + giphy: z.enum(externalEmbedOptions).optional(), + tenor: z.enum(externalEmbedOptions).optional(), + youtube: z.enum(externalEmbedOptions).optional(), + youtubeShorts: z.enum(externalEmbedOptions).optional(), + twitch: z.enum(externalEmbedOptions).optional(), + vimeo: z.enum(externalEmbedOptions).optional(), + spotify: z.enum(externalEmbedOptions).optional(), + appleMusic: z.enum(externalEmbedOptions).optional(), + soundcloud: z.enum(externalEmbedOptions).optional(), + }) + .optional(), mutedThreads: z.array(z.string()), // should move to server invites: z.object({ copiedInvites: z.array(z.string()), @@ -60,6 +75,7 @@ export const defaults: Schema = { appLanguage: deviceLocales[0] || 'en', }, requireAltTextEnabled: false, + externalEmbeds: {}, mutedThreads: [], invites: { copiedInvites: [], diff --git a/src/state/preferences/external-embeds-prefs.tsx b/src/state/preferences/external-embeds-prefs.tsx new file mode 100644 index 000000000..0f6385fe8 --- /dev/null +++ b/src/state/preferences/external-embeds-prefs.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import * as persisted from '#/state/persisted' +import {EmbedPlayerSource} from 'lib/strings/embed-player' + +type StateContext = persisted.Schema['externalEmbeds'] +type SetContext = (source: EmbedPlayerSource, value: 'show' | 'hide') => void + +const stateContext = React.createContext<StateContext>( + persisted.defaults.externalEmbeds, +) +const setContext = React.createContext<SetContext>({} as SetContext) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState(persisted.get('externalEmbeds')) + + const setStateWrapped = React.useCallback( + (source: EmbedPlayerSource, value: 'show' | 'hide') => { + setState(prev => { + persisted.write('externalEmbeds', { + ...prev, + [source]: value, + }) + + return { + ...prev, + [source]: value, + } + }) + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate(() => { + setState(persisted.get('externalEmbeds')) + }) + }, [setStateWrapped]) + + return ( + <stateContext.Provider value={state}> + <setContext.Provider value={setStateWrapped}> + {children} + </setContext.Provider> + </stateContext.Provider> + ) +} + +export function useExternalEmbedsPrefs() { + return React.useContext(stateContext) +} + +export function useSetExternalEmbedPref() { + return React.useContext(setContext) +} diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index 5ec659031..cc2d9244c 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -2,19 +2,26 @@ import React from 'react' 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' export {useLanguagePrefs, useLanguagePrefsApi} from './languages' export { useRequireAltTextEnabled, useSetRequireAltTextEnabled, } from './alt-text-required' +export { + useExternalEmbedsPrefs, + useSetExternalEmbedPref, +} from './external-embeds-prefs' export * from './hidden-posts' export function Provider({children}: React.PropsWithChildren<{}>) { return ( <LanguagesProvider> <AltTextRequiredProvider> - <HiddenPostsProvider>{children}</HiddenPostsProvider> + <ExternalEmbedsProvider> + <HiddenPostsProvider>{children}</HiddenPostsProvider> + </ExternalEmbedsProvider> </AltTextRequiredProvider> </LanguagesProvider> ) |