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

Configure Feed

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

at c906fea77adb2daad28a521f06e68d5bbc4bce4d 234 lines 8.9 kB view raw
1import {useCallback, useMemo, useState} from 'react' 2import {View} from 'react-native' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import { 7 type CommonNavigatorParams, 8 type NativeStackScreenProps, 9} from '#/lib/routes/types' 10import {languageName, sanitizeAppLanguageSetting} from '#/locale/helpers' 11import {APP_LANGUAGES, LANGUAGES} from '#/locale/languages' 12import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences' 13import {atoms as a, web} from '#/alf' 14import {Admonition} from '#/components/Admonition' 15import {Button} from '#/components/Button' 16import {useDialogControl} from '#/components/Dialog' 17import {LanguageSelectDialog} from '#/components/dialogs/LanguageSelectDialog' 18import * as Toggle from '#/components/forms/Toggle' 19import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus' 20import * as Layout from '#/components/Layout' 21import * as Select from '#/components/Select' 22import {Text} from '#/components/Typography' 23import * as SettingsList from './components/SettingsList' 24 25const DEDUPED_LANGUAGES = LANGUAGES.filter( 26 (lang, i, arr) => 27 lang.code2 && arr.findIndex(l => l.code2 === lang.code2) === i, 28) 29 30type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'> 31export function LanguageSettingsScreen({}: Props) { 32 const {_} = useLingui() 33 const langPrefs = useLanguagePrefs() 34 const setLangPrefs = useLanguagePrefsApi() 35 36 const contentLanguagePrefsControl = useDialogControl() 37 38 const onChangePrimaryLanguage = useCallback( 39 (value: string) => { 40 if (!value) return 41 if (langPrefs.primaryLanguage !== value) { 42 setLangPrefs.setPrimaryLanguage(value) 43 } 44 }, 45 [langPrefs, setLangPrefs], 46 ) 47 48 const onChangeAppLanguage = useCallback( 49 (value: string) => { 50 if (!value) return 51 if (langPrefs.appLanguage !== value) { 52 setLangPrefs.setAppLanguage(sanitizeAppLanguageSetting(value)) 53 } 54 }, 55 [langPrefs, setLangPrefs], 56 ) 57 58 const [recentLanguages, setRecentLanguages] = useState<string[]>( 59 langPrefs.contentLanguages, 60 ) 61 62 const possibleLanguages = useMemo(() => { 63 return [ 64 ...new Set([ 65 ...recentLanguages, 66 ...langPrefs.contentLanguages, 67 ...langPrefs.primaryLanguage, 68 ]), 69 ] 70 .map(lang => LANGUAGES.find(l => l.code2 === lang)) 71 .filter(x => !!x) 72 }, [recentLanguages, langPrefs.contentLanguages, langPrefs.primaryLanguage]) 73 74 return ( 75 <Layout.Screen testID="PreferencesLanguagesScreen"> 76 <Layout.Header.Outer> 77 <Layout.Header.BackButton /> 78 <Layout.Header.Content> 79 <Layout.Header.TitleText> 80 <Trans>Languages</Trans> 81 </Layout.Header.TitleText> 82 </Layout.Header.Content> 83 <Layout.Header.Slot /> 84 </Layout.Header.Outer> 85 <Layout.Content> 86 <SettingsList.Container> 87 <SettingsList.Group iconInset={false}> 88 <SettingsList.ItemText> 89 <Trans>App language</Trans> 90 </SettingsList.ItemText> 91 <View style={[a.gap_md, a.w_full]}> 92 <Text style={[a.leading_snug]}> 93 <Trans> 94 Select which language to use for the app's user interface. 95 </Trans> 96 </Text> 97 <Select.Root 98 value={sanitizeAppLanguageSetting(langPrefs.appLanguage)} 99 onValueChange={onChangeAppLanguage}> 100 <Select.Trigger label={_(msg`Select app language`)}> 101 <Select.ValueText /> 102 <Select.Icon /> 103 </Select.Trigger> 104 <Select.Content 105 label={_(msg`App language`)} 106 renderItem={({label, value}) => ( 107 <Select.Item value={value} label={label}> 108 <Select.ItemIndicator /> 109 <Select.ItemText>{label}</Select.ItemText> 110 </Select.Item> 111 )} 112 items={APP_LANGUAGES.map(l => ({ 113 label: l.name, 114 value: l.code2, 115 }))} 116 /> 117 </Select.Root> 118 </View> 119 </SettingsList.Group> 120 <SettingsList.Divider /> 121 <SettingsList.Group iconInset={false}> 122 <SettingsList.ItemText> 123 <Trans>Primary language</Trans> 124 </SettingsList.ItemText> 125 <View style={[a.gap_md, a.w_full]}> 126 <Text style={[a.leading_snug]}> 127 <Trans> 128 Select your preferred language for translations in your feed. 129 </Trans> 130 </Text> 131 <Select.Root 132 value={langPrefs.primaryLanguage} 133 onValueChange={onChangePrimaryLanguage}> 134 <Select.Trigger label={_(msg`Select primary language`)}> 135 <Select.ValueText /> 136 <Select.Icon /> 137 </Select.Trigger> 138 <Select.Content 139 label={_(msg`Primary language`)} 140 renderItem={({label, value}) => ( 141 <Select.Item value={value} label={label}> 142 <Select.ItemIndicator /> 143 <Select.ItemText>{label}</Select.ItemText> 144 </Select.Item> 145 )} 146 items={DEDUPED_LANGUAGES.map(l => ({ 147 label: languageName(l, langPrefs.appLanguage), 148 value: l.code2, 149 }))} 150 /> 151 </Select.Root> 152 </View> 153 </SettingsList.Group> 154 <SettingsList.Divider /> 155 <SettingsList.Group iconInset={false}> 156 <SettingsList.ItemText> 157 <Trans>Content languages</Trans> 158 </SettingsList.ItemText> 159 <View style={[a.gap_md]}> 160 <Text style={[a.leading_snug]}> 161 <Trans> 162 Select which languages you want your subscribed feeds to 163 include. If none are selected, all languages will be shown. 164 </Trans> 165 </Text> 166 167 {langPrefs.contentLanguages.length === 0 && ( 168 <Admonition type="info"> 169 <Trans>All languages will be shown in your feeds.</Trans> 170 </Admonition> 171 )} 172 173 <View style={[a.w_full, web({maxWidth: 400})]}> 174 <Toggle.Group 175 label={_(msg`Select content languages`)} 176 values={langPrefs.contentLanguages} 177 onChange={setLangPrefs.setContentLanguages}> 178 <Toggle.PanelGroup> 179 {possibleLanguages.map((language, index) => { 180 const name = languageName(language, langPrefs.appLanguage) 181 return ( 182 <Toggle.Item 183 key={language.code2} 184 name={language.code2} 185 label={name}> 186 {({selected}) => ( 187 <Toggle.Panel 188 active={selected} 189 adjacent={index === 0 ? 'trailing' : 'both'}> 190 <Toggle.Checkbox /> 191 <Toggle.PanelText>{name}</Toggle.PanelText> 192 </Toggle.Panel> 193 )} 194 </Toggle.Item> 195 ) 196 })} 197 <Button 198 label={_(msg`Add more languages...`)} 199 onPress={contentLanguagePrefsControl.open}> 200 <Toggle.Panel adjacent="leading"> 201 <Toggle.PanelIcon icon={PlusIcon} /> 202 <Toggle.PanelText> 203 Add more languages... 204 </Toggle.PanelText> 205 </Toggle.Panel> 206 </Button> 207 </Toggle.PanelGroup> 208 </Toggle.Group> 209 </View> 210 211 <LanguageSelectDialog 212 control={contentLanguagePrefsControl} 213 titleText={<Trans>Select content languages</Trans>} 214 subtitleText={ 215 <Trans> 216 If none are selected, all languages will be shown in your 217 feeds. 218 </Trans> 219 } 220 currentLanguages={langPrefs.contentLanguages} 221 onSelectLanguages={languages => { 222 setLangPrefs.setContentLanguages(languages) 223 setRecentLanguages(recent => [ 224 ...new Set([...recent, ...languages]), 225 ]) 226 }} 227 /> 228 </View> 229 </SettingsList.Group> 230 </SettingsList.Container> 231 </Layout.Content> 232 </Layout.Screen> 233 ) 234}