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
parent
c1af767fa6
commit
e782db33dc
|
@ -137,6 +137,7 @@ export function sortThread(
|
||||||
opts: UsePreferencesQueryResponse['threadViewPrefs'],
|
opts: UsePreferencesQueryResponse['threadViewPrefs'],
|
||||||
modCache: ThreadModerationCache,
|
modCache: ThreadModerationCache,
|
||||||
currentDid: string | undefined,
|
currentDid: string | undefined,
|
||||||
|
justPostedUris: Set<string>,
|
||||||
): ThreadNode {
|
): ThreadNode {
|
||||||
if (node.type !== 'post') {
|
if (node.type !== 'post') {
|
||||||
return node
|
return node
|
||||||
|
@ -150,6 +151,20 @@ export function sortThread(
|
||||||
return -1
|
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 aIsByOp = a.post.author.did === node.post?.author.did
|
||||||
const bIsByOp = b.post.author.did === node.post?.author.did
|
const bIsByOp = b.post.author.did === node.post?.author.did
|
||||||
if (aIsByOp && bIsByOp) {
|
if (aIsByOp && bIsByOp) {
|
||||||
|
@ -206,7 +221,9 @@ export function sortThread(
|
||||||
}
|
}
|
||||||
return b.post.indexedAt.localeCompare(a.post.indexedAt)
|
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
|
return node
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {
|
||||||
|
AppBskyActorDefs,
|
||||||
AppBskyEmbedRecord,
|
AppBskyEmbedRecord,
|
||||||
AppBskyRichtextFacet,
|
AppBskyRichtextFacet,
|
||||||
ModerationDecision,
|
ModerationDecision,
|
||||||
AppBskyActorDefs,
|
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
|
|
||||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||||
|
|
||||||
export interface ComposerOptsPostRef {
|
export interface ComposerOptsPostRef {
|
||||||
|
@ -31,7 +32,7 @@ export interface ComposerOptsQuote {
|
||||||
}
|
}
|
||||||
export interface ComposerOpts {
|
export interface ComposerOpts {
|
||||||
replyTo?: ComposerOptsPostRef
|
replyTo?: ComposerOptsPostRef
|
||||||
onPost?: () => void
|
onPost?: (postUri: string | undefined) => void
|
||||||
quote?: ComposerOptsQuote
|
quote?: ComposerOptsQuote
|
||||||
mention?: string // handle of user to mention
|
mention?: string // handle of user to mention
|
||||||
openPicker?: (pos: DOMRect | undefined) => void
|
openPicker?: (pos: DOMRect | undefined) => void
|
||||||
|
|
|
@ -392,7 +392,7 @@ export const ComposePost = observer(function ComposePost({
|
||||||
emitPostCreated()
|
emitPostCreated()
|
||||||
}
|
}
|
||||||
setLangPrefs.savePostLanguageToHistory()
|
setLangPrefs.savePostLanguageToHistory()
|
||||||
onPost?.()
|
onPost?.(postUri)
|
||||||
onClose()
|
onClose()
|
||||||
Toast.show(
|
Toast.show(
|
||||||
replyTo
|
replyTo
|
||||||
|
|
|
@ -160,12 +160,22 @@ export function PostThread({uri}: {uri: string | undefined}) {
|
||||||
return cache
|
return cache
|
||||||
}, [thread, moderationOpts])
|
}, [thread, moderationOpts])
|
||||||
|
|
||||||
|
const [justPostedUris, setJustPostedUris] = React.useState(
|
||||||
|
() => new Set<string>(),
|
||||||
|
)
|
||||||
|
|
||||||
const skeleton = React.useMemo(() => {
|
const skeleton = React.useMemo(() => {
|
||||||
const threadViewPrefs = preferences?.threadViewPrefs
|
const threadViewPrefs = preferences?.threadViewPrefs
|
||||||
if (!threadViewPrefs || !thread) return null
|
if (!threadViewPrefs || !thread) return null
|
||||||
|
|
||||||
return createThreadSkeleton(
|
return createThreadSkeleton(
|
||||||
sortThread(thread, threadViewPrefs, threadModerationCache, currentDid),
|
sortThread(
|
||||||
|
thread,
|
||||||
|
threadViewPrefs,
|
||||||
|
threadModerationCache,
|
||||||
|
currentDid,
|
||||||
|
justPostedUris,
|
||||||
|
),
|
||||||
!!currentDid,
|
!!currentDid,
|
||||||
treeView,
|
treeView,
|
||||||
threadModerationCache,
|
threadModerationCache,
|
||||||
|
@ -178,6 +188,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
|
||||||
treeView,
|
treeView,
|
||||||
threadModerationCache,
|
threadModerationCache,
|
||||||
hiddenRepliesState,
|
hiddenRepliesState,
|
||||||
|
justPostedUris,
|
||||||
])
|
])
|
||||||
|
|
||||||
const error = React.useMemo(() => {
|
const error = React.useMemo(() => {
|
||||||
|
@ -302,6 +313,20 @@ export function PostThread({uri}: {uri: string | undefined}) {
|
||||||
setMaxReplies(prev => prev + 50)
|
setMaxReplies(prev => prev + 50)
|
||||||
}, [isFetching, maxReplies, posts.length])
|
}, [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 {openComposer} = useComposerControls()
|
||||||
const onPressReply = React.useCallback(() => {
|
const onPressReply = React.useCallback(() => {
|
||||||
if (thread?.type !== 'post') {
|
if (thread?.type !== 'post') {
|
||||||
|
@ -315,9 +340,9 @@ export function PostThread({uri}: {uri: string | undefined}) {
|
||||||
author: thread.post.author,
|
author: thread.post.author,
|
||||||
embed: thread.post.embed,
|
embed: thread.post.embed,
|
||||||
},
|
},
|
||||||
onPost: () => refetch(),
|
onPost: onPostReply,
|
||||||
})
|
})
|
||||||
}, [openComposer, thread, refetch])
|
}, [openComposer, thread, onPostReply])
|
||||||
|
|
||||||
const canReply = !error && rootPost && !rootPost.viewer?.replyDisabled
|
const canReply = !error && rootPost && !rootPost.viewer?.replyDisabled
|
||||||
const hasParents =
|
const hasParents =
|
||||||
|
@ -415,7 +440,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
|
||||||
HiddenRepliesState.ShowAndOverridePostHider &&
|
HiddenRepliesState.ShowAndOverridePostHider &&
|
||||||
item.ctx.depth > 0
|
item.ctx.depth > 0
|
||||||
}
|
}
|
||||||
onPostReply={refetch}
|
onPostReply={onPostReply}
|
||||||
hideTopBorder={index === 0 && !item.ctx.isParentLoading}
|
hideTopBorder={index === 0 && !item.ctx.isParentLoading}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -75,7 +75,7 @@ export function PostThreadItem({
|
||||||
showParentReplyLine?: boolean
|
showParentReplyLine?: boolean
|
||||||
hasPrecedingItem: boolean
|
hasPrecedingItem: boolean
|
||||||
overrideBlur: boolean
|
overrideBlur: boolean
|
||||||
onPostReply: () => void
|
onPostReply: (postUri: string | undefined) => void
|
||||||
hideTopBorder?: boolean
|
hideTopBorder?: boolean
|
||||||
}) {
|
}) {
|
||||||
const postShadowed = usePostShadow(post)
|
const postShadowed = usePostShadow(post)
|
||||||
|
@ -169,7 +169,7 @@ let PostThreadItemLoaded = ({
|
||||||
showParentReplyLine?: boolean
|
showParentReplyLine?: boolean
|
||||||
hasPrecedingItem: boolean
|
hasPrecedingItem: boolean
|
||||||
overrideBlur: boolean
|
overrideBlur: boolean
|
||||||
onPostReply: () => void
|
onPostReply: (postUri: string | undefined) => void
|
||||||
hideTopBorder?: boolean
|
hideTopBorder?: boolean
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
Loading…
Reference in New Issue