Delete some dead code and do some refactoring

This commit is contained in:
Paul Frazee
2024-03-04 13:24:22 -08:00
parent f30f31f123
commit 473ca0deff
6 changed files with 104 additions and 1273 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ import {
ChevronTop_Stroke2_Corner0_Rounded as ChevronTop,
} from '#/components/icons/Chevron'
import {ScreenHider} from '../com/util/moderation/ScreenHider'
import {ProfileHeader} from '../com/profile/ProfileHeader'
import {ProfileHeader} from '#/screens/Profile/Header'
import {ProfileCard} from '../com/profile/ProfileCard'
import {FeedItem} from '../com/posts/FeedItem'
import {FeedItem as NotifFeedItem} from '../com/notifications/FeedItem'
+12 -440
View File
@@ -1,5 +1,5 @@
import React, {useMemo} from 'react'
import {StyleSheet, View} from 'react-native'
import {StyleSheet} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
import {
AppBskyActorDefs,
@@ -7,54 +7,38 @@ import {
ModerationOpts,
RichText as RichTextAPI,
} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {CenteredView, ScrollView} from '../com/util/Views'
import {CenteredView} from '../com/util/Views'
import {ListRef} from '../com/util/List'
import {ScreenHider} from 'view/com/util/moderation/ScreenHider'
import {Feed} from 'view/com/posts/Feed'
import {ProfileLists} from '../com/lists/ProfileLists'
import {ProfileFeedgens} from '../com/feeds/ProfileFeedgens'
import {ProfileHeader, ProfileHeaderLoading} from '../com/profile/ProfileHeader'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
import {ErrorScreen} from '../com/util/error/ErrorScreen'
import {EmptyState} from '../com/util/EmptyState'
import {FAB} from '../com/util/fab/FAB'
import {s, colors} from 'lib/styles'
import {useAnalytics} from 'lib/analytics/analytics'
import {ComposeIcon2} from 'lib/icons'
import {useSetTitle} from 'lib/hooks/useSetTitle'
import {combinedDisplayName} from 'lib/strings/display-names'
import {
FeedDescriptor,
resetProfilePostsQueries,
} from '#/state/queries/post-feed'
import {resetProfilePostsQueries} from '#/state/queries/post-feed'
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
import {useProfileQuery} from '#/state/queries/profile'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useSession, getAgent} from '#/state/session'
import {useModerationOpts} from '#/state/queries/preferences'
import {useProfileExtraInfoQuery} from '#/state/queries/profile-extra-info'
import {useLabelerInfoQuery} from '#/state/queries/labeler'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
import {cleanError} from '#/lib/strings/errors'
import {LoadLatestBtn} from '../com/util/load-latest/LoadLatestBtn'
import {useQueryClient} from '@tanstack/react-query'
import {useComposerControls} from '#/state/shell/composer'
import {listenSoftReset} from '#/state/events'
import {truncateAndInvalidate} from '#/state/queries/util'
import {Text} from '#/view/com/util/text/Text'
import {usePalette} from 'lib/hooks/usePalette'
import {isNative} from '#/platform/detection'
import {isInvalidHandle} from '#/lib/strings/handles'
import {useTheme, atoms as a} from '#/alf'
import * as ModerationServiceCard from '#/components/ModerationServiceCard'
import {RaisingHande4Finger_Stroke2_Corner0_Rounded as RaisingHand} from '#/components/icons/RaisingHand'
import {ProfileFeedSection} from '#/screens/Profile/Sections/Feed'
import {ProfileContentFiltersSection} from '#/screens/Profile/Sections/ContentFilters'
import {ProfileHeader as ProfileHeaderV2} from '#/screens/Profile/Header'
import {ProfileHeader, ProfileHeaderLoading} from '#/screens/Profile/Header'
interface SectionRef {
scrollToTop: () => void
@@ -119,7 +103,7 @@ export function ProfileScreen({route}: Props) {
}
if (profile && moderationOpts) {
return (
<ProfileScreenLoadedV2
<ProfileScreenLoaded
profile={profile}
moderationOpts={moderationOpts}
isPlaceholderProfile={isPlaceholderProfile}
@@ -149,298 +133,6 @@ function ProfileScreenLoaded({
moderationOpts: ModerationOpts
hideBackButton: boolean
isPlaceholderProfile: boolean
}) {
const profile = useProfileShadow(profileUnshadowed)
const {hasSession, currentAccount} = useSession()
const setMinimalShellMode = useSetMinimalShellMode()
const {openComposer} = useComposerControls()
const {screen, track} = useAnalytics()
const [currentPage, setCurrentPage] = React.useState(0)
const {_} = useLingui()
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
const extraInfoQuery = useProfileExtraInfoQuery(profile.did)
const postsSectionRef = React.useRef<SectionRef>(null)
const repliesSectionRef = React.useRef<SectionRef>(null)
const mediaSectionRef = React.useRef<SectionRef>(null)
const likesSectionRef = React.useRef<SectionRef>(null)
const feedsSectionRef = React.useRef<SectionRef>(null)
const listsSectionRef = React.useRef<SectionRef>(null)
const moderationSectionRef = React.useRef<SectionRef>(null)
useSetTitle(combinedDisplayName(profile))
const description = profile.description ?? ''
const hasDescription = description !== ''
const [descriptionRT, isResolvingDescriptionRT] = useRichText(description)
const showPlaceholder = isPlaceholderProfile || isResolvingDescriptionRT
const moderation = useMemo(
() => moderateProfile(profile, moderationOpts),
[profile, moderationOpts],
)
const isMe = profile.did === currentAccount?.did
const showRepliesTab = hasSession
const showLikesTab = isMe
const showFeedsTab = hasSession && (isMe || extraInfoQuery.data?.hasFeedgens)
const showListsTab = hasSession && (isMe || extraInfoQuery.data?.hasLists)
const showModerationTab =
hasSession && (isMe || true) /* TODO true should be associated modservice */
const sectionTitles = useMemo<string[]>(() => {
return [
_(msg`Posts`),
showRepliesTab ? _(msg`Replies`) : undefined,
_(msg`Media`),
showLikesTab ? _(msg`Likes`) : undefined,
showFeedsTab ? _(msg`Feeds`) : undefined,
showListsTab ? _(msg`Lists`) : undefined,
showModerationTab ? _(msg`Moderation`) : undefined,
].filter(Boolean) as string[]
}, [
showRepliesTab,
showLikesTab,
showFeedsTab,
showListsTab,
showModerationTab,
_,
])
let nextIndex = 0
const postsIndex = nextIndex++
let repliesIndex: number | null = null
if (showRepliesTab) {
repliesIndex = nextIndex++
}
const mediaIndex = nextIndex++
let likesIndex: number | null = null
if (showLikesTab) {
likesIndex = nextIndex++
}
let feedsIndex: number | null = null
if (showFeedsTab) {
feedsIndex = nextIndex++
}
let listsIndex: number | null = null
if (showListsTab) {
listsIndex = nextIndex++
}
let moderationIndex: number | null = null
if (showModerationTab) {
moderationIndex = nextIndex++
}
const scrollSectionToTop = React.useCallback(
(index: number) => {
if (index === postsIndex) {
postsSectionRef.current?.scrollToTop()
} else if (index === repliesIndex) {
repliesSectionRef.current?.scrollToTop()
} else if (index === mediaIndex) {
mediaSectionRef.current?.scrollToTop()
} else if (index === likesIndex) {
likesSectionRef.current?.scrollToTop()
} else if (index === feedsIndex) {
feedsSectionRef.current?.scrollToTop()
} else if (index === listsIndex) {
listsSectionRef.current?.scrollToTop()
} else if (index === moderationIndex) {
moderationSectionRef.current?.scrollToTop()
}
},
[
postsIndex,
repliesIndex,
mediaIndex,
likesIndex,
feedsIndex,
listsIndex,
moderationIndex,
],
)
useFocusEffect(
React.useCallback(() => {
setMinimalShellMode(false)
screen('Profile')
return listenSoftReset(() => {
scrollSectionToTop(currentPage)
})
}, [setMinimalShellMode, screen, currentPage, scrollSectionToTop]),
)
useFocusEffect(
React.useCallback(() => {
setDrawerSwipeDisabled(currentPage > 0)
return () => {
setDrawerSwipeDisabled(false)
}
}, [setDrawerSwipeDisabled, currentPage]),
)
// events
// =
const onPressCompose = React.useCallback(() => {
track('ProfileScreen:PressCompose')
const mention =
profile.handle === currentAccount?.handle ||
isInvalidHandle(profile.handle)
? undefined
: profile.handle
openComposer({mention})
}, [openComposer, currentAccount, track, profile])
const onPageSelected = React.useCallback(
(i: number) => {
setCurrentPage(i)
},
[setCurrentPage],
)
const onCurrentPageSelected = React.useCallback(
(index: number) => {
scrollSectionToTop(index)
},
[scrollSectionToTop],
)
// rendering
// =
const renderHeader = React.useCallback(() => {
return (
<ProfileHeader
profile={profile}
descriptionRT={hasDescription ? descriptionRT : null}
moderationOpts={moderationOpts}
hideBackButton={hideBackButton}
isPlaceholderProfile={showPlaceholder}
/>
)
}, [
profile,
descriptionRT,
hasDescription,
moderationOpts,
hideBackButton,
showPlaceholder,
])
return (
<ScreenHider
testID="profileView"
style={styles.container}
screenDescription="profile"
modui={moderation.ui('profileView')}>
<PagerWithHeader
testID="profilePager"
isHeaderReady={!showPlaceholder}
items={sectionTitles}
onPageSelected={onPageSelected}
onCurrentPageSelected={onCurrentPageSelected}
renderHeader={renderHeader}>
{({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={postsSectionRef}
feed={`author|${profile.did}|posts_and_author_threads`}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)}
{showRepliesTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={repliesSectionRef}
feed={`author|${profile.did}|posts_with_replies`}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)
: null}
{({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={mediaSectionRef}
feed={`author|${profile.did}|posts_with_media`}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)}
{showLikesTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={likesSectionRef}
feed={`likes|${profile.did}`}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)
: null}
{showFeedsTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileFeedgens
ref={feedsSectionRef}
did={profile.did}
scrollElRef={scrollElRef as ListRef}
headerOffset={headerHeight}
enabled={isFocused}
/>
)
: null}
{showListsTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileLists
ref={listsSectionRef}
did={profile.did}
scrollElRef={scrollElRef as ListRef}
headerOffset={headerHeight}
enabled={isFocused}
/>
)
: null}
{showModerationTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ModerationSection
// ref={moderationSectionRef}
did={profile.did}
scrollElRef={scrollElRef as ListRef}
headerOffset={headerHeight}
enabled={isFocused}
/>
)
: null}
</PagerWithHeader>
{hasSession && (
<FAB
testID="composeFAB"
onPress={onPressCompose}
icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
accessibilityRole="button"
accessibilityLabel={_(msg`New post`)}
accessibilityHint=""
/>
)}
</ScreenHider>
)
}
function ProfileScreenLoadedV2({
profile: profileUnshadowed,
isPlaceholderProfile,
moderationOpts,
hideBackButton,
}: {
profile: AppBskyActorDefs.ProfileViewDetailed
moderationOpts: ModerationOpts
hideBackButton: boolean
isPlaceholderProfile: boolean
}) {
const profile = useProfileShadow(profileUnshadowed)
const {hasSession, currentAccount} = useSession()
@@ -618,7 +310,7 @@ function ProfileScreenLoadedV2({
const renderHeader = React.useCallback(() => {
return (
<ProfileHeaderV2
<ProfileHeader
profile={profile}
modservice={modServiceQuery.data}
descriptionRT={hasDescription ? descriptionRT : null}
@@ -675,7 +367,7 @@ function ProfileScreenLoadedV2({
: null}
{showPostsTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
<ProfileFeedSection
ref={postsSectionRef}
feed={`author|${profile.did}|posts_and_author_threads`}
headerHeight={headerHeight}
@@ -687,7 +379,7 @@ function ProfileScreenLoadedV2({
: null}
{showRepliesTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
<ProfileFeedSection
ref={repliesSectionRef}
feed={`author|${profile.did}|posts_with_replies`}
headerHeight={headerHeight}
@@ -699,7 +391,7 @@ function ProfileScreenLoadedV2({
: null}
{showMediaTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
<ProfileFeedSection
ref={mediaSectionRef}
feed={`author|${profile.did}|posts_with_media`}
headerHeight={headerHeight}
@@ -711,7 +403,7 @@ function ProfileScreenLoadedV2({
: null}
{showLikesTab
? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection
<ProfileFeedSection
ref={likesSectionRef}
feed={`likes|${profile.did}`}
headerHeight={headerHeight}
@@ -758,126 +450,6 @@ function ProfileScreenLoadedV2({
)
}
interface FeedSectionProps {
feed: FeedDescriptor
headerHeight: number
isFocused: boolean
scrollElRef: ListRef
ignoreFilterFor?: string
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{feed, headerHeight, isFocused, scrollElRef, ignoreFilterFor},
ref,
) {
const {_} = useLingui()
const queryClient = useQueryClient()
const [hasNew, setHasNew] = React.useState(false)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const onScrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({
animated: isNative,
offset: -headerHeight,
})
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
setHasNew(false)
}, [scrollElRef, headerHeight, queryClient, feed, setHasNew])
React.useImperativeHandle(ref, () => ({
scrollToTop: onScrollToTop,
}))
const renderPostsEmpty = React.useCallback(() => {
return <EmptyState icon="feed" message={_(msg`This feed is empty!`)} />
}, [_])
return (
<View>
<Feed
testID="postsFeed"
enabled={isFocused}
feed={feed}
scrollElRef={scrollElRef}
onHasNew={setHasNew}
onScrolledDownChange={setIsScrolledDown}
renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight}
renderEndOfFeed={ProfileEndOfFeed}
ignoreFilterFor={ignoreFilterFor}
/>
{(isScrolledDown || hasNew) && (
<LoadLatestBtn
onPress={onScrollToTop}
label={_(msg`Load new posts`)}
showIndicator={hasNew}
/>
)}
</View>
)
},
)
function ProfileEndOfFeed() {
const pal = usePalette('default')
return (
<View style={[pal.border, {paddingTop: 32, borderTopWidth: 1}]}>
<Text style={[pal.textLight, pal.border, {textAlign: 'center'}]}>
<Trans>End of feed</Trans>
</Text>
</View>
)
}
function ModerationSection({did}: {did: string}) {
const t = useTheme()
return (
<ScrollView>
<ModerationServiceCard.Loader
did={did}
component={({modservice}) => (
<ModerationServiceCard.Link modservice={modservice}>
{ctx => (
<View
style={[
a.flex_1,
a.flex_row,
a.align_center,
a.gap_md,
a.p_md,
a.border_t,
t.atoms.border_contrast_low,
...(ctx.focused || ctx.hovered
? [t.atoms.bg_contrast_25]
: []),
]}>
<View
style={[
{backgroundColor: t.palette.negative_25},
a.p_lg,
a.rounded_sm,
]}>
<RaisingHand
width={36}
style={[a.z_10]}
fill={t.palette.negative_500}
/>
</View>
<ModerationServiceCard.Card.Content
title="Moderation service"
description={modservice.description}
handle={modservice.creator.handle}
likeCount={modservice.likeCount}
/>
</View>
)}
</ModerationServiceCard.Link>
)}
/>
</ScrollView>
)
}
function useRichText(text: string): [RichTextAPI, boolean] {
const [prevText, setPrevText] = React.useState(text)
const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text}))