From ee3e08393882a9d72ae9cab5f765ed2885c5a98d Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 5 Sep 2025 18:34:00 +0300 Subject: [PATCH] Restore quick language select (#8981) * restore quick language select * rm showCancel * rm margin from thread button * alf composer icons * stop hiding keyboard * use trans --- src/state/persisted/schema.ts | 4 +- src/view/com/composer/Composer.tsx | 29 ++-- .../select-language/PostLanguageSelect.tsx | 131 ++++++++++++++++++ ...ialog.tsx => PostLanguageSelectDialog.tsx} | 80 ++--------- 4 files changed, 154 insertions(+), 90 deletions(-) create mode 100644 src/view/com/composer/select-language/PostLanguageSelect.tsx rename src/view/com/composer/select-language/{SelectPostLanguagesDialog.tsx => PostLanguageSelectDialog.tsx} (81%) diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index f840081f3d..11204f3090 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -78,8 +78,8 @@ const schema = z.object({ postLanguage: z.string(), /** * The user's post language history, used to pre-populate the post language - * selector in the composer. Within each value, multiple languages are - * separated by values. + * selector in the composer. Within each value, multiple languages are separated + * by commas. * * BCP-47 2-letter language codes without region. */ diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 20f2549add..61715a988a 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -110,7 +110,6 @@ import {LabelsBtn} from '#/view/com/composer/labels/LabelsBtn' import {Gallery} from '#/view/com/composer/photos/Gallery' import {OpenCameraBtn} from '#/view/com/composer/photos/OpenCameraBtn' import {SelectGifBtn} from '#/view/com/composer/photos/SelectGifBtn' -import {SelectPostLanguagesBtn} from '#/view/com/composer/select-language/SelectPostLanguagesDialog' import {SuggestedLanguage} from '#/view/com/composer/select-language/SuggestedLanguage' // TODO: Prevent naming components that coincide with RN primitives // due to linting false positives @@ -123,14 +122,16 @@ import {Text} from '#/view/com/util/text/Text' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, native, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' -import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji' -import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo' +import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji' +import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus' +import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' import {LazyQuoteEmbed} from '#/components/Post/Embed/LazyQuoteEmbed' import * as Prompt from '#/components/Prompt' import * as Toast from '#/components/Toast' import {Text as NewText} from '#/components/Typography' import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet' +import {PostLanguageSelect} from './select-language/PostLanguageSelect' import { type AssetType, SelectMediaButton, @@ -941,7 +942,7 @@ let ComposerPost = React.memo(function ComposerPost({ }) } }}> - + - + ) : null} @@ -1440,20 +1441,16 @@ function ComposerFooter({ {showAddButton && ( )} - + - + {error} @@ -1765,7 +1762,7 @@ function ErrorBanner({ shape="round" style={[a.absolute, {top: 0, right: 0}]} onPress={onClearError}> - + {videoError && videoState.jobId && ( diff --git a/src/view/com/composer/select-language/PostLanguageSelect.tsx b/src/view/com/composer/select-language/PostLanguageSelect.tsx new file mode 100644 index 0000000000..6291e84224 --- /dev/null +++ b/src/view/com/composer/select-language/PostLanguageSelect.tsx @@ -0,0 +1,131 @@ +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {LANG_DROPDOWN_HITSLOP} from '#/lib/constants' +import {codeToLanguageName} from '#/locale/helpers' +import { + toPostLanguages, + useLanguagePrefs, + useLanguagePrefsApi, +} from '#/state/preferences/languages' +import {atoms as a, useTheme} from '#/alf' +import {Button, type ButtonProps} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron' +import {Globe_Stroke2_Corner0_Rounded as GlobeIcon} from '#/components/icons/Globe' +import * as Menu from '#/components/Menu' +import {Text} from '#/components/Typography' +import {PostLanguageSelectDialog} from './PostLanguageSelectDialog' + +export function PostLanguageSelect() { + const {_} = useLingui() + const langPrefs = useLanguagePrefs() + const setLangPrefs = useLanguagePrefsApi() + const languageDialogControl = Dialog.useDialogControl() + + const dedupedHistory = Array.from( + new Set([...langPrefs.postLanguageHistory, langPrefs.postLanguage]), + ) + + if ( + dedupedHistory.length === 1 && + dedupedHistory[0] === langPrefs.postLanguage + ) { + return ( + <> + + + + ) + } + + return ( + <> + + + {({props}) => } + + + + {dedupedHistory.map(historyItem => { + const langCodes = historyItem.split(',') + const langName = langCodes + .map(code => codeToLanguageName(code, langPrefs.appLanguage)) + .join(' + ') + return ( + setLangPrefs.setPostLanguage(historyItem)}> + {langName} + + + ) + })} + + + + + More languages... + + + + + + + + + ) +} + +function LanguageBtn(props: Omit) { + const {_} = useLingui() + const langPrefs = useLanguagePrefs() + const t = useTheme() + + const postLanguagesPref = toPostLanguages(langPrefs.postLanguage) + + return ( + + ) +} diff --git a/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx b/src/view/com/composer/select-language/PostLanguageSelectDialog.tsx similarity index 81% rename from src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx rename to src/view/com/composer/select-language/PostLanguageSelectDialog.tsx index c8ecc2b89b..1137415e63 100644 --- a/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx +++ b/src/view/com/composer/select-language/PostLanguageSelectDialog.tsx @@ -1,16 +1,13 @@ import {useCallback, useMemo, useState} from 'react' -import {Keyboard, useWindowDimensions, View} from 'react-native' +import {useWindowDimensions, View} from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {LANG_DROPDOWN_HITSLOP} from '#/lib/constants' import {languageName} from '#/locale/helpers' -import {codeToLanguageName} from '#/locale/helpers' import {type Language, LANGUAGES, LANGUAGES_MAP_CODE2} from '#/locale/languages' import {isNative, isWeb} from '#/platform/detection' import { - toPostLanguages, useLanguagePrefs, useLanguagePrefsApi, } from '#/state/preferences/languages' @@ -21,75 +18,14 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {SearchInput} from '#/components/forms/SearchInput' import * as Toggle from '#/components/forms/Toggle' -import {Globe_Stroke2_Corner0_Rounded as GlobeIcon} from '#/components/icons/Globe' import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' import {Text} from '#/components/Typography' -export function SelectPostLanguagesBtn() { - const {_} = useLingui() - const langPrefs = useLanguagePrefs() - const t = useTheme() - const control = Dialog.useDialogControl() - - const onPressMore = useCallback(async () => { - if (isNative) { - if (Keyboard.isVisible()) { - Keyboard.dismiss() - } - } - control.open() - }, [control]) - - const postLanguagesPref = toPostLanguages(langPrefs.postLanguage) - - return ( - <> - - - - - ) -} - -function LanguageDialog({control}: {control: Dialog.DialogControlProps}) { +export function PostLanguageSelectDialog({ + control, +}: { + control: Dialog.DialogControlProps +}) { const {height} = useWindowDimensions() const insets = useSafeAreaInsets() @@ -104,13 +40,13 @@ function LanguageDialog({control}: {control: Dialog.DialogControlProps}) { nativeOptions={{minHeight: height - insets.top}}> - + ) } -export function PostLanguagesSettingsDialogInner() { +export function DialogInner() { const control = Dialog.useDialogContext() const [headerHeight, setHeaderHeight] = useState(0)