diff options
author | Eric Bailey <git@esb.lol> | 2023-11-08 13:55:38 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-08 11:55:38 -0800 |
commit | bd531f2344c181261afaf8c43c96daf569b58f09 (patch) | |
tree | 631334df0390c14742016dc4a282457e662a3fc8 /src/state/preferences | |
parent | f18b15241ab708f8c25a11937a875e361e9f1221 (diff) | |
download | voidsky-bd531f2344c181261afaf8c43c96daf569b58f09.tar.zst |
Pull language methods into api context (#1847)
* Pull language methods into api context * Rename for consistency
Diffstat (limited to 'src/state/preferences')
-rw-r--r-- | src/state/preferences/index.tsx | 2 | ||||
-rw-r--r-- | src/state/preferences/languages.tsx | 159 |
2 files changed, 88 insertions, 73 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), - })) -} |