diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 5 | ||||
-rw-r--r-- | src/view/com/post/Post.tsx | 5 | ||||
-rw-r--r-- | src/view/com/posts/FeedItem.tsx | 5 | ||||
-rw-r--r-- | src/view/index.ts | 2 | ||||
-rw-r--r-- | src/view/screens/LanguageSettings.tsx | 205 | ||||
-rw-r--r-- | src/view/screens/Settings.tsx | 17 |
6 files changed, 227 insertions, 12 deletions
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index fc0684698..b98ec805e 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -75,7 +75,10 @@ export const PostThreadItem = observer(function PostThreadItem({ }, [item.post.uri, item.post.author]) const repostsTitle = 'Reposts of this post' - const translatorUrl = getTranslatorLink(record?.text || '') + const translatorUrl = getTranslatorLink( + record?.text || '', + store.preferences.primaryLanguage, + ) const needsTranslation = useMemo( () => store.preferences.contentLanguages.length > 0 && diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index d7559e3c4..d5191cf4e 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -115,7 +115,10 @@ const PostLoaded = observer(function PostLoadedImpl({ replyAuthorDid = urip.hostname } - const translatorUrl = getTranslatorLink(record?.text || '') + const translatorUrl = getTranslatorLink( + record?.text || '', + store.preferences.primaryLanguage, + ) const onPressReply = React.useCallback(() => { store.shell.openComposer({ diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 23d8546bc..71be3969a 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -64,7 +64,10 @@ export const FeedItem = observer(function FeedItemImpl({ const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri) return urip.hostname }, [record?.reply]) - const translatorUrl = getTranslatorLink(record?.text || '') + const translatorUrl = getTranslatorLink( + record?.text || '', + store.preferences.primaryLanguage, + ) const onPressReply = React.useCallback(() => { track('FeedItem:PostReply') diff --git a/src/view/index.ts b/src/view/index.ts index 07848aa8f..1e6f27419 100644 --- a/src/view/index.ts +++ b/src/view/index.ts @@ -97,6 +97,7 @@ import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark' import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash' import {faX} from '@fortawesome/free-solid-svg-icons/faX' import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark' +import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown' export function setup() { library.add( @@ -197,5 +198,6 @@ export function setup() { faTrashCan, faX, faXmark, + faChevronDown, ) } diff --git a/src/view/screens/LanguageSettings.tsx b/src/view/screens/LanguageSettings.tsx new file mode 100644 index 000000000..8b952a564 --- /dev/null +++ b/src/view/screens/LanguageSettings.tsx @@ -0,0 +1,205 @@ +import React from 'react' +import {StyleSheet, View} from 'react-native' +import {observer} from 'mobx-react-lite' +import {Text} from '../com/util/text/Text' +import {useStores} from 'state/index' +import {s} from 'lib/styles' +import {usePalette} from 'lib/hooks/usePalette' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' +import {ViewHeader} from 'view/com/util/ViewHeader' +import {CenteredView} from 'view/com/util/Views' +import {Button} from 'view/com/util/forms/Button' +import { + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' +import {useAnalytics} from 'lib/analytics/analytics' +import {useFocusEffect} from '@react-navigation/native' +import {LANGUAGES} from 'lib/../locale/languages' +import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select' + +type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'> + +export const LanguageSettingsScreen = observer(function LanguageSettingsImpl( + _: Props, +) { + const pal = usePalette('default') + const store = useStores() + const {isTabletOrDesktop} = useWebMediaQueries() + const {screen, track} = useAnalytics() + + useFocusEffect( + React.useCallback(() => { + screen('Settings') + store.shell.setMinimalShellMode(false) + }, [screen, store]), + ) + + const onPressContentLanguages = React.useCallback(() => { + track('Settings:ContentlanguagesButtonClicked') + store.shell.openModal({name: 'content-languages-settings'}) + }, [track, store]) + + const onChangePrimaryLanguage = React.useCallback( + (value: Parameters<PickerSelectProps['onValueChange']>[0]) => { + store.preferences.setPrimaryLanguage(value) + }, + [store.preferences], + ) + + const myLanguages = React.useMemo(() => { + return ( + store.preferences.contentLanguages + .map(lang => LANGUAGES.find(l => l.code2 === lang)) + .filter(Boolean) + // @ts-ignore + .map(l => l.name) + .join(', ') + ) + }, [store.preferences.contentLanguages]) + + return ( + <CenteredView + style={[ + pal.view, + pal.border, + styles.container, + isTabletOrDesktop && styles.desktopContainer, + ]}> + <ViewHeader title="Language Settings" showOnDesktop /> + + <View style={{paddingTop: 20, paddingHorizontal: 20}}> + <View style={{paddingBottom: 20}}> + <Text type="title-sm" style={[pal.text, s.pb5]}> + Primary Language + </Text> + <Text style={[pal.text, s.pb10]}> + Select your preferred language for translations in your feed. + </Text> + + <View style={{position: 'relative'}}> + <RNPickerSelect + value={store.preferences.primaryLanguage} + onValueChange={onChangePrimaryLanguage} + items={LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({ + label: l.name, + value: l.code2, + key: l.code2 + l.code3, + }))} + style={{ + inputAndroid: { + backgroundColor: pal.viewLight.backgroundColor, + color: pal.text.color, + fontSize: 14, + letterSpacing: 0.5, + fontWeight: '500', + paddingHorizontal: 14, + paddingVertical: 8, + borderRadius: 24, + }, + inputIOS: { + backgroundColor: pal.viewLight.backgroundColor, + color: pal.text.color, + fontSize: 14, + letterSpacing: 0.5, + fontWeight: '500', + paddingHorizontal: 14, + paddingVertical: 8, + borderRadius: 24, + }, + inputWeb: { + // @ts-ignore web only + cursor: 'pointer', + '-moz-appearance': 'none', + '-webkit-appearance': 'none', + appearance: 'none', + outline: 0, + borderWidth: 0, + backgroundColor: pal.viewLight.backgroundColor, + color: pal.text.color, + fontSize: 14, + letterSpacing: 0.5, + fontWeight: '500', + paddingHorizontal: 14, + paddingVertical: 8, + borderRadius: 24, + }, + }} + /> + + <View + style={{ + position: 'absolute', + top: 1, + right: 1, + bottom: 1, + width: 40, + backgroundColor: pal.viewLight.backgroundColor, + borderRadius: 24, + pointerEvents: 'none', + alignItems: 'center', + justifyContent: 'center', + }}> + <FontAwesomeIcon + icon="chevron-down" + style={pal.text as FontAwesomeIconStyle} + /> + </View> + </View> + </View> + + <View + style={{ + height: 1, + backgroundColor: pal.border.borderColor, + marginBottom: 20, + }} + /> + + <View style={{paddingBottom: 20}}> + <Text type="title-sm" style={[pal.text, s.pb5]}> + Content Languages + </Text> + <Text style={[pal.text, s.pb10]}> + Select which languages you want your subscribed feeds to include. If + none are selected, all languages will be shown. + </Text> + + <Button + type="default" + onPress={onPressContentLanguages} + style={styles.button}> + <FontAwesomeIcon + icon={myLanguages.length ? 'check' : 'plus'} + style={pal.text as FontAwesomeIconStyle} + /> + <Text + type="button" + style={[pal.text, {flexShrink: 1, overflow: 'hidden'}]} + numberOfLines={1}> + {myLanguages.length ? myLanguages : 'Select languages'} + </Text> + </Button> + </View> + </View> + </CenteredView> + ) +}) + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingBottom: 90, + }, + desktopContainer: { + borderLeftWidth: 1, + borderRightWidth: 1, + paddingBottom: 40, + }, + button: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, +}) diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx index 1ff5f58ff..4783f3353 100644 --- a/src/view/screens/Settings.tsx +++ b/src/view/screens/Settings.tsx @@ -145,10 +145,9 @@ export const SettingsScreen = withAuthRequired( store.shell.openModal({name: 'invite-codes'}) }, [track, store]) - const onPressContentLanguages = React.useCallback(() => { - track('Settings:ContentlanguagesButtonClicked') - store.shell.openModal({name: 'content-languages-settings'}) - }, [track, store]) + const onPressLanguageSettings = React.useCallback(() => { + navigation.navigate('LanguageSettings') + }, [navigation]) const onPressSignout = React.useCallback(() => { track('Settings:SignOutButtonClicked') @@ -456,12 +455,12 @@ export const SettingsScreen = withAuthRequired( </Text> </TouchableOpacity> <TouchableOpacity - testID="contentLanguagesBtn" + testID="languageSettingsBtn" style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]} - onPress={isSwitching ? undefined : onPressContentLanguages} + onPress={isSwitching ? undefined : onPressLanguageSettings} accessibilityRole="button" - accessibilityHint="Content languages" - accessibilityLabel="Opens configurable content language settings"> + accessibilityHint="Language settings" + accessibilityLabel="Opens configurable language settings"> <View style={[styles.iconContainer, pal.btn]}> <FontAwesomeIcon icon="language" @@ -469,7 +468,7 @@ export const SettingsScreen = withAuthRequired( /> </View> <Text type="lg" style={pal.text}> - Content languages + Languages </Text> </TouchableOpacity> <TouchableOpacity |