+64
src/screens/Settings/DeerSettings.tsx
+64
src/screens/Settings/DeerSettings.tsx
···
80
useSetShowExternalShareButtons,
81
useShowExternalShareButtons,
82
} from '#/state/preferences/external-share-buttons'
83
import {
84
useHideFeedsPromoTab,
85
useSetHideFeedsPromoTab,
···
467
const showLinkInHandle = useShowLinkInHandle()
468
const setShowLinkInHandle = useSetShowLinkInHandle()
469
470
const [gates, setGatesView] = useState(Object.assign({
471
alt_share_icon: false,
472
debug_show_feedcontext: false,
···
653
</Admonition>
654
</SettingsList.Item>
655
656
<SettingsList.Group contentContainerStyle={[a.gap_sm]}>
657
<SettingsList.ItemIcon icon={PaintRollerIcon} />
658
<SettingsList.ItemText>
···
80
useSetShowExternalShareButtons,
81
useShowExternalShareButtons,
82
} from '#/state/preferences/external-share-buttons'
83
+
import {
84
+
useSetTerminologyPreference,
85
+
useTerminologyPreference,
86
+
} from '#/state/preferences/terminology-preference'
87
import {
88
useHideFeedsPromoTab,
89
useSetHideFeedsPromoTab,
···
471
const showLinkInHandle = useShowLinkInHandle()
472
const setShowLinkInHandle = useSetShowLinkInHandle()
473
474
+
const terminologyPreference = useTerminologyPreference()
475
+
const setTerminologyPreference = useSetTerminologyPreference()
476
+
477
const [gates, setGatesView] = useState(Object.assign({
478
alt_share_icon: false,
479
debug_show_feedcontext: false,
···
660
</Admonition>
661
</SettingsList.Item>
662
663
+
<SettingsList.Group contentContainerStyle={[a.gap_sm]}>
664
+
<SettingsList.ItemIcon icon={PaintRollerIcon} />
665
+
<SettingsList.ItemText>
666
+
<Trans>Terminology</Trans>
667
+
</SettingsList.ItemText>
668
+
</SettingsList.Group>
669
+
670
+
<SettingsList.Item>
671
+
<Admonition type="info" style={[a.flex_1]}>
672
+
<Trans>
673
+
Choose your preferred terminology for posts throughout the app.
674
+
</Trans>
675
+
</Admonition>
676
+
</SettingsList.Item>
677
+
678
+
<SettingsList.Item>
679
+
<Toggle.Item
680
+
name="terminology_skeet"
681
+
label={_(msg`Use "skeet(s)"`)}
682
+
value={terminologyPreference === 'skeet'}
683
+
onChange={() => setTerminologyPreference('skeet')}
684
+
style={[a.w_full]}>
685
+
<Toggle.LabelText style={[a.flex_1]}>
686
+
<Trans>Use "skeet(s)"</Trans>
687
+
</Toggle.LabelText>
688
+
<Toggle.Radio />
689
+
</Toggle.Item>
690
+
</SettingsList.Item>
691
+
692
+
<SettingsList.Item>
693
+
<Toggle.Item
694
+
name="terminology_post"
695
+
label={_(msg`Use "post(s)"`)}
696
+
value={terminologyPreference === 'post'}
697
+
onChange={() => setTerminologyPreference('post')}
698
+
style={[a.w_full]}>
699
+
<Toggle.LabelText style={[a.flex_1]}>
700
+
<Trans>Use "post(s)"</Trans>
701
+
</Toggle.LabelText>
702
+
<Toggle.Radio />
703
+
</Toggle.Item>
704
+
</SettingsList.Item>
705
+
706
+
<SettingsList.Item>
707
+
<Toggle.Item
708
+
name="terminology_spell"
709
+
label={_(msg`Use "spell(s)"`)}
710
+
value={terminologyPreference === 'spell'}
711
+
onChange={() => setTerminologyPreference('spell')}
712
+
style={[a.w_full]}>
713
+
<Toggle.LabelText style={[a.flex_1]}>
714
+
<Trans>Use "spell(s)"</Trans>
715
+
</Toggle.LabelText>
716
+
<Toggle.Radio />
717
+
</Toggle.Item>
718
+
</SettingsList.Item>
719
+
720
<SettingsList.Group contentContainerStyle={[a.gap_sm]}>
721
<SettingsList.ItemIcon icon={PaintRollerIcon} />
722
<SettingsList.ItemText>
+2
src/state/persisted/schema.ts
+2
src/state/persisted/schema.ts
···
169
hideUnreplyablePosts: z.boolean().optional(),
170
171
showExternalShareButtons: z.boolean().optional(),
172
173
/** @deprecated */
174
mutedThreads: z.array(z.string()),
···
272
highQualityImages: false,
273
hideUnreplyablePosts: false,
274
showExternalShareButtons: false,
275
}
276
277
export function tryParse(rawData: string): Schema | undefined {
···
169
hideUnreplyablePosts: z.boolean().optional(),
170
171
showExternalShareButtons: z.boolean().optional(),
172
+
terminologyPreference: z.enum(['skeet', 'post', 'spell']).optional(),
173
174
/** @deprecated */
175
mutedThreads: z.array(z.string()),
···
273
highQualityImages: false,
274
hideUnreplyablePosts: false,
275
showExternalShareButtons: false,
276
+
terminologyPreference: 'skeet',
277
}
278
279
export function tryParse(rawData: string): Schema | undefined {
+8
-1
src/state/preferences/index.tsx
+8
-1
src/state/preferences/index.tsx
···
37
import {Provider as RepostCarouselProvider} from './repost-carousel-enabled'
38
import {Provider as ShowLinkInHandleProvider} from './show-link-in-handle'
39
import {Provider as SubtitlesProvider} from './subtitles'
40
import {Provider as TrendingSettingsProvider} from './trending'
41
import {Provider as UsedStarterPacksProvider} from './used-starter-packs'
42
···
59
export {useLabelDefinitions} from './label-defs'
60
export {useLanguagePrefs, useLanguagePrefsApi} from './languages'
61
export {useSetSubtitlesEnabled, useSubtitlesEnabled} from './subtitles'
62
63
export function Provider({children}: React.PropsWithChildren<{}>) {
64
return (
···
101
<EnableSquareAvatarsProvider>
102
<EnableSquareButtonsProvider>
103
<DisableVerifyEmailReminderProvider>
104
-
{children}
105
</DisableVerifyEmailReminderProvider>
106
</EnableSquareButtonsProvider>
107
</EnableSquareAvatarsProvider>
···
37
import {Provider as RepostCarouselProvider} from './repost-carousel-enabled'
38
import {Provider as ShowLinkInHandleProvider} from './show-link-in-handle'
39
import {Provider as SubtitlesProvider} from './subtitles'
40
+
import {Provider as TerminologyPreferenceProvider} from './terminology-preference'
41
import {Provider as TrendingSettingsProvider} from './trending'
42
import {Provider as UsedStarterPacksProvider} from './used-starter-packs'
43
···
60
export {useLabelDefinitions} from './label-defs'
61
export {useLanguagePrefs, useLanguagePrefsApi} from './languages'
62
export {useSetSubtitlesEnabled, useSubtitlesEnabled} from './subtitles'
63
+
export {
64
+
useTerminologyPreference,
65
+
useSetTerminologyPreference,
66
+
} from './terminology-preference'
67
68
export function Provider({children}: React.PropsWithChildren<{}>) {
69
return (
···
106
<EnableSquareAvatarsProvider>
107
<EnableSquareButtonsProvider>
108
<DisableVerifyEmailReminderProvider>
109
+
<TerminologyPreferenceProvider>
110
+
{children}
111
+
</TerminologyPreferenceProvider>
112
</DisableVerifyEmailReminderProvider>
113
</EnableSquareButtonsProvider>
114
</EnableSquareAvatarsProvider>
+52
src/state/preferences/terminology-preference.tsx
+52
src/state/preferences/terminology-preference.tsx
···
···
1
+
import React from 'react'
2
+
3
+
import * as persisted from '#/state/persisted'
4
+
5
+
type StateContext = persisted.Schema['terminologyPreference']
6
+
type SetContext = (v: persisted.Schema['terminologyPreference']) => void
7
+
8
+
const stateContext = React.createContext<StateContext>(
9
+
persisted.defaults.terminologyPreference,
10
+
)
11
+
const setContext = React.createContext<SetContext>(
12
+
(_: persisted.Schema['terminologyPreference']) => {},
13
+
)
14
+
15
+
export function Provider({children}: React.PropsWithChildren<{}>) {
16
+
const [state, setState] = React.useState(
17
+
persisted.get('terminologyPreference'),
18
+
)
19
+
20
+
const setStateWrapped = React.useCallback(
21
+
(terminologyPreference: persisted.Schema['terminologyPreference']) => {
22
+
setState(terminologyPreference)
23
+
persisted.write('terminologyPreference', terminologyPreference)
24
+
},
25
+
[setState],
26
+
)
27
+
28
+
React.useEffect(() => {
29
+
return persisted.onUpdate(
30
+
'terminologyPreference',
31
+
nextTerminologyPreference => {
32
+
setState(nextTerminologyPreference)
33
+
},
34
+
)
35
+
}, [setStateWrapped])
36
+
37
+
return (
38
+
<stateContext.Provider value={state}>
39
+
<setContext.Provider value={setStateWrapped}>
40
+
{children}
41
+
</setContext.Provider>
42
+
</stateContext.Provider>
43
+
)
44
+
}
45
+
46
+
export function useTerminologyPreference() {
47
+
return React.useContext(stateContext)
48
+
}
49
+
50
+
export function useSetTerminologyPreference() {
51
+
return React.useContext(setContext)
52
+
}