mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Handle pushing to starterpack screen when unauthed (#4692)

authored by hailey.at and committed by

GitHub 8ebf9cc4 91c4aa7c

+142 -131
+12 -4
src/screens/Signup/StepInfo/index.tsx
··· 1 - import React from 'react' 2 - import {View} from 'react-native' 1 + import React, {useEffect} from 'react' 2 + import {LayoutAnimation, View} from 'react-native' 3 3 import {msg, Trans} from '@lingui/macro' 4 4 import {useLingui} from '@lingui/react' 5 5 ··· 27 27 return date 28 28 } 29 29 30 - export function StepInfo() { 30 + export function StepInfo({ 31 + isLoadingStarterPack, 32 + }: { 33 + isLoadingStarterPack: boolean 34 + }) { 31 35 const {_} = useLingui() 32 36 const {state, dispatch} = useSignupContext() 37 + 38 + useEffect(() => { 39 + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) 40 + }, [state.isLoading, isLoadingStarterPack]) 33 41 34 42 return ( 35 43 <ScreenTransition> ··· 46 54 } 47 55 /> 48 56 </View> 49 - {state.isLoading ? ( 57 + {state.isLoading || isLoadingStarterPack ? ( 50 58 <View style={[a.align_center]}> 51 59 <Loader size="xl" /> 52 60 </View>
+33 -30
src/screens/Signup/index.tsx
··· 1 1 import React from 'react' 2 2 import {View} from 'react-native' 3 - import Animated, { 4 - FadeIn, 5 - FadeOut, 6 - LayoutAnimationConfig, 7 - } from 'react-native-reanimated' 3 + import {LayoutAnimationConfig} from 'react-native-reanimated' 8 4 import {AppBskyGraphStarterpack} from '@atproto/api' 9 5 import {msg, Trans} from '@lingui/macro' 10 6 import {useLingui} from '@lingui/react' ··· 47 43 const agent = useAgent() 48 44 49 45 const activeStarterPack = useActiveStarterPack() 50 - const {data: starterPack} = useStarterPackQuery({ 46 + const { 47 + data: starterPack, 48 + isFetching: isFetchingStarterPack, 49 + isError: isErrorStarterPack, 50 + } = useStarterPackQuery({ 51 51 uri: activeStarterPack?.uri, 52 52 }) 53 + const showStarterPackCard = 54 + activeStarterPack?.uri && !isFetchingStarterPack && starterPack 53 55 54 56 const { 55 57 data: serviceInfo, ··· 155 157 description={_(msg`We're so excited to have you join us!`)} 156 158 scrollable> 157 159 <View testID="createAccount" style={a.flex_1}> 158 - {state.activeStep === SignupStep.INFO && 159 - starterPack && 160 + {showStarterPackCard && 160 161 AppBskyGraphStarterpack.isRecord(starterPack.record) ? ( 161 - <Animated.View entering={FadeIn} exiting={FadeOut}> 162 - <LinearGradientBackground 163 - style={[a.mx_lg, a.p_lg, a.gap_sm, a.rounded_sm]}> 164 - <Text style={[a.font_bold, a.text_xl, {color: 'white'}]}> 165 - {starterPack.record.name} 166 - </Text> 167 - <Text style={[{color: 'white'}]}> 168 - {starterPack.feeds?.length ? ( 169 - <Trans> 170 - You'll follow the suggested users and feeds once you 171 - finish creating your account! 172 - </Trans> 173 - ) : ( 174 - <Trans> 175 - You'll follow the suggested users once you finish creating 176 - your account! 177 - </Trans> 178 - )} 179 - </Text> 180 - </LinearGradientBackground> 181 - </Animated.View> 162 + <LinearGradientBackground 163 + style={[a.mx_lg, a.p_lg, a.gap_sm, a.rounded_sm]}> 164 + <Text style={[a.font_bold, a.text_xl, {color: 'white'}]}> 165 + {starterPack.record.name} 166 + </Text> 167 + <Text style={[{color: 'white'}]}> 168 + {starterPack.feeds?.length ? ( 169 + <Trans> 170 + You'll follow the suggested users and feeds once you finish 171 + creating your account! 172 + </Trans> 173 + ) : ( 174 + <Trans> 175 + You'll follow the suggested users once you finish creating 176 + your account! 177 + </Trans> 178 + )} 179 + </Text> 180 + </LinearGradientBackground> 182 181 ) : null} 183 182 <View 184 183 style={[ ··· 211 210 <View style={[a.pb_3xl]}> 212 211 <LayoutAnimationConfig skipEntering skipExiting> 213 212 {state.activeStep === SignupStep.INFO ? ( 214 - <StepInfo /> 213 + <StepInfo 214 + isLoadingStarterPack={ 215 + isFetchingStarterPack && !isErrorStarterPack 216 + } 217 + /> 215 218 ) : state.activeStep === SignupStep.HANDLE ? ( 216 219 <StepHandle /> 217 220 ) : (
-2
src/screens/Signup/state.ts
··· 116 116 break 117 117 } 118 118 case 'setServiceDescription': { 119 - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) 120 - 121 119 next.serviceDescription = a.value 122 120 next.userDomain = a.value?.availableUserDomains[0] ?? '' 123 121 next.isLoading = false
+82 -70
src/screens/StarterPack/StarterPackScreen.tsx
··· 28 28 import {makeProfileLink, makeStarterPackLink} from 'lib/routes/links' 29 29 import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types' 30 30 import {logEvent} from 'lib/statsig/statsig' 31 - import { 32 - createStarterPackUri, 33 - getStarterPackOgCard, 34 - } from 'lib/strings/starter-pack' 31 + import {getStarterPackOgCard} from 'lib/strings/starter-pack' 35 32 import {isWeb} from 'platform/detection' 36 33 import {updateProfileShadow} from 'state/cache/profile-shadow' 37 34 import {useModerationOpts} from 'state/preferences/moderation-opts' ··· 41 38 import {useShortenLink} from 'state/queries/shorten-link' 42 39 import {useStarterPackQuery} from 'state/queries/starter-packs' 43 40 import {useAgent, useSession} from 'state/session' 41 + import {useLoggedOutViewControls} from 'state/shell/logged-out' 44 42 import {useSetActiveStarterPack} from 'state/shell/starter-pack' 45 43 import * as Toast from '#/view/com/util/Toast' 46 44 import {PagerWithHeader} from 'view/com/pager/PagerWithHeader' ··· 78 76 > 79 77 80 78 export function StarterPackScreen({route}: StarterPackScreeProps) { 81 - return <StarterPackAuthCheck routeParams={route.params} /> 79 + return <StarterPackScreenInner routeParams={route.params} /> 82 80 } 83 81 84 82 export function StarterPackScreenShort({route}: StarterPackScreenShortProps) { ··· 101 99 /> 102 100 ) 103 101 } 104 - return <StarterPackAuthCheck routeParams={resolvedStarterPack} /> 105 - } 106 - 107 - export function StarterPackAuthCheck({ 108 - routeParams, 109 - }: { 110 - routeParams: StarterPackScreeProps['route']['params'] 111 - }) { 112 - const navigation = useNavigation<NavigationProp>() 113 - const setActiveStarterPack = useSetActiveStarterPack() 114 - const {currentAccount} = useSession() 115 - 116 - React.useEffect(() => { 117 - if (currentAccount) return 118 - 119 - const uri = createStarterPackUri({ 120 - did: routeParams.name, 121 - rkey: routeParams.rkey, 122 - }) 123 - 124 - if (!uri) return 125 - setActiveStarterPack({ 126 - uri, 127 - }) 128 - 129 - navigation.goBack() 130 - }, [routeParams, currentAccount, navigation, setActiveStarterPack]) 131 - 132 - if (!currentAccount) return null 133 - 134 - return <StarterPackScreenInner routeParams={routeParams} /> 102 + return <StarterPackScreenInner routeParams={resolvedStarterPack} /> 135 103 } 136 104 137 105 export function StarterPackScreenInner({ ··· 330 298 }) { 331 299 const {_} = useLingui() 332 300 const t = useTheme() 333 - const {currentAccount} = useSession() 301 + const {currentAccount, hasSession} = useSession() 334 302 const agent = useAgent() 335 303 const queryClient = useQueryClient() 304 + const setActiveStarterPack = useSetActiveStarterPack() 305 + const {requestSwitchToAccount} = useLoggedOutViewControls() 336 306 337 307 const [isProcessing, setIsProcessing] = React.useState(false) 338 308 339 309 const {record, creator} = starterPack 340 310 const isOwn = creator?.did === currentAccount?.did 341 311 const joinedAllTimeCount = starterPack.joinedAllTimeCount ?? 0 312 + 313 + const navigation = useNavigation<NavigationProp>() 314 + 315 + React.useEffect(() => { 316 + const onFocus = () => { 317 + if (hasSession) return 318 + setActiveStarterPack({ 319 + uri: starterPack.uri, 320 + }) 321 + } 322 + const onBeforeRemove = () => { 323 + if (hasSession) return 324 + setActiveStarterPack(undefined) 325 + } 326 + 327 + navigation.addListener('focus', onFocus) 328 + navigation.addListener('beforeRemove', onBeforeRemove) 329 + 330 + return () => { 331 + navigation.removeListener('focus', onFocus) 332 + navigation.removeListener('beforeRemove', onBeforeRemove) 333 + } 334 + }, [hasSession, navigation, setActiveStarterPack, starterPack.uri]) 342 335 343 336 const onFollowAll = async () => { 344 337 if (!starterPack.list) return ··· 397 390 avatar={undefined} 398 391 creator={creator} 399 392 avatarType="starter-pack"> 400 - <View style={[a.flex_row, a.gap_sm, a.align_center]}> 401 - {isOwn ? ( 402 - <Button 403 - label={_(msg`Share this starter pack`)} 404 - hitSlop={HITSLOP_20} 405 - variant="solid" 406 - color="primary" 407 - size="small" 408 - onPress={onOpenShareDialog}> 409 - <ButtonText> 410 - <Trans>Share</Trans> 411 - </ButtonText> 412 - </Button> 413 - ) : ( 393 + {hasSession ? ( 394 + <View style={[a.flex_row, a.gap_sm, a.align_center]}> 395 + {isOwn ? ( 396 + <Button 397 + label={_(msg`Share this starter pack`)} 398 + hitSlop={HITSLOP_20} 399 + variant="solid" 400 + color="primary" 401 + size="small" 402 + onPress={onOpenShareDialog}> 403 + <ButtonText> 404 + <Trans>Share</Trans> 405 + </ButtonText> 406 + </Button> 407 + ) : ( 408 + <Button 409 + label={_(msg`Follow all`)} 410 + variant="solid" 411 + color="primary" 412 + size="small" 413 + disabled={isProcessing} 414 + onPress={onFollowAll}> 415 + <ButtonText> 416 + <Trans>Follow all</Trans> 417 + {isProcessing && <Loader size="xs" />} 418 + </ButtonText> 419 + </Button> 420 + )} 421 + <OverflowMenu 422 + routeParams={routeParams} 423 + starterPack={starterPack} 424 + onOpenShareDialog={onOpenShareDialog} 425 + /> 426 + </View> 427 + ) : null} 428 + </ProfileSubpageHeader> 429 + {!hasSession || richText || joinedAllTimeCount >= 25 ? ( 430 + <View style={[a.px_lg, a.pt_md, a.pb_sm, a.gap_md]}> 431 + {richText ? ( 432 + <RichText value={richText} style={[a.text_md, a.leading_snug]} /> 433 + ) : null} 434 + {!hasSession ? ( 414 435 <Button 415 - label={_(msg`Follow all`)} 436 + label={_(msg`Join Bluesky`)} 437 + onPress={() => { 438 + setActiveStarterPack({ 439 + uri: starterPack.uri, 440 + }) 441 + requestSwitchToAccount({requestedAccount: 'new'}) 442 + }} 416 443 variant="solid" 417 444 color="primary" 418 - size="small" 419 - disabled={isProcessing} 420 - onPress={onFollowAll}> 421 - <ButtonText> 422 - <Trans>Follow all</Trans> 423 - {isProcessing && <Loader size="xs" />} 445 + size="medium"> 446 + <ButtonText style={[a.text_lg]}> 447 + <Trans>Join Bluesky</Trans> 424 448 </ButtonText> 425 449 </Button> 426 - )} 427 - <OverflowMenu 428 - routeParams={routeParams} 429 - starterPack={starterPack} 430 - onOpenShareDialog={onOpenShareDialog} 431 - /> 432 - </View> 433 - </ProfileSubpageHeader> 434 - {richText || joinedAllTimeCount >= 25 ? ( 435 - <View style={[a.px_lg, a.pt_md, a.pb_sm, a.gap_md]}> 436 - {richText ? ( 437 - <RichText value={richText} style={[a.text_md, a.leading_snug]} /> 438 450 ) : null} 439 451 {joinedAllTimeCount >= 25 ? ( 440 452 <View style={[a.flex_row, a.align_center, a.gap_sm]}>
+15 -5
src/state/queries/starter-packs.ts
··· 25 25 parseStarterPackUri, 26 26 } from 'lib/strings/starter-pack' 27 27 import {invalidateActorStarterPacksQuery} from 'state/queries/actor-starter-packs' 28 + import {STALE} from 'state/queries/index' 28 29 import {invalidateListMembersQuery} from 'state/queries/list-members' 29 30 import {useAgent} from 'state/session' 30 31 31 32 const RQKEY_ROOT = 'starter-pack' 32 - const RQKEY = (did?: string, rkey?: string) => { 33 - if (did?.startsWith('https://') || did?.startsWith('at://')) { 34 - const parsed = parseStarterPackUri(did) 33 + const RQKEY = ({ 34 + uri, 35 + did, 36 + rkey, 37 + }: { 38 + uri?: string 39 + did?: string 40 + rkey?: string 41 + }) => { 42 + if (uri?.startsWith('https://') || uri?.startsWith('at://')) { 43 + const parsed = parseStarterPackUri(uri) 35 44 return [RQKEY_ROOT, parsed?.name, parsed?.rkey] 36 45 } else { 37 46 return [RQKEY_ROOT, did, rkey] ··· 50 59 const agent = useAgent() 51 60 52 61 return useQuery<StarterPackView>({ 53 - queryKey: RQKEY(did, rkey), 62 + queryKey: RQKEY(uri ? {uri} : {did, rkey}), 54 63 queryFn: async () => { 55 64 if (!uri) { 56 65 uri = `at://${did}/app.bsky.graph.starterpack/${rkey}` ··· 64 73 return res.data.starterPack 65 74 }, 66 75 enabled: Boolean(uri) || Boolean(did && rkey), 76 + staleTime: STALE.MINUTES.FIVE, 67 77 }) 68 78 } 69 79 ··· 76 86 did: string 77 87 rkey: string 78 88 }) { 79 - await queryClient.invalidateQueries({queryKey: RQKEY(did, rkey)}) 89 + await queryClient.invalidateQueries({queryKey: RQKEY({did, rkey})}) 80 90 } 81 91 82 92 interface UseCreateStarterPackMutationParams {
-20
src/state/shell/logged-out.tsx
··· 50 50 const activeStarterPack = useActiveStarterPack() 51 51 const {hasSession} = useSession() 52 52 const shouldShowStarterPack = Boolean(activeStarterPack?.uri) && !hasSession 53 - 54 53 const [state, setState] = React.useState<State>({ 55 54 showLoggedOut: shouldShowStarterPack, 56 55 requestedAccountSwitchTo: shouldShowStarterPack ··· 59 58 : 'new' 60 59 : undefined, 61 60 }) 62 - 63 - const [prevActiveStarterPack, setPrevActiveStarterPack] = 64 - React.useState(activeStarterPack) 65 - if (activeStarterPack?.uri !== prevActiveStarterPack?.uri) { 66 - setPrevActiveStarterPack(activeStarterPack) 67 - if (activeStarterPack) { 68 - setState(s => ({ 69 - ...s, 70 - showLoggedOut: true, 71 - requestedAccountSwitchTo: 'starterpack', 72 - })) 73 - } else { 74 - setState(s => ({ 75 - ...s, 76 - showLoggedOut: false, 77 - requestedAccountSwitchTo: undefined, 78 - })) 79 - } 80 - } 81 61 82 62 const controls = React.useMemo<Controls>( 83 63 () => ({