new illustration for splash screen

This commit is contained in:
Samuel Newman
2026-01-02 16:17:50 +02:00
parent 7147b17a9b
commit e7c14204a3
6 changed files with 95 additions and 113 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

+6 -1
View File
@@ -3,10 +3,15 @@ import Svg, {Path} from 'react-native-svg'
import {type Props, useCommonSVGProps} from './common' import {type Props, useCommonSVGProps} from './common'
import {createSinglePathSVG} from './TEMPLATE' import {createSinglePathSVG} from './TEMPLATE'
export const Mark = createSinglePathSVG({ export const LogoMark = createSinglePathSVG({
path: 'M6.335 4.212c2.293 1.76 4.76 5.327 5.665 7.241.906-1.914 3.372-5.482 5.665-7.241C19.319 2.942 22 1.96 22 5.086c0 .624-.35 5.244-.556 5.994-.713 2.608-3.315 3.273-5.629 2.87 4.045.704 5.074 3.035 2.852 5.366-4.22 4.426-6.066-1.111-6.54-2.53-.086-.26-.126-.382-.127-.278 0-.104-.041.018-.128.278-.473 1.419-2.318 6.956-6.539 2.53-2.222-2.331-1.193-4.662 2.852-5.366-2.314.403-4.916-.262-5.63-2.87C2.35 10.33 2 5.71 2 5.086c0-3.126 2.68-2.144 4.335-.874Z', path: 'M6.335 4.212c2.293 1.76 4.76 5.327 5.665 7.241.906-1.914 3.372-5.482 5.665-7.241C19.319 2.942 22 1.96 22 5.086c0 .624-.35 5.244-.556 5.994-.713 2.608-3.315 3.273-5.629 2.87 4.045.704 5.074 3.035 2.852 5.366-4.22 4.426-6.066-1.111-6.54-2.53-.086-.26-.126-.382-.127-.278 0-.104-.041.018-.128.278-.473 1.419-2.318 6.956-6.539 2.53-2.222-2.331-1.193-4.662 2.852-5.366-2.314.403-4.916-.262-5.63-2.87C2.35 10.33 2 5.71 2 5.086c0-3.126 2.68-2.144 4.335-.874Z',
}) })
export const LogoType = createSinglePathSVG({
path: 'm68.737 11.077 5.607-5.781h7.584l1.12 3.485c.828 2.621 1.55 5.215 2.19 7.781.588-2.215 1.335-4.81 2.216-7.754l1.121-3.512H92.1l-5.313 15.076c-.56 1.54-1.255 2.648-2.136 3.27-.88.62-2.136.918-3.79.918-.561 0-1.041-.027-1.468-.081v-2.675h1.28c1.523 0 2.27-.946 2.27-2.242 0-.649-.213-1.595-.64-2.811L78.31 5.334l-5.167 5.23 5.526 8.673h-3.845l-4.004-6.484-2.083 2.107v4.377h-3.31V0h3.31v11.077ZM57.498 4.972c3.924 0 5.953 1.566 6.087 4.727h-3.177c-.08-1.702-1.068-2.296-2.91-2.296q-2.403 0-2.403 1.621c0 .973.694 1.405 2.296 1.703l1.735.27c3.337.62 4.78 1.864 4.78 4.241 0 2.81-2.243 4.377-6.114 4.377-4.004 0-6.114-1.594-6.3-4.81h3.282c.187 1.73 1.042 2.379 3.07 2.379 1.816 0 2.724-.568 2.724-1.675 0-1-.64-1.487-2.696-1.838l-1.575-.27c-3.017-.513-4.512-1.918-4.512-4.214 0-2.621 2.056-4.215 5.713-4.215Zm-31.497 8.997c0 1.756.855 2.647 2.59 2.647 1.628 0 3.07-1.216 3.07-3.512V5.296h3.363v13.941h-3.256v-2.026q-1.562 2.35-4.325 2.35c-2.91 0-4.805-1.783-4.805-5.025v-9.24H26v8.673Zm17.527-8.997c2.083 0 3.738.702 4.966 2.08s1.842 3.215 1.842 5.458v.81H40.03c.24 2.405 1.549 3.593 3.577 3.593 1.549 0 2.59-.675 3.15-1.999h3.231c-.72 2.837-3.123 4.647-6.407 4.647-2.056 0-3.711-.676-4.966-2-1.254-1.323-1.895-3.08-1.895-5.294 0-2.189.614-3.945 1.869-5.296 1.254-1.324 2.883-2 4.938-2ZM8.597 0c4.137 0 6.14 2.135 6.14 4.972 0 1.89-.855 3.269-2.537 4.133 2.163.784 3.31 2.594 3.31 4.62 0 3.432-2.269 5.512-6.62 5.512H0V0h8.597Zm11.91 19.237h-3.363V0h3.364v19.237ZM3.605 16.211h5.1c2.028 0 3.122-.945 3.122-2.647q0-2.675-3.123-2.675H3.604v5.322Zm39.898-8.592c-1.842 0-3.124 1.08-3.444 3.323h6.915c-.294-2.026-1.522-3.323-3.471-3.323Zm-39.898.405H8.33c1.842 0 2.83-.972 2.83-2.593 0-1.486-1.014-2.432-2.83-2.432H3.604v5.025Z',
viewBox: '0 0 93 25',
})
export function Full( export function Full(
props: Omit<Props, 'fill' | 'size' | 'height'> & { props: Omit<Props, 'fill' | 'size' | 'height'> & {
markFill?: Props['fill'] markFill?: Props['fill']
+8 -26
View File
@@ -42,7 +42,8 @@ export function createSinglePathSVG({
strokeLinejoin?: 'miter' | 'round' | 'bevel' strokeLinejoin?: 'miter' | 'round' | 'bevel'
}) { }) {
return React.forwardRef<Svg, Props>(function LogoImpl(props, ref) { return React.forwardRef<Svg, Props>(function LogoImpl(props, ref) {
const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) const {fill, width, height, style, gradient, ...rest} =
useCommonSVGProps(props)
const hasStroke = strokeWidth > 0 const hasStroke = strokeWidth > 0
@@ -52,8 +53,8 @@ export function createSinglePathSVG({
{...rest} {...rest}
ref={ref} ref={ref}
viewBox={viewBox || '0 0 24 24'} viewBox={viewBox || '0 0 24 24'}
width={size} width={width}
height={size} height={height}
style={[style]}> style={[style]}>
{gradient} {gradient}
<Path <Path
@@ -71,29 +72,10 @@ export function createSinglePathSVG({
}) })
} }
export function createSinglePathSVG2({path}: {path: string}) {
return React.forwardRef<Svg, Props>(function LogoImpl(props, ref) {
const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props)
return (
<Svg
fill="none"
{...rest}
ref={ref}
viewBox="0 0 24 24"
width={size}
height={size}
style={style}>
{gradient}
<Path fill={fill} fillRule="evenodd" clipRule="evenodd" d={path} />
</Svg>
)
})
}
export function createMultiPathSVG({paths}: {paths: string[]}) { export function createMultiPathSVG({paths}: {paths: string[]}) {
return React.forwardRef<Svg, Props>(function LogoImpl(props, ref) { return React.forwardRef<Svg, Props>(function LogoImpl(props, ref) {
const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) const {fill, width, height, style, gradient, ...rest} =
useCommonSVGProps(props)
return ( return (
<Svg <Svg
@@ -101,8 +83,8 @@ export function createMultiPathSVG({paths}: {paths: string[]}) {
{...rest} {...rest}
ref={ref} ref={ref}
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={width}
height={size} height={height}
style={[style]}> style={[style]}>
{gradient} {gradient}
{paths.map((path, i) => ( {paths.map((path, i) => (
+8
View File
@@ -28,6 +28,12 @@ export function useCommonSVGProps(props: Props) {
const {fill, size, gradient, ...rest} = props const {fill, size, gradient, ...rest} = props
const style = StyleSheet.flatten(rest.style) const style = StyleSheet.flatten(rest.style)
const _size = Number(size ? sizes[size] : rest.width || sizes.md) const _size = Number(size ? sizes[size] : rest.width || sizes.md)
let _width = _size
let _height = _size
if (!size && rest.width && rest.height) {
_width = Number(rest.width)
_height = Number(rest.height)
}
let _fill = fill || style?.color || t.palette.primary_500 let _fill = fill || style?.color || t.palette.primary_500
let gradientDef = null let gradientDef = null
@@ -55,6 +61,8 @@ export function useCommonSVGProps(props: Props) {
return { return {
fill: _fill, fill: _fill,
size: _size, size: _size,
width: _width,
height: _height,
style, style,
gradient: gradientDef, gradient: gradientDef,
...rest, ...rest,
+5 -1
View File
@@ -7,6 +7,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {PressableScale} from '#/lib/custom-animations/PressableScale' import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {isNative} from '#/platform/detection'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {profilesQueryKey} from '#/state/queries/profile' import {profilesQueryKey} from '#/state/queries/profile'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
@@ -77,13 +78,16 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
clearRequestedAccount() clearRequestedAccount()
}, [clearRequestedAccount, onDismiss]) }, [clearRequestedAccount, onDismiss])
const fullBleed =
isNative && screenState === ScreenState.S_LoginOrCreateAccount
return ( return (
<View <View
testID="noSessionView" testID="noSessionView"
style={[ style={[
a.util_screen_outer, a.util_screen_outer,
t.atoms.bg, t.atoms.bg,
{paddingTop: insets.top, paddingBottom: insets.bottom}, !fullBleed && {paddingTop: insets.top, paddingBottom: insets.bottom},
]}> ]}>
<ErrorBoundary> <ErrorBoundary>
{onDismiss && screenState === ScreenState.S_LoginOrCreateAccount ? ( {onDismiss && screenState === ScreenState.S_LoginOrCreateAccount ? (
+68 -85
View File
@@ -1,18 +1,17 @@
import {View} from 'react-native' import {View} from 'react-native'
import {SystemBars} from 'react-native-edge-to-edge'
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {ImageBackground} from 'expo-image'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useHaptics} from '#/lib/haptics' import {useHaptics} from '#/lib/haptics'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' import {atoms as a, ThemeProvider, tokens, useTheme} from '#/alf'
import {CenteredView} from '#/view/com/util/Views'
import {Logo} from '#/view/icons/Logo'
import {Logotype} from '#/view/icons/Logotype'
import {atoms as a, useTheme} from '#/alf'
import {AppLanguageDropdown} from '#/components/AppLanguageDropdown'
import {Button, ButtonText} from '#/components/Button' import {Button, ButtonText} from '#/components/Button'
import {Text} from '#/components/Typography' import {LogoMark, LogoType} from '#/components/icons/Logo'
const BACKGROUND_GREEN = '#689C60'
export const SplashScreen = ({ export const SplashScreen = ({
onPressSignin, onPressSignin,
@@ -28,83 +27,67 @@ export const SplashScreen = ({
const insets = useSafeAreaInsets() const insets = useSafeAreaInsets()
return ( return (
<CenteredView style={[a.h_full, a.flex_1]}> <Animated.View
<Animated.View style={[a.h_full, a.flex_1, {backgroundColor: BACKGROUND_GREEN}]}
entering={FadeIn.duration(90)} entering={FadeIn.duration(90)}
exiting={FadeOut.duration(90)} exiting={FadeOut.duration(90)}>
style={[a.flex_1]}> <SystemBars style={{statusBar: 'dark'}} />
<ErrorBoundary> <ImageBackground
<View style={[a.flex_1, a.justify_center, a.align_center]}> source={require('../../../../assets/splash-illustration.webp')}
<Logo width={92} fill="sky" /> contentFit="cover"
style={[a.flex_1, a.align_center]}>
<View style={[a.pb_sm, a.pt_5xl]}> <Animated.View
<Logotype width={161} fill={t.atoms.text.color} /> style={[a.absolute, {top: '15%'}, a.align_center, a.gap_2xs]}>
</View> <LogoMark width={85} />
<LogoType width={92.1} height={24.56} />
<Text </Animated.View>
style={[ </ImageBackground>
a.text_md, <ThemeProvider theme="dark">
a.font_semi_bold, <View
t.atoms.text_contrast_medium, style={[
a.text_center, a.w_full,
]}> a.flex_shrink_0,
<Trans>What's up?</Trans> a.px_5xl,
</Text> a.gap_sm,
</View> {paddingBottom: insets.bottom + tokens.space.sm},
]}>
<View <Button
testID="signinOrCreateAccount" testID="createAccountButton"
style={[a.px_xl, a.gap_md, a.pb_2xl]}> onPress={() => {
<Button onPressCreateAccount()
testID="createAccountButton" playHaptic('Light')
onPress={() => { }}
onPressCreateAccount() label={_(msg`Get started`)}
playHaptic('Light') accessibilityHint={_(
}} msg`Opens flow to create a new Bluesky account`,
label={_(msg`Create new account`)} )}
accessibilityHint={_( size="large"
msg`Opens flow to create a new Bluesky account`, color="secondary_inverted"
)} style={[{backgroundColor: t.palette.white}, a.shadow_sm]}>
size="large" <ButtonText>
variant="solid" <Trans>Get started</Trans>
color="primary"> </ButtonText>
<ButtonText> </Button>
<Trans>Create account</Trans> <Button
</ButtonText> testID="signInButton"
</Button> onPress={() => {
<Button onPressSignin()
testID="signInButton" playHaptic('Light')
onPress={() => { }}
onPressSignin() label={_(msg`Sign in`)}
playHaptic('Light') accessibilityHint={_(
}} msg`Opens flow to sign in to your existing Bluesky account`,
label={_(msg`Sign in`)} )}
accessibilityHint={_( size="large"
msg`Opens flow to sign in to your existing Bluesky account`, color="secondary"
)} style={[a.bg_transparent]}
size="large" hoverStyle={[a.bg_transparent, {opacity: 0.8}]}>
variant="solid" <ButtonText style={{color: t.palette.white}}>
color="secondary"> <Trans>Sign in</Trans>
<ButtonText> </ButtonText>
<Trans>Sign in</Trans> </Button>
</ButtonText> </View>
</Button> </ThemeProvider>
</View> </Animated.View>
<View
style={[
a.px_lg,
a.pt_md,
a.pb_2xl,
a.justify_center,
a.align_center,
]}>
<View>
<AppLanguageDropdown />
</View>
</View>
<View style={{height: insets.bottom}} />
</ErrorBoundary>
</Animated.View>
</CenteredView>
) )
} }