Show just-posted replies above OP replies (#4901)

* Unify onPostReply handler

* Show just-posted replies above OP replies

* Only do this for the highlighted post or thread mode

It's confusing to have your post displace OP thread or other people's leaf posts.
zio/stable
dan 2024-08-08 19:19:58 +01:00 committed by GitHub
parent c1af767fa6
commit e782db33dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 10 deletions

View File

@ -137,6 +137,7 @@ export function sortThread(
opts: UsePreferencesQueryResponse['threadViewPrefs'],
modCache: ThreadModerationCache,
currentDid: string | undefined,
justPostedUris: Set<string>,
): ThreadNode {
if (node.type !== 'post') {
return node
@ -150,6 +151,20 @@ export function sortThread(
return -1
}
if (node.ctx.isHighlightedPost || opts.lab_treeViewEnabled) {
const aIsJustPosted =
a.post.author.did === currentDid && justPostedUris.has(a.post.uri)
const bIsJustPosted =
b.post.author.did === currentDid && justPostedUris.has(b.post.uri)
if (aIsJustPosted && bIsJustPosted) {
return a.post.indexedAt.localeCompare(b.post.indexedAt) // oldest
} else if (aIsJustPosted) {
return -1 // reply while onscreen
} else if (bIsJustPosted) {
return 1 // reply while onscreen
}
}
const aIsByOp = a.post.author.did === node.post?.author.did
const bIsByOp = b.post.author.did === node.post?.author.did
if (aIsByOp && bIsByOp) {
@ -206,7 +221,9 @@ export function sortThread(
}
return b.post.indexedAt.localeCompare(a.post.indexedAt)
})
node.replies.forEach(reply => sortThread(reply, opts, modCache, currentDid))
node.replies.forEach(reply =>
sortThread(reply, opts, modCache, currentDid, justPostedUris),
)
}
return node
}

View File

@ -1,10 +1,11 @@
import React from 'react'
import {
AppBskyActorDefs,
AppBskyEmbedRecord,
AppBskyRichtextFacet,
ModerationDecision,
AppBskyActorDefs,
} from '@atproto/api'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
export interface ComposerOptsPostRef {
@ -31,7 +32,7 @@ export interface ComposerOptsQuote {
}
export interface ComposerOpts {
replyTo?: ComposerOptsPostRef
onPost?: () => void
onPost?: (postUri: string | undefined) => void
quote?: ComposerOptsQuote
mention?: string // handle of user to mention
openPicker?: (pos: DOMRect | undefined) => void

View File

@ -392,7 +392,7 @@ export const ComposePost = observer(function ComposePost({
emitPostCreated()
}
setLangPrefs.savePostLanguageToHistory()
onPost?.()
onPost?.(postUri)
onClose()
Toast.show(
replyTo

View File

@ -160,12 +160,22 @@ export function PostThread({uri}: {uri: string | undefined}) {
return cache
}, [thread, moderationOpts])
const [justPostedUris, setJustPostedUris] = React.useState(
() => new Set<string>(),
)
const skeleton = React.useMemo(() => {
const threadViewPrefs = preferences?.threadViewPrefs
if (!threadViewPrefs || !thread) return null
return createThreadSkeleton(
sortThread(thread, threadViewPrefs, threadModerationCache, currentDid),
sortThread(
thread,
threadViewPrefs,
threadModerationCache,
currentDid,
justPostedUris,
),
!!currentDid,
treeView,
threadModerationCache,
@ -178,6 +188,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
treeView,
threadModerationCache,
hiddenRepliesState,
justPostedUris,
])
const error = React.useMemo(() => {
@ -302,6 +313,20 @@ export function PostThread({uri}: {uri: string | undefined}) {
setMaxReplies(prev => prev + 50)
}, [isFetching, maxReplies, posts.length])
const onPostReply = React.useCallback(
(postUri: string | undefined) => {
refetch()
if (postUri) {
setJustPostedUris(set => {
const nextSet = new Set(set)
nextSet.add(postUri)
return nextSet
})
}
},
[refetch],
)
const {openComposer} = useComposerControls()
const onPressReply = React.useCallback(() => {
if (thread?.type !== 'post') {
@ -315,9 +340,9 @@ export function PostThread({uri}: {uri: string | undefined}) {
author: thread.post.author,
embed: thread.post.embed,
},
onPost: () => refetch(),
onPost: onPostReply,
})
}, [openComposer, thread, refetch])
}, [openComposer, thread, onPostReply])
const canReply = !error && rootPost && !rootPost.viewer?.replyDisabled
const hasParents =
@ -415,7 +440,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
HiddenRepliesState.ShowAndOverridePostHider &&
item.ctx.depth > 0
}
onPostReply={refetch}
onPostReply={onPostReply}
hideTopBorder={index === 0 && !item.ctx.isParentLoading}
/>
</View>

View File

@ -75,7 +75,7 @@ export function PostThreadItem({
showParentReplyLine?: boolean
hasPrecedingItem: boolean
overrideBlur: boolean
onPostReply: () => void
onPostReply: (postUri: string | undefined) => void
hideTopBorder?: boolean
}) {
const postShadowed = usePostShadow(post)
@ -169,7 +169,7 @@ let PostThreadItemLoaded = ({
showParentReplyLine?: boolean
hasPrecedingItem: boolean
overrideBlur: boolean
onPostReply: () => void
onPostReply: (postUri: string | undefined) => void
hideTopBorder?: boolean
}): React.ReactNode => {
const pal = usePalette('default')