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