about summary refs log tree commit diff
path: root/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-09-05 18:34:00 +0300
committerGitHub <noreply@github.com>2025-09-05 08:34:00 -0700
commitee3e08393882a9d72ae9cab5f765ed2885c5a98d (patch)
treea18396cf22b84b22073059922819e278890cc36a /src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx
parent0f089060d2596bf75f141d1d574f14952bca1066 (diff)
downloadvoidsky-ee3e08393882a9d72ae9cab5f765ed2885c5a98d.tar.zst
Restore quick language select (#8981)
* restore quick language select

* rm showCancel

* rm margin from thread button

* alf composer icons

* stop hiding keyboard

* use trans
Diffstat (limited to 'src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx')
-rw-r--r--src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx382
1 files changed, 0 insertions, 382 deletions
diff --git a/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx b/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx
deleted file mode 100644
index c8ecc2b89..000000000
--- a/src/view/com/composer/select-language/SelectPostLanguagesDialog.tsx
+++ /dev/null
@@ -1,382 +0,0 @@
-import {useCallback, useMemo, useState} from 'react'
-import {Keyboard, 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'
-import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
-import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
-import {atoms as a, useTheme, web} from '#/alf'
-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 (
-    <>
-      <Button
-        testID="selectLangBtn"
-        onPress={onPressMore}
-        size="small"
-        hitSlop={LANG_DROPDOWN_HITSLOP}
-        label={_(
-          msg({
-            message: `Post language selection`,
-            comment: `Accessibility label for button that opens dialog to choose post language settings`,
-          }),
-        )}
-        accessibilityHint={_(msg`Opens post language settings`)}
-        style={[a.mx_md]}>
-        {({pressed, hovered, focused}) => {
-          const color =
-            pressed || hovered || focused
-              ? t.palette.primary_300
-              : t.palette.primary_500
-          if (postLanguagesPref.length > 0) {
-            return (
-              <Text
-                style={[
-                  {color},
-                  a.font_bold,
-                  a.text_sm,
-                  a.leading_snug,
-                  {maxWidth: 100},
-                ]}
-                numberOfLines={1}>
-                {postLanguagesPref
-                  .map(lang => codeToLanguageName(lang, langPrefs.appLanguage))
-                  .join(', ')}
-              </Text>
-            )
-          } else {
-            return <GlobeIcon size="xs" style={{color}} />
-          }
-        }}
-      </Button>
-
-      <LanguageDialog control={control} />
-    </>
-  )
-}
-
-function LanguageDialog({control}: {control: Dialog.DialogControlProps}) {
-  const {height} = useWindowDimensions()
-  const insets = useSafeAreaInsets()
-
-  const renderErrorBoundary = useCallback(
-    (error: any) => <DialogError details={String(error)} />,
-    [],
-  )
-
-  return (
-    <Dialog.Outer
-      control={control}
-      nativeOptions={{minHeight: height - insets.top}}>
-      <Dialog.Handle />
-      <ErrorBoundary renderError={renderErrorBoundary}>
-        <PostLanguagesSettingsDialogInner />
-      </ErrorBoundary>
-    </Dialog.Outer>
-  )
-}
-
-export function PostLanguagesSettingsDialogInner() {
-  const control = Dialog.useDialogContext()
-  const [headerHeight, setHeaderHeight] = useState(0)
-
-  const allowedLanguages = useMemo(() => {
-    const uniqueLanguagesMap = LANGUAGES.filter(lang => !!lang.code2).reduce(
-      (acc, lang) => {
-        acc[lang.code2] = lang
-        return acc
-      },
-      {} as Record<string, Language>,
-    )
-
-    return Object.values(uniqueLanguagesMap)
-  }, [])
-
-  const langPrefs = useLanguagePrefs()
-  const [checkedLanguagesCode2, setCheckedLanguagesCode2] = useState<string[]>(
-    langPrefs.postLanguage.split(',') || [langPrefs.primaryLanguage],
-  )
-  const [search, setSearch] = useState('')
-
-  const setLangPrefs = useLanguagePrefsApi()
-  const t = useTheme()
-  const {_} = useLingui()
-
-  const handleClose = () => {
-    control.close(() => {
-      let langsString = checkedLanguagesCode2.join(',')
-      if (!langsString) {
-        langsString = langPrefs.primaryLanguage
-      }
-      setLangPrefs.setPostLanguage(langsString)
-    })
-  }
-
-  // NOTE(@elijaharita): Displayed languages are split into 3 lists for
-  // ordering.
-  const displayedLanguages = useMemo(() => {
-    function mapCode2List(code2List: string[]) {
-      return code2List.map(code2 => LANGUAGES_MAP_CODE2[code2]).filter(Boolean)
-    }
-
-    // NOTE(@elijaharita): Get recent language codes and map them to language
-    // objects. Both the user account's saved language history and the current
-    // checked languages are displayed here.
-    const recentLanguagesCode2 =
-      Array.from(
-        new Set([...checkedLanguagesCode2, ...langPrefs.postLanguageHistory]),
-      ).slice(0, 5) || []
-    const recentLanguages = mapCode2List(recentLanguagesCode2)
-
-    // NOTE(@elijaharita): helper functions
-    const matchesSearch = (lang: Language) =>
-      lang.name.toLowerCase().includes(search.toLowerCase())
-    const isChecked = (lang: Language) =>
-      checkedLanguagesCode2.includes(lang.code2)
-    const isInRecents = (lang: Language) =>
-      recentLanguagesCode2.includes(lang.code2)
-
-    const checkedRecent = recentLanguages.filter(isChecked)
-
-    if (search) {
-      // NOTE(@elijaharita): if a search is active, we ALWAYS show checked
-      // items, as well as any items that match the search.
-      const uncheckedRecent = recentLanguages
-        .filter(lang => !isChecked(lang))
-        .filter(matchesSearch)
-      const unchecked = allowedLanguages.filter(lang => !isChecked(lang))
-      const all = unchecked
-        .filter(matchesSearch)
-        .filter(lang => !isInRecents(lang))
-
-      return {
-        all,
-        checkedRecent,
-        uncheckedRecent,
-      }
-    } else {
-      // NOTE(@elijaharita): if no search is active, we show everything.
-      const uncheckedRecent = recentLanguages.filter(lang => !isChecked(lang))
-      const all = allowedLanguages
-        .filter(lang => !recentLanguagesCode2.includes(lang.code2))
-        .filter(lang => !isInRecents(lang))
-
-      return {
-        all,
-        checkedRecent,
-        uncheckedRecent,
-      }
-    }
-  }, [
-    allowedLanguages,
-    search,
-    langPrefs.postLanguageHistory,
-    checkedLanguagesCode2,
-  ])
-
-  const listHeader = (
-    <View
-      style={[a.pb_xs, t.atoms.bg, isNative && a.pt_2xl]}
-      onLayout={evt => setHeaderHeight(evt.nativeEvent.layout.height)}>
-      <View style={[a.flex_row, a.w_full, a.justify_between]}>
-        <View>
-          <Text
-            nativeID="dialog-title"
-            style={[
-              t.atoms.text,
-              a.text_left,
-              a.font_bold,
-              a.text_xl,
-              a.mb_sm,
-            ]}>
-            <Trans>Choose Post Languages</Trans>
-          </Text>
-          <Text
-            nativeID="dialog-description"
-            style={[
-              t.atoms.text_contrast_medium,
-              a.text_left,
-              a.text_md,
-              a.mb_lg,
-            ]}>
-            <Trans>Select up to 3 languages used in this post</Trans>
-          </Text>
-        </View>
-
-        {isWeb && (
-          <Button
-            variant="ghost"
-            size="small"
-            color="secondary"
-            shape="round"
-            label={_(msg`Close dialog`)}
-            onPress={handleClose}>
-            <ButtonIcon icon={XIcon} />
-          </Button>
-        )}
-      </View>
-
-      <View style={[a.w_full, a.flex_row, a.align_stretch, a.gap_xs, a.pb_0]}>
-        <SearchInput
-          value={search}
-          onChangeText={setSearch}
-          placeholder={_(msg`Search languages`)}
-          label={_(msg`Search languages`)}
-          maxLength={50}
-          onClearText={() => setSearch('')}
-        />
-      </View>
-    </View>
-  )
-
-  const isCheckedRecentEmpty =
-    displayedLanguages.checkedRecent.length > 0 ||
-    displayedLanguages.uncheckedRecent.length > 0
-
-  const isDisplayedLanguagesEmpty = displayedLanguages.all.length === 0
-
-  const flatListData = [
-    ...(isCheckedRecentEmpty
-      ? [{type: 'header', label: _(msg`Recently used`)}]
-      : []),
-    ...displayedLanguages.checkedRecent.map(lang => ({type: 'item', lang})),
-    ...displayedLanguages.uncheckedRecent.map(lang => ({type: 'item', lang})),
-    ...(isDisplayedLanguagesEmpty
-      ? []
-      : [{type: 'header', label: _(msg`All languages`)}]),
-    ...displayedLanguages.all.map(lang => ({type: 'item', lang})),
-  ]
-
-  return (
-    <Toggle.Group
-      values={checkedLanguagesCode2}
-      onChange={setCheckedLanguagesCode2}
-      type="checkbox"
-      maxSelections={3}
-      label={_(msg`Select languages`)}
-      style={web([a.contents])}>
-      <Dialog.InnerFlatList
-        data={flatListData}
-        ListHeaderComponent={listHeader}
-        stickyHeaderIndices={[0]}
-        contentContainerStyle={[a.gap_0]}
-        style={[isNative && a.px_lg, web({paddingBottom: 120})]}
-        scrollIndicatorInsets={{top: headerHeight}}
-        renderItem={({item, index}) => {
-          if (item.type === 'header') {
-            return (
-              <Text
-                key={index}
-                style={[
-                  a.px_0,
-                  a.py_md,
-                  a.font_bold,
-                  a.text_xs,
-                  t.atoms.text_contrast_low,
-                  a.pt_3xl,
-                ]}>
-                {item.label}
-              </Text>
-            )
-          }
-          const lang = item.lang
-
-          return (
-            <Toggle.Item
-              key={lang.code2}
-              name={lang.code2}
-              label={languageName(lang, langPrefs.appLanguage)}
-              style={[
-                t.atoms.border_contrast_low,
-                a.border_b,
-                a.rounded_0,
-                a.px_0,
-                a.py_md,
-              ]}>
-              <Toggle.LabelText style={[a.flex_1]}>
-                {languageName(lang, langPrefs.appLanguage)}
-              </Toggle.LabelText>
-              <Toggle.Checkbox />
-            </Toggle.Item>
-          )
-        }}
-        footer={
-          <Dialog.FlatListFooter>
-            <Button
-              label={_(msg`Close dialog`)}
-              onPress={handleClose}
-              color="primary"
-              size="large">
-              <ButtonText>
-                <Trans>Done</Trans>
-              </ButtonText>
-            </Button>
-          </Dialog.FlatListFooter>
-        }
-      />
-    </Toggle.Group>
-  )
-}
-
-function DialogError({details}: {details?: string}) {
-  const {_} = useLingui()
-  const control = Dialog.useDialogContext()
-
-  return (
-    <Dialog.ScrollableInner
-      style={a.gap_md}
-      label={_(msg`An error has occurred`)}>
-      <Dialog.Close />
-      <ErrorScreen
-        title={_(msg`Oh no!`)}
-        message={_(
-          msg`There was an unexpected issue in the application. Please let us know if this happened to you!`,
-        )}
-        details={details}
-      />
-      <Button
-        label={_(msg`Close dialog`)}
-        onPress={() => control.close()}
-        color="primary"
-        size="large">
-        <ButtonText>
-          <Trans>Close</Trans>
-        </ButtonText>
-      </Button>
-    </Dialog.ScrollableInner>
-  )
-}