Bluesky app fork with some witchin' additions 💫

Merge pull request #3294 from bluesky-social/samuel/alf-splash

Use ALF for Splashscreen

authored by samuel.fm and committed by

GitHub 8ad813cd 81bc3ed4

+149 -234
+56 -91
src/view/com/auth/SplashScreen.tsx
··· 1 1 import React from 'react' 2 - import {StyleSheet, TouchableOpacity, View} from 'react-native' 2 + import {View} from 'react-native' 3 3 import {useSafeAreaInsets} from 'react-native-safe-area-context' 4 - import {Text} from 'view/com/util/text/Text' 4 + 5 5 import {ErrorBoundary} from 'view/com/util/ErrorBoundary' 6 - import {s, colors} from 'lib/styles' 7 - import {usePalette} from 'lib/hooks/usePalette' 8 6 import {CenteredView} from '../util/Views' 9 7 import {Trans, msg} from '@lingui/macro' 10 8 import {useLingui} from '@lingui/react' 11 9 import {Logo} from '#/view/icons/Logo' 12 10 import {Logotype} from '#/view/icons/Logotype' 13 - import { 14 - FontAwesomeIcon, 15 - FontAwesomeIconStyle, 16 - } from '@fortawesome/react-native-fontawesome' 17 11 import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select' 18 12 import {sanitizeAppLanguageSetting} from '#/locale/helpers' 19 13 import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences' 20 14 import {APP_LANGUAGES} from '#/locale/languages' 15 + import {atoms as a, useTheme} from '#/alf' 16 + import {Text} from '#/components/Typography' 17 + import {Button, ButtonText} from '#/components/Button' 18 + import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron' 21 19 22 20 export const SplashScreen = ({ 23 21 onPressSignin, ··· 26 24 onPressSignin: () => void 27 25 onPressCreateAccount: () => void 28 26 }) => { 29 - const pal = usePalette('default') 27 + const t = useTheme() 30 28 const {_} = useLingui() 31 29 32 30 const langPrefs = useLanguagePrefs() ··· 46 44 ) 47 45 48 46 return ( 49 - <CenteredView style={[styles.container, pal.view]}> 47 + <CenteredView style={[a.h_full, a.flex_1]}> 50 48 <ErrorBoundary> 51 - <View style={styles.hero}> 49 + <View style={[{flex: 1}, a.justify_center, a.align_center]}> 52 50 <Logo width={92} fill="sky" /> 53 51 54 - <View style={{paddingTop: 40, paddingBottom: 6}}> 55 - <Logotype width={161} fill={pal.text.color} /> 52 + <View style={[a.pb_sm, a.pt_5xl]}> 53 + <Logotype width={161} fill={t.atoms.text.color} /> 56 54 </View> 57 55 58 - <Text type="lg-medium" style={[pal.textLight]}> 56 + <Text 57 + style={[a.text_md, a.font_semibold, t.atoms.text_contrast_medium]}> 59 58 <Trans>What's up?</Trans> 60 59 </Text> 61 60 </View> 62 - <View testID="signinOrCreateAccount" style={styles.btns}> 63 - <TouchableOpacity 61 + <View testID="signinOrCreateAccount"> 62 + <Button 64 63 testID="createAccountButton" 65 - style={[styles.btn, {backgroundColor: colors.blue3}]} 66 64 onPress={onPressCreateAccount} 67 65 accessibilityRole="button" 68 - accessibilityLabel={_(msg`Create new account`)} 66 + label={_(msg`Create new account`)} 69 67 accessibilityHint={_( 70 68 msg`Opens flow to create a new Bluesky account`, 71 - )}> 72 - <Text style={[s.white, styles.btnLabel]}> 69 + )} 70 + style={[a.mx_xl, a.mb_xl]} 71 + size="large" 72 + variant="solid" 73 + color="primary"> 74 + <ButtonText> 73 75 <Trans>Create a new account</Trans> 74 - </Text> 75 - </TouchableOpacity> 76 - <TouchableOpacity 76 + </ButtonText> 77 + </Button> 78 + <Button 77 79 testID="signInButton" 78 - style={[styles.btn, pal.btn]} 79 80 onPress={onPressSignin} 80 - accessibilityRole="button" 81 - accessibilityLabel={_(msg`Sign in`)} 81 + label={_(msg`Sign in`)} 82 82 accessibilityHint={_( 83 83 msg`Opens flow to sign into your existing Bluesky account`, 84 - )}> 85 - <Text style={[pal.text, styles.btnLabel]}> 84 + )} 85 + style={[a.mx_xl, a.mb_xl]} 86 + size="large" 87 + variant="solid" 88 + color="secondary"> 89 + <ButtonText> 86 90 <Trans>Sign In</Trans> 87 - </Text> 88 - </TouchableOpacity> 91 + </ButtonText> 92 + </Button> 89 93 </View> 90 - <View style={styles.footer}> 91 - <View style={{position: 'relative'}}> 94 + <View 95 + style={[ 96 + a.px_lg, 97 + a.pt_md, 98 + a.pb_2xl, 99 + a.justify_center, 100 + a.align_center, 101 + ]}> 102 + <View style={a.relative}> 92 103 <RNPickerSelect 93 104 placeholder={{}} 94 105 value={sanitizedLang} ··· 101 112 useNativeAndroidPickerStyle={false} 102 113 style={{ 103 114 inputAndroid: { 104 - color: pal.textLight.color, 115 + color: t.atoms.text_contrast_medium.color, 105 116 fontSize: 16, 106 - paddingRight: 10 + 4, 117 + paddingRight: 12 + 4, 107 118 }, 108 119 inputIOS: { 109 - color: pal.text.color, 120 + color: t.atoms.text.color, 110 121 fontSize: 16, 111 - paddingRight: 10 + 4, 122 + paddingRight: 12 + 4, 112 123 }, 113 124 }} 114 125 /> 115 126 116 127 <View 117 - style={{ 118 - position: 'absolute', 119 - top: 0, 120 - right: 0, 121 - bottom: 0, 122 - pointerEvents: 'none', 123 - alignItems: 'center', 124 - justifyContent: 'center', 125 - }}> 126 - <FontAwesomeIcon 127 - icon="chevron-down" 128 - size={10} 129 - style={pal.textLight as FontAwesomeIconStyle} 130 - /> 128 + style={[ 129 + a.absolute, 130 + a.inset_0, 131 + {left: 'auto'}, 132 + {pointerEvents: 'none'}, 133 + a.align_center, 134 + a.justify_center, 135 + ]}> 136 + <ChevronDown fill={t.atoms.text.color} size="xs" /> 131 137 </View> 132 138 </View> 133 139 </View> ··· 136 142 </CenteredView> 137 143 ) 138 144 } 139 - 140 - const styles = StyleSheet.create({ 141 - container: { 142 - height: '100%', 143 - }, 144 - hero: { 145 - flex: 2, 146 - justifyContent: 'center', 147 - alignItems: 'center', 148 - }, 149 - btns: { 150 - paddingBottom: 0, 151 - }, 152 - title: { 153 - textAlign: 'center', 154 - fontSize: 68, 155 - fontWeight: 'bold', 156 - }, 157 - subtitle: { 158 - textAlign: 'center', 159 - fontSize: 42, 160 - fontWeight: 'bold', 161 - }, 162 - btn: { 163 - borderRadius: 32, 164 - paddingVertical: 16, 165 - marginBottom: 20, 166 - marginHorizontal: 20, 167 - }, 168 - btnLabel: { 169 - textAlign: 'center', 170 - fontSize: 21, 171 - }, 172 - footer: { 173 - paddingHorizontal: 16, 174 - paddingTop: 12, 175 - paddingBottom: 24, 176 - justifyContent: 'center', 177 - alignItems: 'center', 178 - }, 179 - })
+93 -143
src/view/com/auth/SplashScreen.web.tsx
··· 1 1 import React from 'react' 2 - import {StyleSheet, TouchableOpacity, View, Pressable} from 'react-native' 2 + import {View, Pressable} from 'react-native' 3 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 - import {Text} from 'view/com/util/text/Text' 5 - import {TextLink} from '../util/Link' 6 4 import {ErrorBoundary} from 'view/com/util/ErrorBoundary' 7 - import {s, colors} from 'lib/styles' 8 - import {usePalette} from 'lib/hooks/usePalette' 9 5 import {CenteredView} from '../util/Views' 10 - import {isWeb} from 'platform/detection' 11 6 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 12 7 import {Trans, msg} from '@lingui/macro' 13 8 import {Logo} from '#/view/icons/Logo' ··· 16 11 import {sanitizeAppLanguageSetting} from '#/locale/helpers' 17 12 import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences' 18 13 import {APP_LANGUAGES} from '#/locale/languages' 14 + import {atoms as a, useTheme} from '#/alf' 15 + import {Button, ButtonText} from '#/components/Button' 16 + import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron' 17 + import {Text} from '#/components/Typography' 18 + import {InlineLink} from '#/components/Link' 19 19 20 20 export const SplashScreen = ({ 21 21 onDismiss, ··· 26 26 onPressSignin: () => void 27 27 onPressCreateAccount: () => void 28 28 }) => { 29 - const pal = usePalette('default') 30 - const {isTabletOrMobile} = useWebMediaQueries() 31 - const styles = useStyles() 32 - const isMobileWeb = isWeb && isTabletOrMobile 29 + const {_} = useLingui() 30 + const t = useTheme() 31 + const {isTabletOrMobile: isMobileWeb} = useWebMediaQueries() 33 32 34 33 return ( 35 34 <> ··· 48 47 icon="x" 49 48 size={24} 50 49 style={{ 51 - color: String(pal.text.color), 50 + color: String(t.atoms.text.color), 52 51 }} 53 52 /> 54 53 </Pressable> 55 54 )} 56 55 57 - <CenteredView style={[styles.container, pal.view]}> 56 + <CenteredView style={[a.h_full, a.flex_1]}> 58 57 <View 59 58 testID="noSessionView" 60 59 style={[ 61 - styles.containerInner, 62 - isMobileWeb && styles.containerInnerMobile, 63 - pal.border, 64 - {alignItems: 'center'}, 60 + a.h_full, 61 + a.justify_center, 62 + // @ts-ignore web only 63 + {paddingBottom: '20vh'}, 64 + isMobileWeb && a.pb_5xl, 65 + t.atoms.border_contrast_medium, 66 + a.align_center, 67 + a.gap_5xl, 65 68 ]}> 66 69 <ErrorBoundary> 67 - <Logo width={92} fill="sky" /> 70 + <View style={[a.justify_center, a.align_center]}> 71 + <Logo width={92} fill="sky" /> 72 + 73 + <View style={[a.pb_sm, a.pt_5xl]}> 74 + <Logotype width={161} fill={t.atoms.text.color} /> 75 + </View> 68 76 69 - <View style={{paddingTop: 40, paddingBottom: 20}}> 70 - <Logotype width={161} fill={pal.text.color} /> 77 + <Text 78 + style={[ 79 + a.text_md, 80 + a.font_semibold, 81 + t.atoms.text_contrast_medium, 82 + ]}> 83 + <Trans>What's up?</Trans> 84 + </Text> 71 85 </View> 72 86 73 - <View testID="signinOrCreateAccount" style={styles.btns}> 74 - <TouchableOpacity 87 + <View 88 + testID="signinOrCreateAccount" 89 + style={[a.w_full, {maxWidth: 320}]}> 90 + <Button 75 91 testID="createAccountButton" 76 - style={[styles.btn, {backgroundColor: colors.blue3}]} 77 92 onPress={onPressCreateAccount} 78 - // TODO: web accessibility 79 - accessibilityRole="button"> 80 - <Text style={[s.white, styles.btnLabel]}> 93 + accessibilityRole="button" 94 + label={_(msg`Create new account`)} 95 + accessibilityHint={_( 96 + msg`Opens flow to create a new Bluesky account`, 97 + )} 98 + style={[a.mx_xl, a.mb_xl]} 99 + size="large" 100 + variant="solid" 101 + color="primary"> 102 + <ButtonText> 81 103 <Trans>Create a new account</Trans> 82 - </Text> 83 - </TouchableOpacity> 84 - <TouchableOpacity 104 + </ButtonText> 105 + </Button> 106 + <Button 85 107 testID="signInButton" 86 - style={[styles.btn, pal.btn]} 87 108 onPress={onPressSignin} 88 - // TODO: web accessibility 89 - accessibilityRole="button"> 90 - <Text style={[pal.text, styles.btnLabel]}> 109 + label={_(msg`Sign in`)} 110 + accessibilityHint={_( 111 + msg`Opens flow to sign into your existing Bluesky account`, 112 + )} 113 + style={[a.mx_xl, a.mb_xl]} 114 + size="large" 115 + variant="solid" 116 + color="secondary"> 117 + <ButtonText> 91 118 <Trans>Sign In</Trans> 92 - </Text> 93 - </TouchableOpacity> 119 + </ButtonText> 120 + </Button> 94 121 </View> 95 122 </ErrorBoundary> 96 123 </View> 97 - <Footer styles={styles} /> 124 + <Footer /> 98 125 </CenteredView> 99 126 </> 100 127 ) 101 128 } 102 129 103 - function Footer({styles}: {styles: ReturnType<typeof useStyles>}) { 104 - const pal = usePalette('default') 105 - const {_} = useLingui() 130 + function Footer() { 131 + const t = useTheme() 106 132 107 133 const langPrefs = useLanguagePrefs() 108 134 const setLangPrefs = useLanguagePrefsApi() ··· 122 148 ) 123 149 124 150 return ( 125 - <View style={[styles.footer, pal.view, pal.border]}> 126 - <TextLink 127 - href="https://bsky.social" 128 - text={_(msg`Business`)} 129 - style={[styles.footerLink, pal.link]} 130 - /> 131 - <TextLink 132 - href="https://bsky.social/about/blog" 133 - text={_(msg`Blog`)} 134 - style={[styles.footerLink, pal.link]} 135 - /> 136 - <TextLink 137 - href="https://bsky.social/about/join" 138 - text={_(msg`Jobs`)} 139 - style={[styles.footerLink, pal.link]} 140 - /> 151 + <View 152 + style={[ 153 + a.absolute, 154 + a.inset_0, 155 + {top: 'auto'}, 156 + a.p_xl, 157 + a.border_t, 158 + a.flex_row, 159 + a.flex_wrap, 160 + a.gap_xl, 161 + a.flex_1, 162 + t.atoms.border_contrast_medium, 163 + ]}> 164 + <InlineLink to="https://bsky.social"> 165 + <Trans>Business</Trans> 166 + </InlineLink> 167 + <InlineLink to="https://bsky.social/about/blog"> 168 + <Trans>Blog</Trans> 169 + </InlineLink> 170 + <InlineLink to="https://bsky.social/about/join"> 171 + <Trans>Jobs</Trans> 172 + </InlineLink> 141 173 142 - <View style={styles.footerDivider} /> 174 + <View style={a.flex_1} /> 143 175 144 - <View 145 - style={{ 146 - flexDirection: 'row', 147 - gap: 8, 148 - alignItems: 'center', 149 - flexShrink: 1, 150 - }}> 151 - <Text aria-hidden={true} style={[pal.textLight]}> 176 + <View style={[a.flex_row, a.gap_sm, a.align_center, a.flex_shrink]}> 177 + <Text aria-hidden={true} style={t.atoms.text_contrast_medium}> 152 178 {APP_LANGUAGES.find(l => l.code2 === sanitizedLang)?.name} 153 179 </Text> 154 - <FontAwesomeIcon 155 - icon="chevron-down" 156 - size={12} 157 - style={[pal.textLight, {flexShrink: 0}]} 180 + <ChevronDown 181 + fill={t.atoms.text.color} 182 + size="xs" 183 + style={a.flex_shrink} 158 184 /> 159 185 160 186 <select ··· 183 209 </View> 184 210 ) 185 211 } 186 - const useStyles = () => { 187 - return StyleSheet.create({ 188 - container: { 189 - height: '100%', 190 - }, 191 - containerInner: { 192 - height: '100%', 193 - justifyContent: 'center', 194 - // @ts-ignore web only 195 - paddingBottom: '20vh', 196 - paddingHorizontal: 20, 197 - }, 198 - containerInnerMobile: { 199 - paddingBottom: 50, 200 - }, 201 - title: { 202 - textAlign: 'center', 203 - color: colors.blue3, 204 - fontSize: 68, 205 - fontWeight: 'bold', 206 - paddingBottom: 10, 207 - }, 208 - titleMobile: { 209 - textAlign: 'center', 210 - color: colors.blue3, 211 - fontSize: 58, 212 - fontWeight: 'bold', 213 - }, 214 - subtitle: { 215 - textAlign: 'center', 216 - color: colors.gray5, 217 - fontSize: 52, 218 - fontWeight: 'bold', 219 - paddingBottom: 30, 220 - }, 221 - subtitleMobile: { 222 - textAlign: 'center', 223 - color: colors.gray5, 224 - fontSize: 42, 225 - fontWeight: 'bold', 226 - paddingBottom: 30, 227 - }, 228 - btns: { 229 - gap: 10, 230 - justifyContent: 'center', 231 - paddingBottom: 40, 232 - }, 233 - btn: { 234 - borderRadius: 30, 235 - paddingHorizontal: 24, 236 - paddingVertical: 12, 237 - minWidth: 220, 238 - }, 239 - btnLabel: { 240 - textAlign: 'center', 241 - fontSize: 18, 242 - }, 243 - notice: { 244 - paddingHorizontal: 40, 245 - textAlign: 'center', 246 - }, 247 - footer: { 248 - position: 'absolute', 249 - left: 0, 250 - right: 0, 251 - bottom: 0, 252 - padding: 20, 253 - borderTopWidth: 1, 254 - flexDirection: 'row', 255 - flexWrap: 'wrap', 256 - gap: 20, 257 - }, 258 - footerDivider: {flexGrow: 1}, 259 - footerLink: {}, 260 - }) 261 - }