Bluesky app fork with some witchin' additions 馃挮
at main 176 lines 5.5 kB view raw
1import {msg} from '@lingui/core/macro' 2import {useLingui} from '@lingui/react' 3import {Trans} from '@lingui/react/macro' 4 5import {LANG_DROPDOWN_HITSLOP} from '#/lib/constants' 6import {codeToLanguageName} from '#/locale/helpers' 7import { 8 toPostLanguages, 9 useLanguagePrefs, 10 useLanguagePrefsApi, 11} from '#/state/preferences/languages' 12import {atoms as a, useTheme} from '#/alf' 13import {Button, type ButtonProps} from '#/components/Button' 14import * as Dialog from '#/components/Dialog' 15import {LanguageSelectDialog} from '#/components/dialogs/LanguageSelectDialog' 16import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron' 17import {Globe_Stroke2_Corner0_Rounded as GlobeIcon} from '#/components/icons/Globe' 18import * as Menu from '#/components/Menu' 19import {Text} from '#/components/Typography' 20 21export function PostLanguageSelect({ 22 currentLanguages: currentLanguagesProp, 23 onSelectLanguage, 24}: { 25 currentLanguages?: string[] 26 onSelectLanguage?: (language: string) => void 27}) { 28 const {_} = useLingui() 29 const langPrefs = useLanguagePrefs() 30 const setLangPrefs = useLanguagePrefsApi() 31 const languageDialogControl = Dialog.useDialogControl() 32 33 const dedupedHistory = Array.from( 34 new Set([...langPrefs.postLanguageHistory, langPrefs.postLanguage]), 35 ) 36 37 const currentLanguages = 38 currentLanguagesProp ?? toPostLanguages(langPrefs.postLanguage) 39 40 const onSelectLanguages = (languages: string[]) => { 41 let langsString = languages.join(',') 42 if (!langsString) { 43 langsString = langPrefs.primaryLanguage 44 } 45 setLangPrefs.setPostLanguage(langsString) 46 onSelectLanguage?.(langsString) 47 } 48 49 if ( 50 dedupedHistory.length === 1 && 51 dedupedHistory[0] === langPrefs.postLanguage 52 ) { 53 return ( 54 <> 55 <LanguageBtn onPress={languageDialogControl.open} /> 56 <LanguageSelectDialog 57 titleText={<Trans>Choose post languages</Trans>} 58 subtitleText={ 59 <Trans>Select up to 3 languages used in this post</Trans> 60 } 61 control={languageDialogControl} 62 currentLanguages={currentLanguages} 63 onSelectLanguages={onSelectLanguages} 64 maxLanguages={3} 65 /> 66 </> 67 ) 68 } 69 70 return ( 71 <> 72 <Menu.Root> 73 <Menu.Trigger label={_(msg`Select post language`)}> 74 {({props}) => ( 75 <LanguageBtn currentLanguages={currentLanguages} {...props} /> 76 )} 77 </Menu.Trigger> 78 <Menu.Outer> 79 <Menu.Group> 80 {dedupedHistory.map(historyItem => { 81 const langCodes = historyItem.split(',') 82 const langName = langCodes 83 .map(code => codeToLanguageName(code, langPrefs.appLanguage)) 84 .join(' + ') 85 return ( 86 <Menu.Item 87 key={historyItem} 88 label={_(msg`Select ${langName}`)} 89 onPress={() => { 90 setLangPrefs.setPostLanguage(historyItem) 91 onSelectLanguage?.(historyItem) 92 }}> 93 <Menu.ItemText>{langName}</Menu.ItemText> 94 <Menu.ItemRadio 95 selected={currentLanguages.includes(historyItem)} 96 /> 97 </Menu.Item> 98 ) 99 })} 100 </Menu.Group> 101 <Menu.Divider /> 102 <Menu.Item 103 label={_(msg`More languages...`)} 104 onPress={languageDialogControl.open}> 105 <Menu.ItemText> 106 <Trans>More languages...</Trans> 107 </Menu.ItemText> 108 <Menu.ItemIcon icon={ChevronRightIcon} /> 109 </Menu.Item> 110 </Menu.Outer> 111 </Menu.Root> 112 113 <LanguageSelectDialog 114 titleText={<Trans>Choose post languages</Trans>} 115 subtitleText={<Trans>Select up to 3 languages used in this post</Trans>} 116 control={languageDialogControl} 117 currentLanguages={currentLanguages} 118 onSelectLanguages={onSelectLanguages} 119 maxLanguages={3} 120 /> 121 </> 122 ) 123} 124 125function LanguageBtn( 126 props: Omit<ButtonProps, 'label' | 'children'> & { 127 currentLanguages?: string[] 128 }, 129) { 130 const {_} = useLingui() 131 const langPrefs = useLanguagePrefs() 132 const t = useTheme() 133 134 const postLanguagesPref = toPostLanguages(langPrefs.postLanguage) 135 const currentLanguages = props.currentLanguages ?? postLanguagesPref 136 137 return ( 138 <Button 139 testID="selectLangBtn" 140 size="small" 141 hitSlop={LANG_DROPDOWN_HITSLOP} 142 label={_( 143 msg({ 144 message: `Post language selection`, 145 comment: `Accessibility label for button that opens dialog to choose post language settings`, 146 }), 147 )} 148 accessibilityHint={_(msg`Opens post language settings`)} 149 style={[a.mr_xs]} 150 {...props}> 151 {({pressed, hovered}) => { 152 const color = 153 pressed || hovered ? t.palette.primary_300 : t.palette.primary_500 154 if (currentLanguages.length > 0) { 155 return ( 156 <Text 157 style={[ 158 {color}, 159 a.font_semi_bold, 160 a.text_sm, 161 a.leading_snug, 162 {maxWidth: 100}, 163 ]} 164 numberOfLines={1}> 165 {currentLanguages 166 .map(lang => codeToLanguageName(lang, langPrefs.appLanguage)) 167 .join(', ')} 168 </Text> 169 ) 170 } else { 171 return <GlobeIcon size="xs" style={{color}} /> 172 } 173 }} 174 </Button> 175 ) 176}