Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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