Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

authored by

dan and committed by
GitHub
e782db33 c1af767f

+53 -10
+18 -1
src/state/queries/post-thread.ts
··· 137 137 opts: UsePreferencesQueryResponse['threadViewPrefs'], 138 138 modCache: ThreadModerationCache, 139 139 currentDid: string | undefined, 140 + justPostedUris: Set<string>, 140 141 ): ThreadNode { 141 142 if (node.type !== 'post') { 142 143 return node ··· 148 149 } 149 150 if (b.type !== 'post') { 150 151 return -1 152 + } 153 + 154 + if (node.ctx.isHighlightedPost || opts.lab_treeViewEnabled) { 155 + const aIsJustPosted = 156 + a.post.author.did === currentDid && justPostedUris.has(a.post.uri) 157 + const bIsJustPosted = 158 + b.post.author.did === currentDid && justPostedUris.has(b.post.uri) 159 + if (aIsJustPosted && bIsJustPosted) { 160 + return a.post.indexedAt.localeCompare(b.post.indexedAt) // oldest 161 + } else if (aIsJustPosted) { 162 + return -1 // reply while onscreen 163 + } else if (bIsJustPosted) { 164 + return 1 // reply while onscreen 165 + } 151 166 } 152 167 153 168 const aIsByOp = a.post.author.did === node.post?.author.did ··· 206 221 } 207 222 return b.post.indexedAt.localeCompare(a.post.indexedAt) 208 223 }) 209 - node.replies.forEach(reply => sortThread(reply, opts, modCache, currentDid)) 224 + node.replies.forEach(reply => 225 + sortThread(reply, opts, modCache, currentDid, justPostedUris), 226 + ) 210 227 } 211 228 return node 212 229 }
+3 -2
src/state/shell/composer.tsx
··· 1 1 import React from 'react' 2 2 import { 3 + AppBskyActorDefs, 3 4 AppBskyEmbedRecord, 4 5 AppBskyRichtextFacet, 5 6 ModerationDecision, 6 - AppBskyActorDefs, 7 7 } from '@atproto/api' 8 + 8 9 import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' 9 10 10 11 export interface ComposerOptsPostRef { ··· 31 32 } 32 33 export interface ComposerOpts { 33 34 replyTo?: ComposerOptsPostRef 34 - onPost?: () => void 35 + onPost?: (postUri: string | undefined) => void 35 36 quote?: ComposerOptsQuote 36 37 mention?: string // handle of user to mention 37 38 openPicker?: (pos: DOMRect | undefined) => void
+1 -1
src/view/com/composer/Composer.tsx
··· 392 392 emitPostCreated() 393 393 } 394 394 setLangPrefs.savePostLanguageToHistory() 395 - onPost?.() 395 + onPost?.(postUri) 396 396 onClose() 397 397 Toast.show( 398 398 replyTo
+29 -4
src/view/com/post-thread/PostThread.tsx
··· 160 160 return cache 161 161 }, [thread, moderationOpts]) 162 162 163 + const [justPostedUris, setJustPostedUris] = React.useState( 164 + () => new Set<string>(), 165 + ) 166 + 163 167 const skeleton = React.useMemo(() => { 164 168 const threadViewPrefs = preferences?.threadViewPrefs 165 169 if (!threadViewPrefs || !thread) return null 166 170 167 171 return createThreadSkeleton( 168 - sortThread(thread, threadViewPrefs, threadModerationCache, currentDid), 172 + sortThread( 173 + thread, 174 + threadViewPrefs, 175 + threadModerationCache, 176 + currentDid, 177 + justPostedUris, 178 + ), 169 179 !!currentDid, 170 180 treeView, 171 181 threadModerationCache, ··· 178 188 treeView, 179 189 threadModerationCache, 180 190 hiddenRepliesState, 191 + justPostedUris, 181 192 ]) 182 193 183 194 const error = React.useMemo(() => { ··· 302 313 setMaxReplies(prev => prev + 50) 303 314 }, [isFetching, maxReplies, posts.length]) 304 315 316 + const onPostReply = React.useCallback( 317 + (postUri: string | undefined) => { 318 + refetch() 319 + if (postUri) { 320 + setJustPostedUris(set => { 321 + const nextSet = new Set(set) 322 + nextSet.add(postUri) 323 + return nextSet 324 + }) 325 + } 326 + }, 327 + [refetch], 328 + ) 329 + 305 330 const {openComposer} = useComposerControls() 306 331 const onPressReply = React.useCallback(() => { 307 332 if (thread?.type !== 'post') { ··· 315 340 author: thread.post.author, 316 341 embed: thread.post.embed, 317 342 }, 318 - onPost: () => refetch(), 343 + onPost: onPostReply, 319 344 }) 320 - }, [openComposer, thread, refetch]) 345 + }, [openComposer, thread, onPostReply]) 321 346 322 347 const canReply = !error && rootPost && !rootPost.viewer?.replyDisabled 323 348 const hasParents = ··· 415 440 HiddenRepliesState.ShowAndOverridePostHider && 416 441 item.ctx.depth > 0 417 442 } 418 - onPostReply={refetch} 443 + onPostReply={onPostReply} 419 444 hideTopBorder={index === 0 && !item.ctx.isParentLoading} 420 445 /> 421 446 </View>
+2 -2
src/view/com/post-thread/PostThreadItem.tsx
··· 75 75 showParentReplyLine?: boolean 76 76 hasPrecedingItem: boolean 77 77 overrideBlur: boolean 78 - onPostReply: () => void 78 + onPostReply: (postUri: string | undefined) => void 79 79 hideTopBorder?: boolean 80 80 }) { 81 81 const postShadowed = usePostShadow(post) ··· 169 169 showParentReplyLine?: boolean 170 170 hasPrecedingItem: boolean 171 171 overrideBlur: boolean 172 - onPostReply: () => void 172 + onPostReply: (postUri: string | undefined) => void 173 173 hideTopBorder?: boolean 174 174 }): React.ReactNode => { 175 175 const pal = usePalette('default')