diff --git a/src/screens/Settings/DeerSettings.tsx b/src/screens/Settings/DeerSettings.tsx index d44748848..39c8a78ec 100644 --- a/src/screens/Settings/DeerSettings.tsx +++ b/src/screens/Settings/DeerSettings.tsx @@ -80,6 +80,10 @@ import { useSetShowExternalShareButtons, useShowExternalShareButtons, } from '#/state/preferences/external-share-buttons' +import { + useSetTerminologyPreference, + useTerminologyPreference, +} from '#/state/preferences/terminology-preference' import { useHideFeedsPromoTab, useSetHideFeedsPromoTab, @@ -467,6 +471,9 @@ export function DeerSettingsScreen({}: Props) { const showLinkInHandle = useShowLinkInHandle() const setShowLinkInHandle = useSetShowLinkInHandle() + const terminologyPreference = useTerminologyPreference() + const setTerminologyPreference = useSetTerminologyPreference() + const [gates, setGatesView] = useState(Object.assign({ alt_share_icon: false, debug_show_feedcontext: false, @@ -653,6 +660,63 @@ export function DeerSettingsScreen({}: Props) { + + + + Terminology + + + + + + + Choose your preferred terminology for posts throughout the app. + + + + + + setTerminologyPreference('skeet')} + style={[a.w_full]}> + + Use "skeet(s)" + + + + + + + setTerminologyPreference('post')} + style={[a.w_full]}> + + Use "post(s)" + + + + + + + setTerminologyPreference('spell')} + style={[a.w_full]}> + + Use "spell(s)" + + + + + diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 6b280ffaf..e6ec2c12a 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -169,6 +169,7 @@ const schema = z.object({ hideUnreplyablePosts: z.boolean().optional(), showExternalShareButtons: z.boolean().optional(), + terminologyPreference: z.enum(['skeet', 'post', 'spell']).optional(), /** @deprecated */ mutedThreads: z.array(z.string()), @@ -272,6 +273,7 @@ export const defaults: Schema = { highQualityImages: false, hideUnreplyablePosts: false, showExternalShareButtons: false, + terminologyPreference: 'skeet', } export function tryParse(rawData: string): Schema | undefined { diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index b7df1b568..1231b456b 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -37,6 +37,7 @@ import {Provider as NoDiscoverProvider} from './no-discover-fallback' import {Provider as RepostCarouselProvider} from './repost-carousel-enabled' import {Provider as ShowLinkInHandleProvider} from './show-link-in-handle' import {Provider as SubtitlesProvider} from './subtitles' +import {Provider as TerminologyPreferenceProvider} from './terminology-preference' import {Provider as TrendingSettingsProvider} from './trending' import {Provider as UsedStarterPacksProvider} from './used-starter-packs' @@ -59,6 +60,10 @@ export { export {useLabelDefinitions} from './label-defs' export {useLanguagePrefs, useLanguagePrefsApi} from './languages' export {useSetSubtitlesEnabled, useSubtitlesEnabled} from './subtitles' +export { + useTerminologyPreference, + useSetTerminologyPreference, +} from './terminology-preference' export function Provider({children}: React.PropsWithChildren<{}>) { return ( @@ -101,7 +106,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { - {children} + + {children} + diff --git a/src/state/preferences/terminology-preference.tsx b/src/state/preferences/terminology-preference.tsx new file mode 100644 index 000000000..cf8b1cc53 --- /dev/null +++ b/src/state/preferences/terminology-preference.tsx @@ -0,0 +1,52 @@ +import React from 'react' + +import * as persisted from '#/state/persisted' + +type StateContext = persisted.Schema['terminologyPreference'] +type SetContext = (v: persisted.Schema['terminologyPreference']) => void + +const stateContext = React.createContext( + persisted.defaults.terminologyPreference, +) +const setContext = React.createContext( + (_: persisted.Schema['terminologyPreference']) => {}, +) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState( + persisted.get('terminologyPreference'), + ) + + const setStateWrapped = React.useCallback( + (terminologyPreference: persisted.Schema['terminologyPreference']) => { + setState(terminologyPreference) + persisted.write('terminologyPreference', terminologyPreference) + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate( + 'terminologyPreference', + nextTerminologyPreference => { + setState(nextTerminologyPreference) + }, + ) + }, [setStateWrapped]) + + return ( + + + {children} + + + ) +} + +export function useTerminologyPreference() { + return React.useContext(stateContext) +} + +export function useSetTerminologyPreference() { + return React.useContext(setContext) +}