about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/view/com/auth/SplashScreen.tsx75
-rw-r--r--src/view/com/auth/SplashScreen.web.tsx79
2 files changed, 146 insertions, 8 deletions
diff --git a/src/view/com/auth/SplashScreen.tsx b/src/view/com/auth/SplashScreen.tsx
index ffd07d945..4fd800c3b 100644
--- a/src/view/com/auth/SplashScreen.tsx
+++ b/src/view/com/auth/SplashScreen.tsx
@@ -9,6 +9,14 @@ import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {Logo} from '#/view/icons/Logo'
 import {Logotype} from '#/view/icons/Logotype'
+import {
+  FontAwesomeIcon,
+  FontAwesomeIconStyle,
+} from '@fortawesome/react-native-fontawesome'
+import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select'
+import {sanitizeAppLanguageSetting} from '#/locale/helpers'
+import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
+import {APP_LANGUAGES} from '#/locale/languages'
 
 export const SplashScreen = ({
   onPressSignin,
@@ -20,6 +28,21 @@ export const SplashScreen = ({
   const pal = usePalette('default')
   const {_} = useLingui()
 
+  const langPrefs = useLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
+
+  const sanitizedLang = sanitizeAppLanguageSetting(langPrefs.appLanguage)
+
+  const onChangeAppLanguage = React.useCallback(
+    (value: Parameters<PickerSelectProps['onValueChange']>[0]) => {
+      if (!value) return
+      if (sanitizedLang !== value) {
+        setLangPrefs.setAppLanguage(sanitizeAppLanguageSetting(value))
+      }
+    },
+    [sanitizedLang, setLangPrefs],
+  )
+
   return (
     <CenteredView style={[styles.container, pal.view]}>
       <ErrorBoundary>
@@ -58,6 +81,50 @@ export const SplashScreen = ({
             </Text>
           </TouchableOpacity>
         </View>
+        <View style={styles.footer}>
+          <View style={{position: 'relative'}}>
+            <RNPickerSelect
+              placeholder={{}}
+              value={sanitizedLang}
+              onValueChange={onChangeAppLanguage}
+              items={APP_LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
+                label: l.name,
+                value: l.code2,
+                key: l.code2,
+              }))}
+              useNativeAndroidPickerStyle={false}
+              style={{
+                inputAndroid: {
+                  color: pal.textLight.color,
+                  fontSize: 16,
+                  paddingRight: 10 + 4,
+                },
+                inputIOS: {
+                  color: pal.text.color,
+                  fontSize: 16,
+                  paddingRight: 10 + 4,
+                },
+              }}
+            />
+
+            <View
+              style={{
+                position: 'absolute',
+                top: 0,
+                right: 0,
+                bottom: 0,
+                pointerEvents: 'none',
+                alignItems: 'center',
+                justifyContent: 'center',
+              }}>
+              <FontAwesomeIcon
+                icon="chevron-down"
+                size={10}
+                style={pal.textLight as FontAwesomeIconStyle}
+              />
+            </View>
+          </View>
+        </View>
       </ErrorBoundary>
     </CenteredView>
   )
@@ -73,7 +140,7 @@ const styles = StyleSheet.create({
     alignItems: 'center',
   },
   btns: {
-    paddingBottom: 40,
+    paddingBottom: 0,
   },
   title: {
     textAlign: 'center',
@@ -95,4 +162,10 @@ const styles = StyleSheet.create({
     textAlign: 'center',
     fontSize: 21,
   },
+  footer: {
+    paddingHorizontal: 16,
+    paddingVertical: 12,
+    justifyContent: 'center',
+    alignItems: 'center',
+  },
 })
diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx
index 8ef64099f..f1921c7ff 100644
--- a/src/view/com/auth/SplashScreen.web.tsx
+++ b/src/view/com/auth/SplashScreen.web.tsx
@@ -9,9 +9,13 @@ import {usePalette} from 'lib/hooks/usePalette'
 import {CenteredView} from '../util/Views'
 import {isWeb} from 'platform/detection'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {Trans} from '@lingui/macro'
+import {Trans, msg} from '@lingui/macro'
 import {Logo} from '#/view/icons/Logo'
 import {Logotype} from '#/view/icons/Logotype'
+import {useLingui} from '@lingui/react'
+import {sanitizeAppLanguageSetting} from '#/locale/helpers'
+import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
+import {APP_LANGUAGES} from '#/locale/languages'
 
 export const SplashScreen = ({
   onDismiss,
@@ -98,24 +102,84 @@ export const SplashScreen = ({
 
 function Footer({styles}: {styles: ReturnType<typeof useStyles>}) {
   const pal = usePalette('default')
+  const {_} = useLingui()
+
+  const langPrefs = useLanguagePrefs()
+  const setLangPrefs = useLanguagePrefsApi()
+
+  const sanitizedLang = sanitizeAppLanguageSetting(langPrefs.appLanguage)
+
+  const onChangeAppLanguage = React.useCallback(
+    (ev: React.ChangeEvent<HTMLSelectElement>) => {
+      const value = ev.target.value
+
+      if (!value) return
+      if (sanitizedLang !== value) {
+        setLangPrefs.setAppLanguage(sanitizeAppLanguageSetting(value))
+      }
+    },
+    [sanitizedLang, setLangPrefs],
+  )
 
   return (
     <View style={[styles.footer, pal.view, pal.border]}>
       <TextLink
         href="https://bsky.social"
-        text="Business"
+        text={_(msg`Business`)}
         style={[styles.footerLink, pal.link]}
       />
       <TextLink
         href="https://bsky.social/about/blog"
-        text="Blog"
+        text={_(msg`Blog`)}
         style={[styles.footerLink, pal.link]}
       />
       <TextLink
         href="https://bsky.social/about/join"
-        text="Jobs"
+        text={_(msg`Jobs`)}
         style={[styles.footerLink, pal.link]}
       />
+
+      <View style={styles.footerDivider} />
+
+      <View
+        style={{
+          flexDirection: 'row',
+          gap: 8,
+          alignItems: 'center',
+          flexShrink: 1,
+        }}>
+        <Text aria-hidden={true} style={[pal.textLight]}>
+          {APP_LANGUAGES.find(l => l.code2 === sanitizedLang)?.name}
+        </Text>
+        <FontAwesomeIcon
+          icon="chevron-down"
+          size={12}
+          style={[pal.textLight, {flexShrink: 0}]}
+        />
+
+        <select
+          value={sanitizedLang}
+          onChange={onChangeAppLanguage}
+          style={{
+            cursor: 'pointer',
+            MozAppearance: 'none',
+            WebkitAppearance: 'none',
+            appearance: 'none',
+            position: 'absolute',
+            inset: 0,
+            width: '100%',
+            color: 'transparent',
+            background: 'transparent',
+            border: 0,
+            padding: 0,
+          }}>
+          {APP_LANGUAGES.filter(l => Boolean(l.code2)).map(l => (
+            <option key={l.code2} value={l.code2}>
+              {l.name}
+            </option>
+          ))}
+        </select>
+      </View>
     </View>
   )
 }
@@ -188,9 +252,10 @@ const useStyles = () => {
       padding: 20,
       borderTopWidth: 1,
       flexDirection: 'row',
+      flexWrap: 'wrap',
+      gap: 20,
     },
-    footerLink: {
-      marginRight: 20,
-    },
+    footerDivider: {flexGrow: 1},
+    footerLink: {},
   })
 }