Bluesky app fork with some witchin' additions 馃挮
at post-text-option 247 lines 8.2 kB view raw
1import {useEffect, useState} from 'react' 2import {Pressable, View} from 'react-native' 3import {ImageBackground} from 'expo-image' 4import {msg, Trans} from '@lingui/macro' 5import {useLingui} from '@lingui/react' 6import {FocusGuards, FocusScope} from 'radix-ui/internal' 7 8import {logger} from '#/logger' 9import {useLoggedOutViewControls} from '#/state/shell/logged-out' 10import {Logo} from '#/view/icons/Logo' 11import {atoms as a, flatten, useBreakpoints, web} from '#/alf' 12import {Button, ButtonText} from '#/components/Button' 13import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' 14import {Text} from '#/components/Typography' 15 16const welcomeModalBg = require('../../assets/images/welcome-modal-bg.jpg') // TODO: Xan: Change background to something cuter 17 18interface WelcomeModalProps { 19 control: { 20 isOpen: boolean 21 open: () => void 22 close: () => void 23 } 24} 25 26export function WelcomeModal({control}: WelcomeModalProps) { 27 const {_} = useLingui() 28 const {requestSwitchToAccount} = useLoggedOutViewControls() 29 const {gtMobile} = useBreakpoints() 30 const [isExiting, setIsExiting] = useState(false) 31 const [signInLinkHovered, setSignInLinkHovered] = useState(false) 32 33 const fadeOutAndClose = (callback?: () => void) => { 34 setIsExiting(true) 35 setTimeout(() => { 36 control.close() 37 if (callback) callback() 38 }, 150) 39 } 40 41 useEffect(() => { 42 if (control.isOpen) { 43 logger.metric('welcomeModal:presented', {}) 44 } 45 }, [control.isOpen]) 46 47 const onPressCreateAccount = () => { 48 logger.metric('welcomeModal:signupClicked', {}) 49 control.close() 50 requestSwitchToAccount({requestedAccount: 'new'}) 51 } 52 53 const onPressExplore = () => { 54 logger.metric('welcomeModal:exploreClicked', {}) 55 fadeOutAndClose() 56 } 57 58 const onPressSignIn = () => { 59 logger.metric('welcomeModal:signinClicked', {}) 60 control.close() 61 requestSwitchToAccount({requestedAccount: 'existing'}) 62 } 63 64 FocusGuards.useFocusGuards() 65 66 return ( 67 <View 68 role="dialog" 69 aria-modal 70 style={[ 71 a.fixed, 72 a.inset_0, 73 a.justify_center, 74 a.align_center, 75 {zIndex: 9999, backgroundColor: 'rgba(0,0,0,0.2)'}, 76 web({backdropFilter: 'blur(15px)'}), 77 isExiting ? a.fade_out : a.fade_in, 78 ]}> 79 <FocusScope.FocusScope asChild loop trapped> 80 <View 81 style={flatten([ 82 { 83 maxWidth: 800, 84 maxHeight: 600, 85 width: '90%', 86 height: '90%', 87 backgroundColor: '#716066', 88 }, 89 a.rounded_lg, 90 a.overflow_hidden, 91 a.zoom_in, 92 ])}> 93 <ImageBackground 94 source={welcomeModalBg} 95 style={[a.flex_1, a.justify_center]} 96 contentFit="cover"> 97 <View style={[a.gap_2xl, a.align_center, a.p_4xl]}> 98 <View 99 style={[ 100 a.flex_row, 101 a.align_center, 102 a.justify_center, 103 a.w_full, 104 a.p_0, 105 ]}> 106 <View style={[a.flex_row, a.align_center, a.gap_xs]}> 107 <Logo width={26} /> 108 <Text 109 style={[ 110 a.text_2xl, 111 a.font_semi_bold, 112 a.user_select_none, 113 {color: '#ff9696ff', letterSpacing: -0.5}, 114 ]}> 115 Witchsky 116 </Text> 117 </View> 118 </View> 119 <View 120 style={[ 121 a.gap_sm, 122 a.align_center, 123 a.pt_5xl, 124 a.pb_3xl, 125 a.mt_2xl, 126 ]}> 127 <Text 128 style={[ 129 gtMobile ? a.text_4xl : a.text_3xl, 130 a.font_semi_bold, 131 a.text_center, 132 {color: '#583535ff'}, 133 web({ 134 backgroundImage: 135 'linear-gradient(180deg, #ffd8d8ff 0%, #eca8a8ff 83.65%, rgba(233, 165, 165, 0.47) 100%)', 136 backgroundClip: 'text', 137 WebkitBackgroundClip: 'text', 138 WebkitTextFillColor: 'transparent', 139 color: 'transparent', 140 lineHeight: 1.2, 141 letterSpacing: -0.5, 142 }), 143 ]}> 144 <Trans>Real talk.</Trans> 145 {'\n'} 146 <Trans>Real creatures.</Trans> 147 {'\n'} 148 <Trans>Social media if it was good.</Trans> 149 </Text> 150 </View> 151 <View style={[a.gap_md, a.align_center]}> 152 <View> 153 <Button 154 onPress={onPressCreateAccount} 155 label={_(msg`Create account`)} 156 size="large" 157 color="primary" 158 style={{ 159 width: 200, 160 backgroundColor: '#BB6868', 161 }}> 162 <ButtonText> 163 <Trans>Create account</Trans> 164 </ButtonText> 165 </Button> 166 <Button 167 onPress={onPressExplore} 168 label={_(msg`Explore the app`)} 169 size="large" 170 color="primary" 171 variant="ghost" 172 style={[a.bg_transparent, {width: 200}]} 173 hoverStyle={[a.bg_transparent]}> 174 {({hovered}) => ( 175 <ButtonText 176 style={[hovered && [a.underline], {color: '#ff9191'}]}> 177 <Trans>Explore the app</Trans> 178 </ButtonText> 179 )} 180 </Button> 181 </View> 182 <View style={[a.align_center, {minWidth: 200}]}> 183 <Text 184 style={[ 185 a.text_md, 186 a.text_center, 187 {color: '#ffe3e3ff', lineHeight: 24}, 188 ]}> 189 <Trans>Already have an account?</Trans>{' '} 190 <Pressable 191 onPointerEnter={() => setSignInLinkHovered(true)} 192 onPointerLeave={() => setSignInLinkHovered(false)} 193 accessibilityRole="button" 194 accessibilityLabel={_(msg`Sign in`)} 195 accessibilityHint=""> 196 <Text 197 style={[ 198 a.font_medium, 199 { 200 color: '#ff9191', 201 fontSize: undefined, 202 }, 203 signInLinkHovered && a.underline, 204 ]} 205 onPress={onPressSignIn}> 206 <Trans>Sign in</Trans> 207 </Text> 208 </Pressable> 209 </Text> 210 </View> 211 </View> 212 </View> 213 <Button 214 label={_(msg`Close welcome modal`)} 215 style={[ 216 a.absolute, 217 { 218 top: 8, 219 right: 8, 220 }, 221 a.bg_transparent, 222 ]} 223 hoverStyle={[a.bg_transparent]} 224 onPress={() => { 225 logger.metric('welcomeModal:dismissed', {}) 226 fadeOutAndClose() 227 }} 228 color="secondary" 229 size="small" 230 variant="ghost" 231 shape="round"> 232 {({hovered, pressed, focused}) => ( 233 <XIcon 234 size="md" 235 style={{ 236 color: '#ffe3e3ff', 237 opacity: hovered || pressed || focused ? 1 : 0.7, 238 }} 239 /> 240 )} 241 </Button> 242 </ImageBackground> 243 </View> 244 </FocusScope.FocusScope> 245 </View> 246 ) 247}