diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/FeedInterstitials.tsx | 201 | ||||
-rw-r--r-- | src/components/KnownFollowers.tsx | 16 | ||||
-rw-r--r-- | src/components/ProfileCard.tsx | 45 | ||||
-rw-r--r-- | src/components/SearchError.tsx | 45 | ||||
-rw-r--r-- | src/components/VideoPostCard.tsx | 80 | ||||
-rw-r--r-- | src/components/dialogs/EmailDialog/data/useAccountEmailState.ts | 65 | ||||
-rw-r--r-- | src/components/dialogs/EmailDialog/data/useConfirmEmail.ts | 10 | ||||
-rw-r--r-- | src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts | 10 | ||||
-rw-r--r-- | src/components/interstitials/TrendingVideos.tsx | 31 |
9 files changed, 305 insertions, 198 deletions
diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index a92e7be7f..2a3a00ba7 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -25,18 +25,17 @@ import { type ViewStyleProp, web, } from '#/alf' -import {Button} from '#/components/Button' +import {Button, ButtonText} from '#/components/Button' import * as FeedCard from '#/components/FeedCard' import {ArrowRight_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow' import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' -import {PersonPlus_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' import {InlineLinkText} from '#/components/Link' import * as ProfileCard from '#/components/ProfileCard' import {Text} from '#/components/Typography' import type * as bsky from '#/types/bsky' import {ProgressGuideList} from './ProgressGuide/List' -const MOBILE_CARD_WIDTH = 300 +const MOBILE_CARD_WIDTH = 165 function CardOuter({ children, @@ -48,8 +47,8 @@ function CardOuter({ <View style={[ a.w_full, - a.p_lg, - a.rounded_md, + a.p_md, + a.rounded_lg, a.border, t.atoms.bg, t.atoms.border_contrast_low, @@ -65,14 +64,30 @@ function CardOuter({ export function SuggestedFollowPlaceholder() { const t = useTheme() + return ( - <CardOuter style={[a.gap_md, t.atoms.border_contrast_low]}> - <ProfileCard.Header> - <ProfileCard.AvatarPlaceholder /> - <ProfileCard.NameAndHandlePlaceholder /> - </ProfileCard.Header> + <CardOuter + style={[a.gap_md, t.atoms.border_contrast_low, t.atoms.shadow_sm]}> + <ProfileCard.Outer> + <View + style={[a.flex_col, a.align_center, a.gap_sm, a.pb_sm, a.mb_auto]}> + <ProfileCard.AvatarPlaceholder size={88} /> + <ProfileCard.NamePlaceholder /> + <View style={[a.w_full]}> + <ProfileCard.DescriptionPlaceholder numberOfLines={2} /> + </View> + </View> - <ProfileCard.DescriptionPlaceholder numberOfLines={2} /> + <Button + label="" + size="small" + variant="solid" + color="secondary" + disabled + style={[a.w_full, a.rounded_sm]}> + <ButtonText>Follow</ButtonText> + </Button> + </ProfileCard.Outer> </CardOuter> ) } @@ -243,10 +258,9 @@ export function ProfileGrid({ const t = useTheme() const {_} = useLingui() const moderationOpts = useModerationOpts() - const navigation = useNavigation<NavigationProp>() const {gtMobile} = useBreakpoints() const isLoading = isSuggestionsLoading || !moderationOpts - const maxLength = gtMobile ? 4 : 6 + const maxLength = gtMobile ? 3 : 6 const content = isLoading ? ( Array(maxLength) @@ -254,7 +268,14 @@ export function ProfileGrid({ .map((_, i) => ( <View key={i} - style={[gtMobile && web([a.flex_0, {width: 'calc(50% - 6px)'}])]}> + style={[ + gtMobile && + web([ + a.flex_0, + a.flex_grow, + {width: `calc(30% - ${a.gap_md.gap / 2}px)`}, + ]), + ]}> <SuggestedFollowPlaceholder /> </View> )) @@ -276,44 +297,69 @@ export function ProfileGrid({ }} style={[ a.flex_1, - gtMobile && web([a.flex_0, {width: 'calc(50% - 6px)'}]), + gtMobile && + web([ + a.flex_0, + a.flex_grow, + {width: `calc(30% - ${a.gap_md.gap / 2}px)`}, + ]), ]}> {({hovered, pressed}) => ( <CardOuter style={[ a.flex_1, + t.atoms.shadow_sm, (hovered || pressed) && t.atoms.border_contrast_high, ]}> <ProfileCard.Outer> - <ProfileCard.Header> + <View + style={[ + a.flex_col, + a.align_center, + a.gap_sm, + a.pb_sm, + a.mb_auto, + ]}> <ProfileCard.Avatar profile={profile} moderationOpts={moderationOpts} + size={88} /> - <ProfileCard.NameAndHandle - profile={profile} - moderationOpts={moderationOpts} - /> - <ProfileCard.FollowButton - profile={profile} - moderationOpts={moderationOpts} - logContext="FeedInterstitial" - shape="round" - colorInverted - onFollow={() => { - logEvent('suggestedUser:follow', { - logContext: - viewContext === 'feed' - ? 'InterstitialDiscover' - : 'InterstitialProfile', - location: 'Card', - recId, - position: index, - }) - }} - /> - </ProfileCard.Header> - <ProfileCard.Description profile={profile} numberOfLines={2} /> + <View style={[a.flex_col, a.align_center, a.max_w_full]}> + <ProfileCard.Name + profile={profile} + moderationOpts={moderationOpts} + /> + <ProfileCard.Description + profile={profile} + numberOfLines={2} + style={[ + t.atoms.text_contrast_medium, + a.text_center, + a.text_xs, + ]} + /> + </View> + </View> + + <ProfileCard.FollowButton + profile={profile} + moderationOpts={moderationOpts} + logContext="FeedInterstitial" + withIcon={false} + style={[a.rounded_sm]} + onFollow={() => { + logEvent('suggestedUser:follow', { + logContext: + viewContext === 'feed' + ? 'InterstitialDiscover' + : 'InterstitialProfile', + location: 'Card', + recId, + position: index, + }) + }} + /> </ProfileCard.Outer> </CardOuter> )} @@ -333,36 +379,30 @@ export function ProfileGrid({ <View style={[ a.p_lg, - a.pb_xs, + a.py_md, a.flex_row, a.align_center, a.justify_between, ]}> - <Text style={[a.text_sm, a.font_bold, t.atoms.text_contrast_medium]}> + <Text style={[a.text_sm, a.font_bold, t.atoms.text]}> {viewContext === 'profile' ? ( <Trans>Similar accounts</Trans> ) : ( <Trans>Suggested for you</Trans> )} </Text> - <Person fill={t.atoms.text_contrast_low.color} size="sm" /> + <InlineLinkText + label={_(msg`See more suggested profiles on the Explore page`)} + to="/search"> + <Trans>See more</Trans> + </InlineLinkText> </View> {gtMobile ? ( - <View style={[a.flex_1, a.px_lg, a.pt_sm, a.pb_lg, a.gap_md]}> - <View style={[a.flex_1, a.flex_row, a.flex_wrap, a.gap_sm]}> + <View style={[a.px_lg, a.pb_lg]}> + <View style={[a.flex_1, a.flex_row, a.flex_wrap, a.gap_md]}> {content} </View> - - <View style={[a.flex_row, a.justify_end, a.align_center, a.gap_md]}> - <InlineLinkText - label={_(msg`Browse more suggestions`)} - to="/search" - style={[t.atoms.text_contrast_medium]}> - <Trans>Browse more suggestions</Trans> - </InlineLinkText> - <Arrow size="sm" fill={t.atoms.text_contrast_medium.color} /> - </View> </View> ) : ( <BlockDrawerGesture> @@ -371,29 +411,12 @@ export function ProfileGrid({ horizontal showsHorizontalScrollIndicator={false} snapToInterval={MOBILE_CARD_WIDTH + a.gap_md.gap} - decelerationRate="fast"> - <View style={[a.px_lg, a.pt_sm, a.pb_lg, a.flex_row, a.gap_md]}> + decelerationRate="fast" + style={[a.overflow_visible]}> + <View style={[a.px_lg, a.pb_lg, a.flex_row, a.gap_md]}> {content} - <Button - label={_(msg`Browse more accounts on the Explore page`)} - onPress={() => { - navigation.navigate('SearchTab') - }}> - <CardOuter style={[a.flex_1, {borderWidth: 0}]}> - <View style={[a.flex_1, a.justify_center]}> - <View style={[a.flex_row, a.px_lg]}> - <Text style={[a.pr_xl, a.flex_1, a.leading_snug]}> - <Trans> - Browse more suggestions on the Explore page - </Trans> - </Text> - - <Arrow size="xl" /> - </View> - </View> - </CardOuter> - </Button> + <SeeMoreSuggestedProfilesCard /> </View> </ScrollView> </View> @@ -403,6 +426,32 @@ export function ProfileGrid({ ) } +function SeeMoreSuggestedProfilesCard() { + const navigation = useNavigation<NavigationProp>() + const t = useTheme() + const {_} = useLingui() + + return ( + <Button + label={_(msg`Browse more accounts on the Explore page`)} + onPress={() => { + navigation.navigate('SearchTab') + }}> + <CardOuter style={[a.flex_1, t.atoms.shadow_sm]}> + <View style={[a.flex_1, a.justify_center]}> + <View style={[a.flex_col, a.align_center, a.gap_md]}> + <Text style={[a.leading_snug, a.text_center]}> + <Trans>See more accounts you might like</Trans> + </Text> + + <Arrow size="xl" /> + </View> + </View> + </CardOuter> + </Button> + ) +} + export function SuggestedFeeds() { const numFeedsToDisplay = 3 const t = useTheme() diff --git a/src/components/KnownFollowers.tsx b/src/components/KnownFollowers.tsx index c60d0f92e..28fb8f1f1 100644 --- a/src/components/KnownFollowers.tsx +++ b/src/components/KnownFollowers.tsx @@ -1,6 +1,10 @@ import React from 'react' import {View} from 'react-native' -import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api' +import { + type AppBskyActorDefs, + moderateProfile, + type ModerationOpts, +} from '@atproto/api' import {msg, Plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -8,9 +12,9 @@ import {makeProfileLink} from '#/lib/routes/links' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' -import {Link, LinkProps} from '#/components/Link' +import {Link, type LinkProps} from '#/components/Link' import {Text} from '#/components/Typography' -import * as bsky from '#/types/bsky' +import type * as bsky from '#/types/bsky' const AVI_SIZE = 30 const AVI_SIZE_SMALL = 20 @@ -137,9 +141,9 @@ function KnownFollowersInner({ <> <View style={[ + a.flex_row, { height: SIZE, - width: SIZE + (slice.length - 1) * a.gap_md.gap, }, pressed && { opacity: 0.5, @@ -149,15 +153,14 @@ function KnownFollowersInner({ <View key={prof.did} style={[ - a.absolute, a.rounded_full, { borderWidth: AVI_BORDER, borderColor: t.atoms.bg.backgroundColor, width: SIZE + AVI_BORDER * 2, height: SIZE + AVI_BORDER * 2, - left: i * a.gap_md.gap, zIndex: AVI_BORDER - i, + marginLeft: i > 0 ? -8 : 0, }, ]}> <UserAvatar @@ -165,6 +168,7 @@ function KnownFollowersInner({ avatar={prof.avatar} moderation={moderation.ui('avatar')} type={prof.associated?.labeler ? 'labeler' : 'user'} + noBorder /> </View> ))} diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index e01c27655..f12d922fd 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -20,7 +20,13 @@ import {useProfileFollowMutationQueue} from '#/state/queries/profile' import {useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a, platform, useTheme} from '#/alf' +import { + atoms as a, + platform, + type TextStyleProp, + useTheme, + type ViewStyleProp, +} from '#/alf' import { Button, ButtonIcon, @@ -136,12 +142,14 @@ export function Avatar({ onPress, disabledPreview, liveOverride, + size = 40, }: { profile: bsky.profile.AnyProfileView moderationOpts: ModerationOpts onPress?: () => void disabledPreview?: boolean liveOverride?: boolean + size?: number }) { const moderation = moderateProfile(profile, moderationOpts) @@ -149,7 +157,7 @@ export function Avatar({ return disabledPreview ? ( <UserAvatar - size={40} + size={size} avatar={profile.avatar} type={profile.associated?.labeler ? 'labeler' : 'user'} moderation={moderation.ui('avatar')} @@ -157,7 +165,7 @@ export function Avatar({ /> ) : ( <PreviewableUserAvatar - size={40} + size={size} profile={profile} moderation={moderation.ui('avatar')} onBeforePress={onPress} @@ -166,7 +174,7 @@ export function Avatar({ ) } -export function AvatarPlaceholder() { +export function AvatarPlaceholder({size = 40}: {size?: number}) { const t = useTheme() return ( <View @@ -174,8 +182,8 @@ export function AvatarPlaceholder() { a.rounded_full, t.atoms.bg_contrast_25, { - width: 40, - height: 40, + width: size, + height: size, }, ]} /> @@ -274,7 +282,7 @@ export function Name({ ) const verification = useSimpleVerificationState({profile}) return ( - <View style={[a.flex_row, a.align_center]}> + <View style={[a.flex_row, a.align_center, a.max_w_full]}> <Text emoji style={[ @@ -343,13 +351,32 @@ export function NameAndHandlePlaceholder() { ) } +export function NamePlaceholder({style}: ViewStyleProp) { + const t = useTheme() + + return ( + <View + style={[ + a.rounded_xs, + t.atoms.bg_contrast_25, + { + width: '60%', + height: 14, + }, + style, + ]} + /> + ) +} + export function Description({ profile: profileUnshadowed, numberOfLines = 3, + style, }: { profile: bsky.profile.AnyProfileView numberOfLines?: number -}) { +} & TextStyleProp) { const profile = useProfileShadow(profileUnshadowed) const rt = useMemo(() => { if (!('description' in profile)) return @@ -369,7 +396,7 @@ export function Description({ <View style={[a.pt_xs]}> <RichText value={rt} - style={[a.leading_snug]} + style={[a.leading_snug, style]} numberOfLines={numberOfLines} disableLinks /> diff --git a/src/components/SearchError.tsx b/src/components/SearchError.tsx new file mode 100644 index 000000000..443bbab8f --- /dev/null +++ b/src/components/SearchError.tsx @@ -0,0 +1,45 @@ +import {View} from 'react-native' + +import {usePalette} from '#/lib/hooks/usePalette' +import {atoms as a, useBreakpoints} from '#/alf' +import * as Layout from '#/components/Layout' +import {Text} from '#/components/Typography' +import {TimesLarge_Stroke2_Corner0_Rounded} from './icons/Times' + +export function SearchError({ + title, + children, +}: { + title?: string + children?: React.ReactNode +}) { + const {gtMobile} = useBreakpoints() + const pal = usePalette('default') + + return ( + <Layout.Content> + <View + style={[ + a.align_center, + a.gap_4xl, + a.px_xl, + { + paddingVertical: 150, + }, + ]}> + <TimesLarge_Stroke2_Corner0_Rounded width={32} fill={pal.colors.icon} /> + <View + style={[ + a.align_center, + {maxWidth: gtMobile ? 394 : 294}, + gtMobile ? a.gap_md : a.gap_sm, + ]}> + <Text style={[a.font_bold, a.text_lg, a.text_center, a.leading_snug]}> + {title} + </Text> + {children} + </View> + </View> + </Layout.Content> + ) +} diff --git a/src/components/VideoPostCard.tsx b/src/components/VideoPostCard.tsx index c28adad8b..a1bdd29b4 100644 --- a/src/components/VideoPostCard.tsx +++ b/src/components/VideoPostCard.tsx @@ -390,6 +390,7 @@ export function CompactVideoPostCard({ if (!AppBskyEmbedVideo.isView(embed)) return null const likeCount = post?.likeCount ?? 0 + const showLikeCount = false const {thumbnail} = embed const black = getBlackColor(t) @@ -410,6 +411,7 @@ export function CompactVideoPostCard({ onPressOut={onPressOut} style={[ a.flex_col, + t.atoms.shadow_sm, { alignItems: undefined, justifyContent: undefined, @@ -420,8 +422,10 @@ export function CompactVideoPostCard({ <View style={[ a.justify_center, - a.rounded_md, + a.rounded_lg, a.overflow_hidden, + a.border, + t.atoms.border_contrast_low, { backgroundColor: black, aspectRatio: 9 / 16, @@ -442,6 +446,8 @@ export function CompactVideoPostCard({ a.inset_0, a.justify_center, a.align_center, + a.border, + t.atoms.border_contrast_low, { backgroundColor: 'black', opacity: 0.2, @@ -461,8 +467,10 @@ export function CompactVideoPostCard({ <View style={[ a.justify_center, - a.rounded_md, + a.rounded_lg, a.overflow_hidden, + a.border, + t.atoms.border_contrast_low, { backgroundColor: black, aspectRatio: 9 / 16, @@ -475,47 +483,51 @@ export function CompactVideoPostCard({ /> <MediaInsetBorder /> - <View style={[a.absolute, a.inset_0]}> + <View style={[a.absolute, a.inset_0, t.atoms.shadow_sm]}> <View style={[a.absolute, a.inset_0, a.p_sm, {bottom: 'auto'}]}> <View - style={[a.relative, a.rounded_full, {width: 20, height: 20}]}> + style={[a.relative, a.rounded_full, {width: 24, height: 24}]}> <UserAvatar type="user" - size={20} + size={24} avatar={post.author.avatar} /> <MediaInsetBorder /> </View> </View> - <View - style={[ - a.absolute, - a.inset_0, - a.pt_2xl, - { - top: 'auto', - }, - ]}> - <LinearGradient - colors={[black, 'rgba(0, 0, 0, 0)']} - locations={[0.02, 1]} - start={{x: 0, y: 1}} - end={{x: 0, y: 0}} - style={[a.absolute, a.inset_0, {opacity: 0.9}]} - /> + {showLikeCount && ( <View - style={[a.relative, a.z_10, a.p_sm, a.flex_row, a.gap_md]}> - {likeCount > 0 && ( - <View style={[a.flex_row, a.align_center, a.gap_xs]}> - <Heart size="sm" fill="white" /> - <Text style={[a.text_sm, a.font_bold, {color: 'white'}]}> - {formatCount(i18n, likeCount)} - </Text> - </View> - )} + style={[ + a.absolute, + a.inset_0, + a.pt_2xl, + { + top: 'auto', + }, + ]}> + <LinearGradient + colors={[black, 'rgba(0, 0, 0, 0)']} + locations={[0.02, 1]} + start={{x: 0, y: 1}} + end={{x: 0, y: 0}} + style={[a.absolute, a.inset_0, {opacity: 0.9}]} + /> + + <View + style={[a.relative, a.z_10, a.p_sm, a.flex_row, a.gap_md]}> + {likeCount > 0 && ( + <View style={[a.flex_row, a.align_center, a.gap_xs]}> + <Heart size="sm" fill="white" /> + <Text + style={[a.text_sm, a.font_bold, {color: 'white'}]}> + {formatCount(i18n, likeCount)} + </Text> + </View> + )} + </View> </View> - </View> + )} </View> </View> </Hider.Content> @@ -529,11 +541,13 @@ export function CompactVideoPostCardPlaceholder() { const black = getBlackColor(t) return ( - <View style={[a.flex_1]}> + <View style={[a.flex_1, t.atoms.shadow_sm]}> <View style={[ - a.rounded_md, + a.rounded_lg, a.overflow_hidden, + a.border, + t.atoms.border_contrast_low, { backgroundColor: black, aspectRatio: 9 / 16, diff --git a/src/components/dialogs/EmailDialog/data/useAccountEmailState.ts b/src/components/dialogs/EmailDialog/data/useAccountEmailState.ts index 377411107..f25369f8d 100644 --- a/src/components/dialogs/EmailDialog/data/useAccountEmailState.ts +++ b/src/components/dialogs/EmailDialog/data/useAccountEmailState.ts @@ -1,7 +1,7 @@ -import {useCallback, useEffect, useState} from 'react' -import {useQuery, useQueryClient} from '@tanstack/react-query' +import {useEffect, useMemo, useState} from 'react' +import {useQuery} from '@tanstack/react-query' -import {useAgent} from '#/state/session' +import {useAgent, useSessionApi} from '#/state/session' import {emitEmailVerified} from '#/components/dialogs/EmailDialog/events' export type AccountEmailState = { @@ -11,57 +11,36 @@ export type AccountEmailState = { export const accountEmailStateQueryKey = ['accountEmailState'] as const -export function useInvalidateAccountEmailState() { - const qc = useQueryClient() - - return useCallback(() => { - return qc.invalidateQueries({ - queryKey: accountEmailStateQueryKey, - }) - }, [qc]) -} - -export function useUpdateAccountEmailStateQueryCache() { - const qc = useQueryClient() - - return useCallback( - (data: AccountEmailState) => { - return qc.setQueriesData( - { - queryKey: accountEmailStateQueryKey, - }, - data, - ) - }, - [qc], - ) -} - export function useAccountEmailState() { const agent = useAgent() + const {partialRefreshSession} = useSessionApi() const [prevIsEmailVerified, setPrevEmailIsVerified] = useState( !!agent.session?.emailConfirmed, ) - const fallbackData: AccountEmailState = { - isEmailVerified: !!agent.session?.emailConfirmed, - email2FAEnabled: !!agent.session?.emailAuthFactor, - } - const query = useQuery<AccountEmailState>({ + const state: AccountEmailState = useMemo( + () => ({ + isEmailVerified: !!agent.session?.emailConfirmed, + email2FAEnabled: !!agent.session?.emailAuthFactor, + }), + [agent.session], + ) + + /** + * Only here to refetch on focus, when necessary + */ + useQuery({ enabled: !!agent.session, - refetchOnWindowFocus: true, + /** + * Only refetch if the email verification s incomplete. + */ + refetchOnWindowFocus: !prevIsEmailVerified, queryKey: accountEmailStateQueryKey, queryFn: async () => { - // will also trigger updates to `#/state/session` data - const {data} = await agent.resumeSession(agent.session!) - return { - isEmailVerified: !!data.emailConfirmed, - email2FAEnabled: !!data.emailAuthFactor, - } + await partialRefreshSession() + return null }, }) - const state = query.data ?? fallbackData - /* * This will emit `n` times for each instance of this hook. So the listeners * all use `once` to prevent multiple handlers firing. diff --git a/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts index 73f824fcc..475a8cbfb 100644 --- a/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts +++ b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts @@ -1,13 +1,10 @@ import {useMutation} from '@tanstack/react-query' import {useAgent, useSession} from '#/state/session' -import {useUpdateAccountEmailStateQueryCache} from '#/components/dialogs/EmailDialog/data/useAccountEmailState' export function useConfirmEmail() { const agent = useAgent() const {currentAccount} = useSession() - const updateAccountEmailStateQueryCache = - useUpdateAccountEmailStateQueryCache() return useMutation({ mutationFn: async ({token}: {token: string}) => { @@ -19,11 +16,8 @@ export function useConfirmEmail() { email: currentAccount.email, token: token.trim(), }) - const {data} = await agent.resumeSession(agent.session!) - updateAccountEmailStateQueryCache({ - isEmailVerified: !!data.emailConfirmed, - email2FAEnabled: !!data.emailAuthFactor, - }) + // will update session state at root of app + await agent.resumeSession(agent.session!) }, }) } diff --git a/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts b/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts index 39f5fd2d9..358bf8654 100644 --- a/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts +++ b/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts @@ -1,13 +1,10 @@ import {useMutation} from '@tanstack/react-query' import {useAgent, useSession} from '#/state/session' -import {useUpdateAccountEmailStateQueryCache} from '#/components/dialogs/EmailDialog/data/useAccountEmailState' export function useManageEmail2FA() { const agent = useAgent() const {currentAccount} = useSession() - const updateAccountEmailStateQueryCache = - useUpdateAccountEmailStateQueryCache() return useMutation({ mutationFn: async ({ @@ -25,11 +22,8 @@ export function useManageEmail2FA() { emailAuthFactor: enabled, token, }) - const {data} = await agent.resumeSession(agent.session!) - updateAccountEmailStateQueryCache({ - isEmailVerified: !!data.emailConfirmed, - email2FAEnabled: !!data.emailAuthFactor, - }) + // will update session state at root of app + await agent.resumeSession(agent.session!) }, }) } diff --git a/src/components/interstitials/TrendingVideos.tsx b/src/components/interstitials/TrendingVideos.tsx index fab738b9c..4d59e2fb5 100644 --- a/src/components/interstitials/TrendingVideos.tsx +++ b/src/components/interstitials/TrendingVideos.tsx @@ -16,7 +16,6 @@ import {atoms as a, useGutters, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' -import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending' import {Link} from '#/components/Link' import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' @@ -25,7 +24,7 @@ import { CompactVideoPostCardPlaceholder, } from '#/components/VideoPostCard' -const CARD_WIDTH = 100 +const CARD_WIDTH = 108 const FEED_DESC = `feedgen|${VIDEO_FEED_URI}` const FEED_PARAMS: { @@ -68,9 +67,10 @@ export function TrendingVideos() { return ( <View style={[ - a.pt_lg, + a.pt_sm, a.pb_lg, a.border_t, + a.overflow_hidden, t.atoms.border_contrast_low, t.atoms.bg_contrast_25, ]}> @@ -82,20 +82,17 @@ export function TrendingVideos() { a.align_center, a.justify_between, ]}> - <View style={[a.flex_1, a.flex_row, a.align_center, a.gap_xs]}> - <Graph /> - <Text style={[a.text_md, a.font_bold, a.leading_snug]}> - <Trans>Trending Videos</Trans> - </Text> - </View> + <Text style={[a.text_sm, a.font_bold, a.leading_snug]}> + <Trans>Trending Videos</Trans> + </Text> <Button label={_(msg`Dismiss this section`)} size="tiny" - variant="ghost" + variant="solid" color="secondary" - shape="round" + shape="square" onPress={() => trendingPrompt.open()}> - <ButtonIcon icon={X} /> + <ButtonIcon icon={X} size="sm" /> </Button> </View> @@ -104,11 +101,12 @@ export function TrendingVideos() { horizontal showsHorizontalScrollIndicator={false} decelerationRate="fast" - snapToInterval={CARD_WIDTH + a.gap_sm.gap}> + snapToInterval={CARD_WIDTH + a.gap_md.gap} + style={[a.overflow_visible]}> <View style={[ a.flex_row, - a.gap_sm, + a.gap_md, { paddingLeft: gutters.paddingLeft, paddingRight: gutters.paddingRight, @@ -193,8 +191,11 @@ function VideoCards({ a.justify_center, a.align_center, a.flex_1, - a.rounded_md, + a.rounded_lg, + a.border, + t.atoms.border_contrast_low, t.atoms.bg, + t.atoms.shadow_sm, ]}> {({pressed}) => ( <View |