Move language preferences to new persistence + context (#1837)

This commit is contained in:
Paul Frazee 2023-11-08 09:38:28 -08:00 committed by GitHub
parent e75b2d508b
commit 5843e212c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 233 additions and 190 deletions

View file

@ -50,6 +50,12 @@ import {SelectLangBtn} from './select-language/SelectLangBtn'
import {EmojiPickerButton} from './text-input/web/EmojiPicker.web'
import {insertMentionAt} from 'lib/strings/mention-manip'
import {useRequireAltTextEnabled} from '#/state/shell'
import {
useLanguagePrefs,
useSetLanguagePrefs,
toPostLanguages,
savePostLanguageToHistory,
} from '#/state/preferences/languages'
type Props = ComposerOpts
export const ComposePost = observer(function ComposePost({
@ -63,6 +69,8 @@ export const ComposePost = observer(function ComposePost({
const {isDesktop, isMobile} = useWebMediaQueries()
const store = useStores()
const requireAltTextEnabled = useRequireAltTextEnabled()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useSetLanguagePrefs()
const textInput = useRef<TextInputRef>(null)
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
const [isProcessing, setIsProcessing] = useState(false)
@ -212,7 +220,7 @@ export const ComposePost = observer(function ComposePost({
labels,
onStateChange: setProcessingState,
knownHandles: autocompleteView.knownHandles,
langs: store.preferences.postLanguages,
langs: toPostLanguages(langPrefs.postLanguage),
})
} catch (e: any) {
if (extLink) {
@ -234,7 +242,7 @@ export const ComposePost = observer(function ComposePost({
if (!replyTo) {
store.me.mainFeed.onPostCreated()
}
store.preferences.savePostLanguageToHistory()
savePostLanguageToHistory(setLangPrefs)
onPost?.()
onClose()
Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`)

View file

@ -15,10 +15,18 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useStores} from 'state/index'
import {isNative} from 'platform/detection'
import {codeToLanguageName} from '../../../../locale/helpers'
import {
useLanguagePrefs,
useSetLanguagePrefs,
toPostLanguages,
hasPostLanguage,
} from '#/state/preferences/languages'
export const SelectLangBtn = observer(function SelectLangBtn() {
const pal = usePalette('default')
const store = useStores()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useSetLanguagePrefs()
const onPressMore = useCallback(async () => {
if (isNative) {
@ -29,8 +37,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
store.shell.openModal({name: 'post-languages-settings'})
}, [store])
const postLanguagesPref = store.preferences.postLanguages
const postLanguagePref = store.preferences.postLanguage
const postLanguagesPref = toPostLanguages(langPrefs.postLanguage)
const items: DropdownItem[] = useMemo(() => {
let arr: DropdownItemButton[] = []
@ -49,13 +56,14 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
arr.push({
icon:
langCodes.every(code => store.preferences.hasPostLanguage(code)) &&
langCodes.length === postLanguagesPref.length
langCodes.every(code =>
hasPostLanguage(langPrefs.postLanguage, code),
) && langCodes.length === postLanguagesPref.length
? ['fas', 'circle-dot']
: ['far', 'circle'],
label: langName,
onPress() {
store.preferences.setPostLanguage(commaSeparatedLangCodes)
setLangPrefs(v => ({...v, postLanguage: commaSeparatedLangCodes}))
},
})
}
@ -65,11 +73,11 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
* Re-join here after sanitization bc postLanguageHistory is an array of
* comma-separated strings too
*/
add(postLanguagePref)
add(langPrefs.postLanguage)
}
// comma-separted strings of lang codes that have been used in the past
for (const lang of store.preferences.postLanguageHistory) {
for (const lang of langPrefs.postLanguageHistory) {
add(lang)
}
@ -82,7 +90,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
onPress: onPressMore,
},
]
}, [store.preferences, onPressMore, postLanguagePref, postLanguagesPref])
}, [onPressMore, langPrefs, setLangPrefs, postLanguagesPref])
return (
<DropdownButton

View file

@ -9,11 +9,18 @@ import {deviceLocales} from 'platform/detection'
import {LANGUAGES, LANGUAGES_MAP_CODE2} from '../../../../locale/languages'
import {LanguageToggle} from './LanguageToggle'
import {ConfirmLanguagesButton} from './ConfirmLanguagesButton'
import {
useLanguagePrefs,
useSetLanguagePrefs,
toggleContentLanguage,
} from '#/state/preferences/languages'
export const snapPoints = ['100%']
export function Component({}: {}) {
const store = useStores()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useSetLanguagePrefs()
const pal = usePalette('default')
const {isMobile} = useWebMediaQueries()
const onPressDone = React.useCallback(() => {
@ -29,23 +36,23 @@ export function Component({}: {}) {
// sort so that device & selected languages are on top, then alphabetically
langs.sort((a, b) => {
const hasA =
store.preferences.hasContentLanguage(a.code2) ||
langPrefs.contentLanguages.includes(a.code2) ||
deviceLocales.includes(a.code2)
const hasB =
store.preferences.hasContentLanguage(b.code2) ||
langPrefs.contentLanguages.includes(b.code2) ||
deviceLocales.includes(b.code2)
if (hasA === hasB) return a.name.localeCompare(b.name)
if (hasA) return -1
return 1
})
return langs
}, [store])
}, [langPrefs])
const onPress = React.useCallback(
(code2: string) => {
store.preferences.toggleContentLanguage(code2)
toggleContentLanguage(langPrefs, setLangPrefs, code2)
},
[store],
[langPrefs, setLangPrefs],
)
return (

View file

@ -3,7 +3,7 @@ import {StyleSheet} from 'react-native'
import {usePalette} from 'lib/hooks/usePalette'
import {observer} from 'mobx-react-lite'
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
import {useStores} from 'state/index'
import {useLanguagePrefs, toPostLanguages} from '#/state/preferences/languages'
export const LanguageToggle = observer(function LanguageToggleImpl({
code2,
@ -17,17 +17,17 @@ export const LanguageToggle = observer(function LanguageToggleImpl({
langType: 'contentLanguages' | 'postLanguages'
}) {
const pal = usePalette('default')
const store = useStores()
const langPrefs = useLanguagePrefs()
const isSelected = store.preferences[langType].includes(code2)
const values =
langType === 'contentLanguages'
? langPrefs.contentLanguages
: toPostLanguages(langPrefs.postLanguage)
const isSelected = values.includes(code2)
// enforce a max of 3 selections for post languages
let isDisabled = false
if (
langType === 'postLanguages' &&
store.preferences[langType].length >= 3 &&
!isSelected
) {
if (langType === 'postLanguages' && values.length >= 3 && !isSelected) {
isDisabled = true
}

View file

@ -10,11 +10,19 @@ import {deviceLocales} from 'platform/detection'
import {LANGUAGES, LANGUAGES_MAP_CODE2} from '../../../../locale/languages'
import {ConfirmLanguagesButton} from './ConfirmLanguagesButton'
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
import {
useLanguagePrefs,
useSetLanguagePrefs,
hasPostLanguage,
togglePostLanguage,
} from '#/state/preferences/languages'
export const snapPoints = ['100%']
export const Component = observer(function PostLanguagesSettingsImpl() {
const store = useStores()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useSetLanguagePrefs()
const pal = usePalette('default')
const {isMobile} = useWebMediaQueries()
const onPressDone = React.useCallback(() => {
@ -30,23 +38,23 @@ export const Component = observer(function PostLanguagesSettingsImpl() {
// sort so that device & selected languages are on top, then alphabetically
langs.sort((a, b) => {
const hasA =
store.preferences.hasPostLanguage(a.code2) ||
hasPostLanguage(langPrefs.postLanguage, a.code2) ||
deviceLocales.includes(a.code2)
const hasB =
store.preferences.hasPostLanguage(b.code2) ||
hasPostLanguage(langPrefs.postLanguage, b.code2) ||
deviceLocales.includes(b.code2)
if (hasA === hasB) return a.name.localeCompare(b.name)
if (hasA) return -1
return 1
})
return langs
}, [store])
}, [langPrefs])
const onPress = React.useCallback(
(code2: string) => {
store.preferences.togglePostLanguage(code2)
togglePostLanguage(langPrefs, setLangPrefs, code2)
},
[store],
[langPrefs, setLangPrefs],
)
return (
@ -70,14 +78,11 @@ export const Component = observer(function PostLanguagesSettingsImpl() {
</Text>
<ScrollView style={styles.scrollContainer}>
{languages.map(lang => {
const isSelected = store.preferences.hasPostLanguage(lang.code2)
const isSelected = hasPostLanguage(langPrefs.postLanguage, lang.code2)
// enforce a max of 3 selections for post languages
let isDisabled = false
if (
store.preferences.postLanguage.split(',').length >= 3 &&
!isSelected
) {
if (langPrefs.postLanguage.split(',').length >= 3 && !isSelected) {
isDisabled = true
}

View file

@ -38,6 +38,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {MAX_POST_LINES} from 'lib/constants'
import {logger} from '#/logger'
import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'
import {useLanguagePrefs} from '#/state/preferences'
export const PostThreadItem = observer(function PostThreadItem({
item,
@ -54,6 +55,7 @@ export const PostThreadItem = observer(function PostThreadItem({
const store = useStores()
const mutedThreads = useMutedThreads()
const toggleThreadMute = useToggleThreadMute()
const langPrefs = useLanguagePrefs()
const [deleted, setDeleted] = React.useState(false)
const [limitLines, setLimitLines] = React.useState(
countLines(item.richText?.text) >= MAX_POST_LINES,
@ -85,15 +87,15 @@ export const PostThreadItem = observer(function PostThreadItem({
const translatorUrl = getTranslatorLink(
record?.text || '',
store.preferences.primaryLanguage,
langPrefs.primaryLanguage,
)
const needsTranslation = useMemo(
() =>
Boolean(
store.preferences.primaryLanguage &&
!isPostInLanguage(item.post, [store.preferences.primaryLanguage]),
langPrefs.primaryLanguage &&
!isPostInLanguage(item.post, [langPrefs.primaryLanguage]),
),
[item.post, store.preferences.primaryLanguage],
[item.post, langPrefs.primaryLanguage],
)
const onPressReply = React.useCallback(() => {

View file

@ -34,6 +34,7 @@ import {MAX_POST_LINES} from 'lib/constants'
import {countLines} from 'lib/strings/helpers'
import {logger} from '#/logger'
import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'
import {useLanguagePrefs} from '#/state/preferences'
export const Post = observer(function PostImpl({
view,
@ -109,6 +110,7 @@ const PostLoaded = observer(function PostLoadedImpl({
const store = useStores()
const mutedThreads = useMutedThreads()
const toggleThreadMute = useToggleThreadMute()
const langPrefs = useLanguagePrefs()
const [limitLines, setLimitLines] = React.useState(
countLines(item.richText?.text) >= MAX_POST_LINES,
)
@ -125,7 +127,7 @@ const PostLoaded = observer(function PostLoadedImpl({
const translatorUrl = getTranslatorLink(
record?.text || '',
store.preferences.primaryLanguage,
langPrefs.primaryLanguage,
)
const onPressReply = React.useCallback(() => {

View file

@ -34,6 +34,7 @@ import {MAX_POST_LINES} from 'lib/constants'
import {countLines} from 'lib/strings/helpers'
import {logger} from '#/logger'
import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'
import {useLanguagePrefs} from '#/state/preferences'
export const FeedItem = observer(function FeedItemImpl({
item,
@ -50,6 +51,7 @@ export const FeedItem = observer(function FeedItemImpl({
showReplyLine?: boolean
}) {
const store = useStores()
const langPrefs = useLanguagePrefs()
const pal = usePalette('default')
const mutedThreads = useMutedThreads()
const toggleThreadMute = useToggleThreadMute()
@ -75,7 +77,7 @@ export const FeedItem = observer(function FeedItemImpl({
}, [record?.reply])
const translatorUrl = getTranslatorLink(
record?.text || '',
store.preferences.primaryLanguage,
langPrefs.primaryLanguage,
)
const onPressReply = React.useCallback(() => {