Add annotations

This commit is contained in:
Eric Bailey
2025-05-22 16:23:03 -05:00
parent a16f5ecbff
commit 2183de7452
6 changed files with 31 additions and 45 deletions
+2 -2
View File
@@ -43,8 +43,8 @@ export function usePostThread({
queryKey, queryKey,
async queryFn() { async queryFn() {
const {data} = await agent.app.bsky.unspecced.getPostThreadV2({ const {data} = await agent.app.bsky.unspecced.getPostThreadV2({
uri: uri!, anchor: uri!,
nestedBranchingFactor: params.view === 'linear' ? 1 : 10, branchingFactor: params.view === 'linear' ? 1 : 10,
below: 10, below: 10,
sorting: mapSortOptionsToSortID(params.sort), sorting: mapSortOptionsToSortID(params.sort),
}) })
+11 -5
View File
@@ -193,8 +193,9 @@ export function sort(
moderationOpts, moderationOpts,
}) })
const postMod = getModerationState(post.moderation) const postMod = getModerationState(post.moderation)
const postIsHidden = threadgateHiddenReplies.has(item.uri) const postIsHiddenByThreadgate = threadgateHiddenReplies.has(item.uri)
const postIsModerated = postIsHidden || postMod.blurred || postMod.muted const postIsModerated =
postIsHiddenByThreadgate || postMod.blurred || postMod.muted
if (!postIsModerated) { if (!postIsModerated) {
/* /*
@@ -233,15 +234,20 @@ export function sort(
oneDown: thread[ci + 1], oneDown: thread[ci + 1],
moderationOpts, moderationOpts,
}) })
const childMod = getModerationState(childPost.moderation) const childPostMod = getModerationState(childPost.moderation)
const childIsHidden = threadgateHiddenReplies.has(child.uri) const childPostIsHiddenByThreadgate =
threadgateHiddenReplies.has(child.uri)
/* /*
* If a child is hidden in any way, drop it an its sub-branch * If a child is hidden in any way, drop it an its sub-branch
* entirely. To reveal these, the user must navigate to the * entirely. To reveal these, the user must navigate to the
* parent post directly. * parent post directly.
*/ */
if (childMod.blurred || childMod.muted || childIsHidden) { if (
childPostMod.blurred ||
childPostMod.muted ||
childPostIsHiddenByThreadgate
) {
ci = getBranch(thread, ci, child.depth).end ci = getBranch(thread, ci, child.depth).end
} else { } else {
sortArray.push(childPost) sortArray.push(childPost)
+9 -1
View File
@@ -1,4 +1,6 @@
import { import {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type APP_BSKY_UNSPECCED,
type AppBskyFeedDefs, type AppBskyFeedDefs,
type AppBskyFeedPost, type AppBskyFeedPost,
type AppBskyUnspeccedGetPostThreadV2, type AppBskyUnspeccedGetPostThreadV2,
@@ -14,7 +16,7 @@ export const createPostThreadQueryKey = (
export type PostThreadParams = { export type PostThreadParams = {
view: 'tree' | 'linear' view: 'tree' | 'linear'
sort: 'hotness' | 'oldest' | 'newest' | 'most-likes' | 'random' | string sort: 'top' | 'oldest' | 'newest' | string
prioritizeFollows: BskyThreadViewPreference['prioritizeFollowedUsers'] prioritizeFollows: BskyThreadViewPreference['prioritizeFollowedUsers']
} }
@@ -44,6 +46,12 @@ export type Slice =
} }
} }
moderation: ModerationDecision moderation: ModerationDecision
/**
* Reference via {@link APP_BSKY_UNSPECCED}
*/
annotations: Set<
AppBskyUnspeccedGetPostThreadV2.ThreadItemPost['annotations'][number]
>
ui: { ui: {
isAnchor: boolean isAnchor: boolean
showParentReplyLine: boolean showParentReplyLine: boolean
+3 -5
View File
@@ -12,16 +12,14 @@ import * as bsky from '#/types/bsky'
export function mapSortOptionsToSortID(sort: PostThreadParams['sort']) { export function mapSortOptionsToSortID(sort: PostThreadParams['sort']) {
switch (sort) { switch (sort) {
case 'hotness': case 'top':
return APP_BSKY_UNSPECCED.GetPostThreadV2Hotness return APP_BSKY_UNSPECCED.GetPostThreadV2Top
case 'oldest': case 'oldest':
return APP_BSKY_UNSPECCED.GetPostThreadV2Oldest return APP_BSKY_UNSPECCED.GetPostThreadV2Oldest
case 'newest': case 'newest':
return APP_BSKY_UNSPECCED.GetPostThreadV2Newest return APP_BSKY_UNSPECCED.GetPostThreadV2Newest
case 'most-likes':
return APP_BSKY_UNSPECCED.GetPostThreadV2MostLikes
default: default:
return APP_BSKY_UNSPECCED.GetPostThreadV2Hotness return APP_BSKY_UNSPECCED.GetPostThreadV2Top
} }
} }
+2 -8
View File
@@ -90,6 +90,7 @@ export function threadPost({
record: AppBskyFeedPost.Record record: AppBskyFeedPost.Record
}, },
}, },
annotations: new Set(value.annotations),
moderation: moderatePost(value.post, moderationOpts), moderation: moderatePost(value.post, moderationOpts),
ui: { ui: {
isAnchor: depth === 0, isAnchor: depth === 0,
@@ -99,8 +100,6 @@ export function threadPost({
} }
} }
// export function threadPostNoOp({ })
export function postViewToThreadPlaceholder( export function postViewToThreadPlaceholder(
post: AppBskyFeedDefs.PostView, post: AppBskyFeedDefs.PostView,
): $Typed< ): $Typed<
@@ -115,12 +114,7 @@ export function postViewToThreadPlaceholder(
value: { value: {
$type: 'app.bsky.unspecced.getPostThreadV2#threadItemPost', $type: 'app.bsky.unspecced.getPostThreadV2#threadItemPost',
post, post,
isOPThread: false, // unknown annotations: [],
hasOPLike: false, // unknown
// @ts-expect-error
hasUnhydratedReplies: false, // unknown
// TODO test
hasUnhydratedParents: !!(post.record as AppBskyFeedPost.Record).reply, // unknown
}, },
} }
} }
+4 -24
View File
@@ -447,14 +447,14 @@ function ThreadMenu({
</Menu.LabelText> </Menu.LabelText>
<Menu.Group> <Menu.Group>
<Menu.Item <Menu.Item
label={_(msg`Hot replies first`)} label={_(msg`Top replies first`)}
onPress={() => { onPress={() => {
setSortReplies('hotness') setSortReplies('top')
}}> }}>
<Menu.ItemText> <Menu.ItemText>
<Trans>Hot replies first</Trans> <Trans>Top replies first</Trans>
</Menu.ItemText> </Menu.ItemText>
<Menu.ItemRadio selected={sortReplies === 'hotness'} /> <Menu.ItemRadio selected={sortReplies === 'top'} />
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
label={_(msg`Oldest replies first`)} label={_(msg`Oldest replies first`)}
@@ -476,26 +476,6 @@ function ThreadMenu({
</Menu.ItemText> </Menu.ItemText>
<Menu.ItemRadio selected={sortReplies === 'newest'} /> <Menu.ItemRadio selected={sortReplies === 'newest'} />
</Menu.Item> </Menu.Item>
<Menu.Item
label={_(msg`Most-liked replies first`)}
onPress={() => {
setSortReplies('most-likes')
}}>
<Menu.ItemText>
<Trans>Most-liked replies first</Trans>
</Menu.ItemText>
<Menu.ItemRadio selected={sortReplies === 'most-likes'} />
</Menu.Item>
<Menu.Item
label={_(msg`Random (aka "Poster's Roulette")`)}
onPress={() => {
setSortReplies('random')
}}>
<Menu.ItemText>
<Trans>Random (aka "Poster's Roulette")</Trans>
</Menu.ItemText>
<Menu.ItemRadio selected={sortReplies === 'random'} />
</Menu.Item>
</Menu.Group> </Menu.Group>
</Menu.Outer> </Menu.Outer>
</Menu.Root> </Menu.Root>