Improve handling of unselecting languanges in composer language menu (#1093)

* allow toggling off/on multiple from main composer lang menu

* fix dropdown styles for long labels

* udpate model to use new string field

* update language UI

* save langs to history on submit

* remove edit

* clean up use new fields

* default to deviceLocales

* fix default valu

* feedback

* use radio icon
This commit is contained in:
Eric Bailey 2023-08-23 15:40:15 -05:00 committed by GitHub
parent acad8cb455
commit b6317d4ce7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 49 deletions

View file

@ -212,6 +212,7 @@ export const ComposePost = observer(function ComposePost({
if (!replyTo) {
store.me.mainFeed.onPostCreated()
}
store.preferences.savePostLanguageToHistory()
onPost?.()
onClose()
Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`)

View file

@ -15,7 +15,6 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useStores} from 'state/index'
import {isNative} from 'platform/detection'
import {codeToLanguageName} from '../../../../locale/helpers'
import {deviceLocales} from 'platform/detection'
export const SelectLangBtn = observer(function SelectLangBtn() {
const pal = usePalette('default')
@ -31,35 +30,48 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
}, [store])
const postLanguagesPref = store.preferences.postLanguages
const postLanguagePref = store.preferences.postLanguage
const items: DropdownItem[] = useMemo(() => {
let arr: DropdownItemButton[] = []
const add = (langCode: string) => {
const langName = codeToLanguageName(langCode)
function add(commaSeparatedLangCodes: string) {
const langCodes = commaSeparatedLangCodes.split(',')
const langName = langCodes
.map(code => codeToLanguageName(code))
.join(' + ')
/*
* Filter out any duplicates
*/
if (arr.find((item: DropdownItemButton) => item.label === langName)) {
return
}
arr.push({
icon: store.preferences.hasPostLanguage(langCode)
? ['fas', 'circle-check']
: ['far', 'circle'],
icon:
langCodes.every(code => store.preferences.hasPostLanguage(code)) &&
langCodes.length === postLanguagesPref.length
? ['fas', 'circle-dot']
: ['far', 'circle'],
label: langName,
onPress() {
store.preferences.setPostLanguage(langCode)
store.preferences.setPostLanguage(commaSeparatedLangCodes)
},
})
}
for (const lang of postLanguagesPref) {
if (postLanguagesPref.length) {
/*
* Re-join here after sanitization bc postLanguageHistory is an array of
* comma-separated strings too
*/
add(postLanguagePref)
}
// comma-separted strings of lang codes that have been used in the past
for (const lang of store.preferences.postLanguageHistory) {
add(lang)
}
for (const lang of deviceLocales) {
add(lang)
}
add('en') // english
add('ja') // japanese
add('pt') // portugese
add('de') // german
return [
{heading: true, label: 'Post language'},
@ -70,7 +82,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
onPress: onPressMore,
},
]
}, [store.preferences, postLanguagesPref, onPressMore])
}, [store.preferences, onPressMore, postLanguagePref, postLanguagesPref])
return (
<DropdownButton
@ -81,11 +93,9 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
style={styles.button}
accessibilityLabel="Language selection"
accessibilityHint="">
{store.preferences.postLanguages.length > 0 ? (
{postLanguagesPref.length > 0 ? (
<Text type="lg-bold" style={[pal.link, styles.label]} numberOfLines={1}>
{store.preferences.postLanguages
.map(lang => codeToLanguageName(lang))
.join(', ')}
{postLanguagesPref.map(lang => codeToLanguageName(lang)).join(', ')}
</Text>
) : (
<FontAwesomeIcon

View file

@ -1,17 +1,18 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {ScrollView} from '../util'
import {useStores} from 'state/index'
import {Text} from '../../util/text/Text'
import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb, deviceLocales} from 'platform/detection'
import {LANGUAGES, LANGUAGES_MAP_CODE2} from '../../../../locale/languages'
import {LanguageToggle} from './LanguageToggle'
import {ConfirmLanguagesButton} from './ConfirmLanguagesButton'
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
export const snapPoints = ['100%']
export function Component({}: {}) {
export const Component = observer(() => {
const store = useStores()
const pal = usePalette('default')
const onPressDone = React.useCallback(() => {
@ -53,23 +54,38 @@ export function Component({}: {}) {
Which languages are used in this post?
</Text>
<ScrollView style={styles.scrollContainer}>
{languages.map(lang => (
<LanguageToggle
key={lang.code2}
code2={lang.code2}
langType="postLanguages"
name={lang.name}
onPress={() => {
onPress(lang.code2)
}}
/>
))}
{languages.map(lang => {
const isSelected = store.preferences.hasPostLanguage(lang.code2)
// enforce a max of 3 selections for post languages
let isDisabled = false
if (
store.preferences.postLanguage.split(',').length >= 3 &&
!isSelected
) {
isDisabled = true
}
return (
<ToggleButton
key={lang.code2}
label={lang.name}
isSelected={isSelected}
onPress={() => (isDisabled ? undefined : onPress(lang.code2))}
style={[
pal.border,
styles.languageToggle,
isDisabled && styles.dimmed,
]}
/>
)
})}
<View style={styles.bottomSpacer} />
</ScrollView>
<ConfirmLanguagesButton onPress={onPressDone} />
</View>
)
}
})
const styles = StyleSheet.create({
container: {
@ -94,4 +110,13 @@ const styles = StyleSheet.create({
bottomSpacer: {
height: isDesktopWeb ? 0 : 60,
},
languageToggle: {
borderTopWidth: 1,
borderRadius: 0,
paddingHorizontal: 6,
paddingVertical: 12,
},
dimmed: {
opacity: 0.5,
},
})

View file

@ -319,9 +319,12 @@ const styles = StyleSheet.create({
icon: {
marginLeft: 2,
marginRight: 8,
flexShrink: 0,
},
label: {
fontSize: 18,
flexShrink: 1,
flexGrow: 1,
},
separator: {
borderTopWidth: 1,