From ef3baf83687f4dbd4a7f7dba852d68725a7e71d7 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 25 May 2025 13:05:32 -0500 Subject: [PATCH] Update APIs --- src/state/queries/usePostThread/index.ts | 19 ++++------- src/state/queries/usePostThread/traversal.ts | 18 +++++++---- src/state/queries/usePostThread/types.ts | 22 ++++--------- src/state/queries/usePostThread/utils.ts | 15 --------- src/state/queries/usePostThread/views.ts | 7 ++-- src/view/screens/PostThread.tsx | 34 +++++++------------- 6 files changed, 42 insertions(+), 73 deletions(-) diff --git a/src/state/queries/usePostThread/index.ts b/src/state/queries/usePostThread/index.ts index f45d60bf6c..98702a54aa 100644 --- a/src/state/queries/usePostThread/index.ts +++ b/src/state/queries/usePostThread/index.ts @@ -11,17 +11,13 @@ import { HiddenReplyKind, type UsePostThreadProps, } from '#/state/queries/usePostThread/types' -import { - getThreadgateRecord, - mapSortOptionsToSortID, -} from '#/state/queries/usePostThread/utils' +import {getThreadgateRecord} from '#/state/queries/usePostThread/utils' import {useAgent, useSession} from '#/state/session' import {useMergeThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' export * from '#/state/queries/usePostThread/types' export function usePostThread({ - uri, enabled: isEnabled, params, state, @@ -32,9 +28,8 @@ export function usePostThread({ const moderationOpts = useModerationOpts() const mergeThreadgateHiddenReplies = useMergeThreadgateHiddenReplies() - const enabled = isEnabled !== false && !!uri && !!moderationOpts + const enabled = isEnabled !== false && !!params.anchor && !!moderationOpts const queryKey = createPostThreadQueryKey({ - uri, params, }) @@ -44,16 +39,17 @@ export function usePostThread({ gcTime: 0, async queryFn() { const {data} = await agent.app.bsky.unspecced.getPostThreadV2({ - anchor: uri!, + anchor: params.anchor!, branchingFactor: params.view === 'linear' ? 1 : 3, // 100 TODO below: 3, - sorting: mapSortOptionsToSortID(params.sort), + sort: params.sort, + prioritizeFollowedUsers: params.prioritizeFollowedUsers, }) return data }, placeholderData() { - if (!uri) return - const placeholder = getThreadPlaceholder(qc, uri) + if (!params.anchor) return + const placeholder = getThreadPlaceholder(qc, params.anchor) if (placeholder) { return {thread: [placeholder]} } @@ -96,7 +92,6 @@ export function usePostThread({ return { ...query, data: { - anchorIndex: items.findIndex(i => Boolean(i.ui?.isAnchor)), items, threadgate: query.data?.threadgate, }, diff --git a/src/state/queries/usePostThread/traversal.ts b/src/state/queries/usePostThread/traversal.ts index fa2a138386..842cd511b2 100644 --- a/src/state/queries/usePostThread/traversal.ts +++ b/src/state/queries/usePostThread/traversal.ts @@ -1,7 +1,6 @@ import { - APP_BSKY_UNSPECCED, - AtUri, AppBskyUnspeccedGetPostThreadV2, + AtUri, type ModerationDecision, type ModerationOpts, } from '@atproto/api' @@ -30,7 +29,11 @@ export function flatten( if (item.type === 'threadPost') { // TODO should not insert if not found post etc - if (item.ui.isAnchor && hasSession && !item.value.post.viewer?.replyDisabled) { + if ( + item.ui.isAnchor && + hasSession && + !item.value.post.viewer?.replyDisabled + ) { flattened.splice(i + 1, 0, { type: 'replyComposer', key: 'replyComposer', @@ -39,18 +42,19 @@ export function flatten( const prev = unhydratedReplyIntervals[unhydratedReplyIntervals.length - 1] - if (item.annotations.has(APP_BSKY_UNSPECCED.GetPostThreadV2HasMoreReplies)) { + if (item.value.moreReplies > 0) { unhydratedReplyIntervals.push({ item, - replyCount: item.value.post.replyCount || 0, + replyCount: item.value.moreReplies, }) } /* - * If direct child of previous item with `hasMoreReplies`, subtract + * If direct child of previous item with `hasMoreReplies`, subtract */ if (prev && item.depth === prev.item.depth + 1) { - prev.replyCount = Math.max(0, prev.replyCount - 1) + // TODO test if we need this + // prev.replyCount = Math.max(0, prev.replyCount - 1) } if (prev && item.depth <= prev.item.depth) { diff --git a/src/state/queries/usePostThread/types.ts b/src/state/queries/usePostThread/types.ts index 4a7f36ff20..11eab28249 100644 --- a/src/state/queries/usePostThread/types.ts +++ b/src/state/queries/usePostThread/types.ts @@ -1,28 +1,26 @@ import { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - type APP_BSKY_UNSPECCED, - type AtUri, type AppBskyFeedDefs, type AppBskyFeedPost, type AppBskyUnspeccedGetPostThreadV2, - type BskyThreadViewPreference, + type AtUri, type ModerationDecision, } from '@atproto/api' export const postThreadQueryKeyRoot = 'getPostThreadV2' as const export const createPostThreadQueryKey = ( - props: Pick, + props: Pick, ) => [postThreadQueryKeyRoot, props] as const -export type PostThreadParams = { +export type PostThreadParams = Pick< + AppBskyUnspeccedGetPostThreadV2.QueryParams, + 'sort' | 'prioritizeFollowedUsers' +> & { + anchor?: string view: 'tree' | 'linear' - sort: 'top' | 'oldest' | 'newest' | string - prioritizeFollows: BskyThreadViewPreference['prioritizeFollowedUsers'] } export type UsePostThreadProps = { - uri?: string enabled?: boolean params: PostThreadParams state: { @@ -47,12 +45,6 @@ export type Slice = } } moderation: ModerationDecision - /** - * Reference via {@link APP_BSKY_UNSPECCED} - */ - annotations: Set< - AppBskyUnspeccedGetPostThreadV2.ThreadItemPost['annotations'][number] - > ui: { isAnchor: boolean showParentReplyLine: boolean diff --git a/src/state/queries/usePostThread/utils.ts b/src/state/queries/usePostThread/utils.ts index 7e7b274a63..efcb45b02d 100644 --- a/src/state/queries/usePostThread/utils.ts +++ b/src/state/queries/usePostThread/utils.ts @@ -1,5 +1,4 @@ import { - APP_BSKY_UNSPECCED, type AppBskyFeedDefs, AppBskyFeedPost, AppBskyFeedThreadgate, @@ -7,22 +6,8 @@ import { AtUri, } from '@atproto/api' -import {type PostThreadParams} from '#/state/queries/usePostThread/types' import * as bsky from '#/types/bsky' -export function mapSortOptionsToSortID(sort: PostThreadParams['sort']) { - switch (sort) { - case 'top': - return APP_BSKY_UNSPECCED.GetPostThreadV2Top - case 'oldest': - return APP_BSKY_UNSPECCED.GetPostThreadV2Oldest - case 'newest': - return APP_BSKY_UNSPECCED.GetPostThreadV2Newest - default: - return APP_BSKY_UNSPECCED.GetPostThreadV2Top - } -} - export function getThreadgateRecord( view: AppBskyUnspeccedGetPostThreadV2.OutputSchema['threadgate'], ) { diff --git a/src/state/queries/usePostThread/views.ts b/src/state/queries/usePostThread/views.ts index 50c0d27a82..002ffa79db 100644 --- a/src/state/queries/usePostThread/views.ts +++ b/src/state/queries/usePostThread/views.ts @@ -90,7 +90,6 @@ export function threadPost({ record: AppBskyFeedPost.Record }, }, - annotations: new Set(value.annotations), moderation: moderatePost(value.post, moderationOpts), ui: { isAnchor: depth === 0, @@ -114,7 +113,11 @@ export function postViewToThreadPlaceholder( value: { $type: 'app.bsky.unspecced.getPostThreadV2#threadItemPost', post, - annotations: [], + hiddenByThreadgate: false, + opThread: false, + moreParents: false, + moreReplies: 0, + mutedByViewer: false, }, } } diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx index 68001a3ce3..652644aa5c 100644 --- a/src/view/screens/PostThread.tsx +++ b/src/view/screens/PostThread.tsx @@ -5,24 +5,25 @@ import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' import {HITSLOP_10} from '#/lib/constants' +// import {PostThread as PostThreadComponent} from '#/view/com/post-thread/PostThread' +import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' +import {makeProfileLink} from '#/lib/routes/links' import { type CommonNavigatorParams, type NativeStackScreenProps, } from '#/lib/routes/types' +import {ScrollProvider} from '#/lib/ScrollContext' import {cleanError} from '#/lib/strings/errors' import {makeRecordUri} from '#/lib/strings/url-helpers' import {isNative} from '#/platform/detection' -import {useSetMinimalShellMode} from '#/state/shell' -import {PostThread as PostThreadComponent} from '#/view/com/post-thread/PostThread' -import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' -import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {ScrollProvider} from '#/lib/ScrollContext' import {usePreferencesQuery} from '#/state/queries/preferences' import { HiddenReplyKind, type Slice, usePostThread, } from '#/state/queries/usePostThread' +import {useSetMinimalShellMode} from '#/state/shell' import {type OnPostSuccessData} from '#/state/shell/composer' import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt' import {PostThreadItem} from '#/view/com/post-thread/PostThreadItem' @@ -30,21 +31,14 @@ import {PostThreadShowHiddenReplies} from '#/view/com/post-thread/PostThreadShow import {List, type ListMethods} from '#/view/com/util/List' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' -import {Link} from '#/components/Link' -import {makeProfileLink} from '#/lib/routes/links' -import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider' import {CirclePlus_Stroke2_Corner0_Rounded as CirclePlus} from '#/components/icons/CirclePlus' +import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider' import * as Layout from '#/components/Layout' +import {Link} from '#/components/Link' import {ListFooter} from '#/components/Lists' import * as Menu from '#/components/Menu' import {Text} from '#/components/Typography' -const MAINTAIN_VISIBLE_CONTENT_POSITION = { - // We don't insert any elements before the root row while loading. - // So the row we want to use as the scroll anchor is the first row. - minIndexForVisible: 0, -} - type Props = NativeStackScreenProps export function PostThreadScreen({route}: Props) { const setMinimalShellMode = useSetMinimalShellMode() @@ -144,12 +138,12 @@ export function Inner({uri}: {uri: string | undefined}) { >(new Set()) const {isFetching, error, data, refetch, insertReplies} = usePostThread({ - uri, enabled: isThreadPreferencesLoaded, params: { + anchor: uri, sort: sortReplies, view: treeViewEnabled ? 'tree' : 'linear', - prioritizeFollows: prioritizeFollowedUsers, + prioritizeFollowedUsers, }, state: { shownHiddenReplyKinds, @@ -236,9 +230,7 @@ export function Inner({uri}: {uri: string | undefined}) { hasMore={false} // TODO need to replace this entirely showChildReplyLine={item.ui.showChildReplyLine} showParentReplyLine={item.ui.showParentReplyLine} - hasPrecedingItem={ - item.ui.showParentReplyLine - } // !!hasUnrevealedParents // TODO + hasPrecedingItem={item.ui.showParentReplyLine} // !!hasUnrevealedParents // TODO overrideBlur={ shownHiddenReplyKinds.has(HiddenReplyKind.Muted) && item.depth > 0 } @@ -358,8 +350,6 @@ export function Inner({uri}: {uri: string | undefined}) { return null } - console.log('PostThreadScreen', data?.anchorIndex) - return ( <> @@ -400,7 +390,7 @@ export function Inner({uri}: {uri: string | undefined}) { */ maintainVisibleContentPosition={ isNative // && hasParents // TODO not sure we need this - ? { minIndexForVisible: 0 } // MAINTAIN_VISIBLE_CONTENT_POSITION + ? {minIndexForVisible: 0} // MAINTAIN_VISIBLE_CONTENT_POSITION : undefined } desktopFixedHeight