about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/state/preferences/index.tsx2
-rw-r--r--src/state/preferences/languages.tsx159
-rw-r--r--src/view/com/composer/Composer.tsx7
-rw-r--r--src/view/com/composer/select-language/SelectLangBtn.tsx6
-rw-r--r--src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx9
-rw-r--r--src/view/com/modals/lang-settings/PostLanguagesSettings.tsx9
-rw-r--r--src/view/screens/LanguageSettings.tsx6
7 files changed, 105 insertions, 93 deletions
diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx
index 50cb86c65..1f4348cfc 100644
--- a/src/state/preferences/index.tsx
+++ b/src/state/preferences/index.tsx
@@ -2,7 +2,7 @@ import React from 'react'
 import {Provider as LanguagesProvider} from './languages'
 import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-required'
 
-export {useLanguagePrefs, useSetLanguagePrefs} from './languages'
+export {useLanguagePrefs, useLanguagePrefsApi} from './languages'
 export {
   useRequireAltTextEnabled,
   useSetRequireAltTextEnabled,
diff --git a/src/state/preferences/languages.tsx b/src/state/preferences/languages.tsx
index 49b63550d..95cf67417 100644
--- a/src/state/preferences/languages.tsx
+++ b/src/state/preferences/languages.tsx
@@ -2,24 +2,36 @@ import React from 'react'
 import * as persisted from '#/state/persisted'
 
 type SetStateCb = (
-  v: persisted.Schema['languagePrefs'],
+  s: persisted.Schema['languagePrefs'],
 ) => persisted.Schema['languagePrefs']
 type StateContext = persisted.Schema['languagePrefs']
-type SetContext = (fn: SetStateCb) => void
+type ApiContext = {
+  setPrimaryLanguage: (code2: string) => void
+  setPostLanguage: (commaSeparatedLangCodes: string) => void
+  toggleContentLanguage: (code2: string) => void
+  togglePostLanguage: (code2: string) => void
+  savePostLanguageToHistory: () => void
+}
 
 const stateContext = React.createContext<StateContext>(
   persisted.defaults.languagePrefs,
 )
-const setContext = React.createContext<SetContext>((_: SetStateCb) => {})
+const apiContext = React.createContext<ApiContext>({
+  setPrimaryLanguage: (_: string) => {},
+  setPostLanguage: (_: string) => {},
+  toggleContentLanguage: (_: string) => {},
+  togglePostLanguage: (_: string) => {},
+  savePostLanguageToHistory: () => {},
+})
 
 export function Provider({children}: React.PropsWithChildren<{}>) {
   const [state, setState] = React.useState(persisted.get('languagePrefs'))
 
   const setStateWrapped = React.useCallback(
     (fn: SetStateCb) => {
-      const v = fn(persisted.get('languagePrefs'))
-      setState(v)
-      persisted.write('languagePrefs', v)
+      const s = fn(persisted.get('languagePrefs'))
+      setState(s)
+      persisted.write('languagePrefs', s)
     },
     [setState],
   )
@@ -30,11 +42,75 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
     })
   }, [setStateWrapped])
 
+  const api = React.useMemo(
+    () => ({
+      setPrimaryLanguage(code2: string) {
+        setStateWrapped(s => ({...s, primaryLanguage: code2}))
+      },
+      setPostLanguage(commaSeparatedLangCodes: string) {
+        setStateWrapped(s => ({...s, postLanguage: commaSeparatedLangCodes}))
+      },
+      toggleContentLanguage(code2: string) {
+        setStateWrapped(s => {
+          const exists = s.contentLanguages.includes(code2)
+          const next = exists
+            ? s.contentLanguages.filter(lang => lang !== code2)
+            : s.contentLanguages.concat(code2)
+          return {
+            ...s,
+            contentLanguages: next,
+          }
+        })
+      },
+      togglePostLanguage(code2: string) {
+        setStateWrapped(s => {
+          const exists = hasPostLanguage(state.postLanguage, code2)
+          let next = s.postLanguage
+
+          if (exists) {
+            next = toPostLanguages(s.postLanguage)
+              .filter(lang => lang !== code2)
+              .join(',')
+          } else {
+            // sort alphabetically for deterministic comparison in context menu
+            next = toPostLanguages(s.postLanguage)
+              .concat([code2])
+              .sort((a, b) => a.localeCompare(b))
+              .join(',')
+          }
+
+          return {
+            ...s,
+            postLanguage: next,
+          }
+        })
+      },
+      /**
+       * Saves whatever language codes are currently selected into a history array,
+       * which is then used to populate the language selector menu.
+       */
+      savePostLanguageToHistory() {
+        // filter out duplicate `this.postLanguage` if exists, and prepend
+        // value to start of array
+        setStateWrapped(s => ({
+          ...s,
+          postLanguageHistory: [s.postLanguage]
+            .concat(
+              s.postLanguageHistory.filter(
+                commaSeparatedLangCodes =>
+                  commaSeparatedLangCodes !== s.postLanguage,
+              ),
+            )
+            .slice(0, 6),
+        }))
+      },
+    }),
+    [state, setStateWrapped],
+  )
+
   return (
     <stateContext.Provider value={state}>
-      <setContext.Provider value={setStateWrapped}>
-        {children}
-      </setContext.Provider>
+      <apiContext.Provider value={api}>{children}</apiContext.Provider>
     </stateContext.Provider>
   )
 }
@@ -43,32 +119,14 @@ export function useLanguagePrefs() {
   return React.useContext(stateContext)
 }
 
-export function useSetLanguagePrefs() {
-  return React.useContext(setContext)
+export function useLanguagePrefsApi() {
+  return React.useContext(apiContext)
 }
 
 export function getContentLanguages() {
   return persisted.get('languagePrefs').contentLanguages
 }
 
-export function toggleContentLanguage(
-  state: StateContext,
-  setState: SetContext,
-  code2: string,
-) {
-  if (state.contentLanguages.includes(code2)) {
-    setState(v => ({
-      ...v,
-      contentLanguages: v.contentLanguages.filter(lang => lang !== code2),
-    }))
-  } else {
-    setState(v => ({
-      ...v,
-      contentLanguages: v.contentLanguages.concat(code2),
-    }))
-  }
-}
-
 export function toPostLanguages(postLanguage: string): string[] {
   // filter out empty strings if exist
   return postLanguage.split(',').filter(Boolean)
@@ -77,46 +135,3 @@ export function toPostLanguages(postLanguage: string): string[] {
 export function hasPostLanguage(postLanguage: string, code2: string): boolean {
   return toPostLanguages(postLanguage).includes(code2)
 }
-
-export function togglePostLanguage(
-  state: StateContext,
-  setState: SetContext,
-  code2: string,
-) {
-  if (hasPostLanguage(state.postLanguage, code2)) {
-    setState(v => ({
-      ...v,
-      postLanguage: toPostLanguages(v.postLanguage)
-        .filter(lang => lang !== code2)
-        .join(','),
-    }))
-  } else {
-    // sort alphabetically for deterministic comparison in context menu
-    setState(v => ({
-      ...v,
-      postLanguage: toPostLanguages(v.postLanguage)
-        .concat([code2])
-        .sort((a, b) => a.localeCompare(b))
-        .join(','),
-    }))
-  }
-}
-
-/**
- * Saves whatever language codes are currently selected into a history array,
- * which is then used to populate the language selector menu.
- */
-export function savePostLanguageToHistory(setState: SetContext) {
-  // filter out duplicate `this.postLanguage` if exists, and prepend
-  // value to start of array
-  setState(v => ({
-    ...v,
-    postLanguageHistory: [v.postLanguage]
-      .concat(
-        v.postLanguageHistory.filter(
-          commaSeparatedLangCodes => commaSeparatedLangCodes !== v.postLanguage,
-        ),
-      )
-      .slice(0, 6),
-  }))
-}
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 68f706828..cdc9768f7 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -53,9 +53,8 @@ import {useModals, useModalControls} from '#/state/modals'
 import {useRequireAltTextEnabled} from '#/state/preferences'
 import {
   useLanguagePrefs,
-  useSetLanguagePrefs,
+  useLanguagePrefsApi,
   toPostLanguages,
-  savePostLanguageToHistory,
 } from '#/state/preferences/languages'
 
 type Props = ComposerOpts
@@ -73,7 +72,7 @@ export const ComposePost = observer(function ComposePost({
   const store = useStores()
   const requireAltTextEnabled = useRequireAltTextEnabled()
   const langPrefs = useLanguagePrefs()
-  const setLangPrefs = useSetLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
   const textInput = useRef<TextInputRef>(null)
   const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
   const [isProcessing, setIsProcessing] = useState(false)
@@ -245,7 +244,7 @@ export const ComposePost = observer(function ComposePost({
     if (!replyTo) {
       store.me.mainFeed.onPostCreated()
     }
-    savePostLanguageToHistory(setLangPrefs)
+    setLangPrefs.savePostLanguageToHistory()
     onPost?.()
     onClose()
     Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`)
diff --git a/src/view/com/composer/select-language/SelectLangBtn.tsx b/src/view/com/composer/select-language/SelectLangBtn.tsx
index 6c45f3384..896df041e 100644
--- a/src/view/com/composer/select-language/SelectLangBtn.tsx
+++ b/src/view/com/composer/select-language/SelectLangBtn.tsx
@@ -17,7 +17,7 @@ import {codeToLanguageName} from '../../../../locale/helpers'
 import {useModalControls} from '#/state/modals'
 import {
   useLanguagePrefs,
-  useSetLanguagePrefs,
+  useLanguagePrefsApi,
   toPostLanguages,
   hasPostLanguage,
 } from '#/state/preferences/languages'
@@ -26,7 +26,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
   const pal = usePalette('default')
   const {openModal} = useModalControls()
   const langPrefs = useLanguagePrefs()
-  const setLangPrefs = useSetLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
 
   const onPressMore = useCallback(async () => {
     if (isNative) {
@@ -63,7 +63,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
             : ['far', 'circle'],
         label: langName,
         onPress() {
-          setLangPrefs(v => ({...v, postLanguage: commaSeparatedLangCodes}))
+          setLangPrefs.setPostLanguage(commaSeparatedLangCodes)
         },
       })
     }
diff --git a/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx b/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx
index d37d51e47..0b19abc68 100644
--- a/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx
+++ b/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx
@@ -11,8 +11,7 @@ import {ConfirmLanguagesButton} from './ConfirmLanguagesButton'
 import {useModalControls} from '#/state/modals'
 import {
   useLanguagePrefs,
-  useSetLanguagePrefs,
-  toggleContentLanguage,
+  useLanguagePrefsApi,
 } from '#/state/preferences/languages'
 
 export const snapPoints = ['100%']
@@ -20,7 +19,7 @@ export const snapPoints = ['100%']
 export function Component({}: {}) {
   const {closeModal} = useModalControls()
   const langPrefs = useLanguagePrefs()
-  const setLangPrefs = useSetLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
   const pal = usePalette('default')
   const {isMobile} = useWebMediaQueries()
   const onPressDone = React.useCallback(() => {
@@ -50,9 +49,9 @@ export function Component({}: {}) {
 
   const onPress = React.useCallback(
     (code2: string) => {
-      toggleContentLanguage(langPrefs, setLangPrefs, code2)
+      setLangPrefs.toggleContentLanguage(code2)
     },
-    [langPrefs, setLangPrefs],
+    [setLangPrefs],
   )
 
   return (
diff --git a/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx b/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx
index 4a39da752..7ec26ca52 100644
--- a/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx
+++ b/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx
@@ -12,9 +12,8 @@ import {ToggleButton} from 'view/com/util/forms/ToggleButton'
 import {useModalControls} from '#/state/modals'
 import {
   useLanguagePrefs,
-  useSetLanguagePrefs,
+  useLanguagePrefsApi,
   hasPostLanguage,
-  togglePostLanguage,
 } from '#/state/preferences/languages'
 
 export const snapPoints = ['100%']
@@ -22,7 +21,7 @@ export const snapPoints = ['100%']
 export const Component = observer(function PostLanguagesSettingsImpl() {
   const {closeModal} = useModalControls()
   const langPrefs = useLanguagePrefs()
-  const setLangPrefs = useSetLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
   const pal = usePalette('default')
   const {isMobile} = useWebMediaQueries()
   const onPressDone = React.useCallback(() => {
@@ -52,9 +51,9 @@ export const Component = observer(function PostLanguagesSettingsImpl() {
 
   const onPress = React.useCallback(
     (code2: string) => {
-      togglePostLanguage(langPrefs, setLangPrefs, code2)
+      setLangPrefs.togglePostLanguage(code2)
     },
-    [langPrefs, setLangPrefs],
+    [setLangPrefs],
   )
 
   return (
diff --git a/src/view/screens/LanguageSettings.tsx b/src/view/screens/LanguageSettings.tsx
index c94364e9a..677451526 100644
--- a/src/view/screens/LanguageSettings.tsx
+++ b/src/view/screens/LanguageSettings.tsx
@@ -19,7 +19,7 @@ import {LANGUAGES} from 'lib/../locale/languages'
 import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {useModalControls} from '#/state/modals'
-import {useLanguagePrefs, useSetLanguagePrefs} from '#/state/preferences'
+import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'>
 
@@ -28,7 +28,7 @@ export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
 ) {
   const pal = usePalette('default')
   const langPrefs = useLanguagePrefs()
-  const setLangPrefs = useSetLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
   const {isTabletOrDesktop} = useWebMediaQueries()
   const {screen, track} = useAnalytics()
   const setMinimalShellMode = useSetMinimalShellMode()
@@ -49,7 +49,7 @@ export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
   const onChangePrimaryLanguage = React.useCallback(
     (value: Parameters<PickerSelectProps['onValueChange']>[0]) => {
       if (langPrefs.primaryLanguage !== value) {
-        setLangPrefs(v => ({...v, primaryLanguage: value}))
+        setLangPrefs.setPrimaryLanguage(value)
       }
     },
     [langPrefs, setLangPrefs],