diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/state/session/index.tsx | 5 | ||||
-rw-r--r-- | src/view/com/profile/ProfileHeader.tsx | 175 | ||||
-rw-r--r-- | src/view/screens/Profile.tsx | 48 |
3 files changed, 126 insertions, 102 deletions
diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index d7541295b..1e7fa2297 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -9,6 +9,7 @@ import {PUBLIC_BSKY_AGENT} from '#/state/queries' import {IS_PROD} from '#/lib/constants' import {emitSessionLoaded, emitSessionDropped} from '../events' import {useLoggedOutViewControls} from '#/state/shell/logged-out' +import {useCloseAllActiveElements} from '#/state/util' let __globalAgent: BskyAgent = PUBLIC_BSKY_AGENT @@ -520,15 +521,17 @@ export function useSessionApi() { export function useRequireAuth() { const {hasSession} = useSession() const {setShowLoggedOut} = useLoggedOutViewControls() + const closeAll = useCloseAllActiveElements() return React.useCallback( (fn: () => void) => { if (hasSession) { fn() } else { + closeAll() setShowLoggedOut(true) } }, - [hasSession, setShowLoggedOut], + [hasSession, setShowLoggedOut, closeAll], ) } diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index 45998406c..30446fba1 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -51,6 +51,7 @@ import {s, colors} from 'lib/styles' import {logger} from '#/logger' import {useSession} from '#/state/session' import {Shadow} from '#/state/cache/types' +import {useRequireAuth} from '#/state/session' interface Props { profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> | null @@ -113,7 +114,8 @@ let ProfileHeaderLoaded = ({ }: LoadedProps): React.ReactNode => { const pal = usePalette('default') const palInverted = usePalette('inverted') - const {currentAccount} = useSession() + const {currentAccount, hasSession} = useSession() + const requireAuth = useRequireAuth() const {_} = useLingui() const {openModal} = useModalControls() const {openLightbox} = useLightboxControls() @@ -150,38 +152,42 @@ let ProfileHeaderLoaded = ({ } }, [openLightbox, profile, moderation]) - const onPressFollow = async () => { - try { - track('ProfileHeader:FollowButtonClicked') - await queueFollow() - Toast.show( - `Following ${sanitizeDisplayName( - profile.displayName || profile.handle, - )}`, - ) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to follow', {error: String(e)}) - Toast.show(`There was an issue! ${e.toString()}`) + const onPressFollow = () => { + requireAuth(async () => { + try { + track('ProfileHeader:FollowButtonClicked') + await queueFollow() + Toast.show( + `Following ${sanitizeDisplayName( + profile.displayName || profile.handle, + )}`, + ) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to follow', {error: String(e)}) + Toast.show(`There was an issue! ${e.toString()}`) + } } - } + }) } - const onPressUnfollow = async () => { - try { - track('ProfileHeader:UnfollowButtonClicked') - await queueUnfollow() - Toast.show( - `No longer following ${sanitizeDisplayName( - profile.displayName || profile.handle, - )}`, - ) - } catch (e: any) { - if (e?.name !== 'AbortError') { - logger.error('Failed to unfollow', {error: String(e)}) - Toast.show(`There was an issue! ${e.toString()}`) + const onPressUnfollow = () => { + requireAuth(async () => { + try { + track('ProfileHeader:UnfollowButtonClicked') + await queueUnfollow() + Toast.show( + `No longer following ${sanitizeDisplayName( + profile.displayName || profile.handle, + )}`, + ) + } catch (e: any) { + if (e?.name !== 'AbortError') { + logger.error('Failed to unfollow', {error: String(e)}) + Toast.show(`There was an issue! ${e.toString()}`) + } } - } + }) } const onPressEditProfile = React.useCallback(() => { @@ -303,72 +309,75 @@ let ProfileHeaderLoaded = ({ }, }, ] - items.push({label: 'separator'}) - items.push({ - testID: 'profileHeaderDropdownListAddRemoveBtn', - label: _(msg`Add to Lists`), - onPress: onPressAddRemoveLists, - icon: { - ios: { - name: 'list.bullet', + if (hasSession) { + items.push({label: 'separator'}) + items.push({ + testID: 'profileHeaderDropdownListAddRemoveBtn', + label: _(msg`Add to Lists`), + onPress: onPressAddRemoveLists, + icon: { + ios: { + name: 'list.bullet', + }, + android: 'ic_menu_add', + web: 'list', }, - android: 'ic_menu_add', - web: 'list', - }, - }) - if (!isMe) { - if (!profile.viewer?.blocking) { - items.push({ - testID: 'profileHeaderDropdownMuteBtn', - label: profile.viewer?.muted - ? _(msg`Unmute Account`) - : _(msg`Mute Account`), - onPress: profile.viewer?.muted - ? onPressUnmuteAccount - : onPressMuteAccount, - icon: { - ios: { - name: 'speaker.slash', + }) + if (!isMe) { + if (!profile.viewer?.blocking) { + items.push({ + testID: 'profileHeaderDropdownMuteBtn', + label: profile.viewer?.muted + ? _(msg`Unmute Account`) + : _(msg`Mute Account`), + onPress: profile.viewer?.muted + ? onPressUnmuteAccount + : onPressMuteAccount, + icon: { + ios: { + name: 'speaker.slash', + }, + android: 'ic_lock_silent_mode', + web: 'comment-slash', }, - android: 'ic_lock_silent_mode', - web: 'comment-slash', - }, - }) - } - if (!profile.viewer?.blockingByList) { + }) + } + if (!profile.viewer?.blockingByList) { + items.push({ + testID: 'profileHeaderDropdownBlockBtn', + label: profile.viewer?.blocking + ? _(msg`Unblock Account`) + : _(msg`Block Account`), + onPress: profile.viewer?.blocking + ? onPressUnblockAccount + : onPressBlockAccount, + icon: { + ios: { + name: 'person.fill.xmark', + }, + android: 'ic_menu_close_clear_cancel', + web: 'user-slash', + }, + }) + } items.push({ - testID: 'profileHeaderDropdownBlockBtn', - label: profile.viewer?.blocking - ? _(msg`Unblock Account`) - : _(msg`Block Account`), - onPress: profile.viewer?.blocking - ? onPressUnblockAccount - : onPressBlockAccount, + testID: 'profileHeaderDropdownReportBtn', + label: _(msg`Report Account`), + onPress: onPressReportAccount, icon: { ios: { - name: 'person.fill.xmark', + name: 'exclamationmark.triangle', }, - android: 'ic_menu_close_clear_cancel', - web: 'user-slash', + android: 'ic_menu_report_image', + web: 'circle-exclamation', }, }) } - items.push({ - testID: 'profileHeaderDropdownReportBtn', - label: _(msg`Report Account`), - onPress: onPressReportAccount, - icon: { - ios: { - name: 'exclamationmark.triangle', - }, - android: 'ic_menu_report_image', - web: 'circle-exclamation', - }, - }) } return items }, [ isMe, + hasSession, profile.viewer?.muted, profile.viewer?.blocking, profile.viewer?.blockingByList, @@ -421,7 +430,7 @@ let ProfileHeaderLoaded = ({ ) ) : !profile.viewer?.blockedBy ? ( <> - {!isProfilePreview && ( + {!isProfilePreview && hasSession && ( <TouchableOpacity testID="suggestedFollowsBtn" onPress={() => setShowSuggestedFollows(!showSuggestedFollows)} diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index 55fe02cdd..7c0491d52 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -155,23 +155,27 @@ function ProfileScreenLoaded({ ) const isMe = profile.did === currentAccount?.did + const showRepliesTab = hasSession const showLikesTab = isMe - const showFeedsTab = isMe || extraInfoQuery.data?.hasFeedgens - const showListsTab = isMe || extraInfoQuery.data?.hasLists + const showFeedsTab = hasSession && (isMe || extraInfoQuery.data?.hasFeedgens) + const showListsTab = hasSession && (isMe || extraInfoQuery.data?.hasLists) const sectionTitles = useMemo<string[]>(() => { return [ 'Posts', - 'Posts & Replies', + showRepliesTab ? 'Posts & Replies' : undefined, 'Media', showLikesTab ? 'Likes' : undefined, showFeedsTab ? 'Feeds' : undefined, showListsTab ? 'Lists' : undefined, ].filter(Boolean) as string[] - }, [showLikesTab, showFeedsTab, showListsTab]) + }, [showRepliesTab, showLikesTab, showFeedsTab, showListsTab]) let nextIndex = 0 const postsIndex = nextIndex++ - const repliesIndex = nextIndex++ + let repliesIndex: number | null = null + if (showRepliesTab) { + repliesIndex = nextIndex++ + } const mediaIndex = nextIndex++ let likesIndex: number | null = null if (showLikesTab) { @@ -282,19 +286,27 @@ function ProfileScreenLoaded({ } /> )} - {({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => ( - <FeedSection - ref={repliesSectionRef} - feed={`author|${profile.did}|posts_with_replies`} - onScroll={onScroll} - headerHeight={headerHeight} - isFocused={isFocused} - isScrolledDown={isScrolledDown} - scrollElRef={ - scrollElRef as React.MutableRefObject<FlatList<any> | null> - } - /> - )} + {showRepliesTab + ? ({ + onScroll, + headerHeight, + isFocused, + isScrolledDown, + scrollElRef, + }) => ( + <FeedSection + ref={repliesSectionRef} + feed={`author|${profile.did}|posts_with_replies`} + onScroll={onScroll} + headerHeight={headerHeight} + isFocused={isFocused} + isScrolledDown={isScrolledDown} + scrollElRef={ + scrollElRef as React.MutableRefObject<FlatList<any> | null> + } + /> + ) + : null} {({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => ( <FeedSection ref={mediaSectionRef} |