tangled mirror of catsky-🐱 Soothing soft social-app fork with all the niche toggles! (Unofficial); for issues and PRs please put them on github:NekoDrone/catsky-social

Fix computation of `isLastSibling`, `isLastChild`, and `replyIndex` (#9202)

* Fix computation of isLastSibling and isLastChild to account for muted or
otherwise hidden replies

* Update comments

* isLastSiblingByCounts isn't needed, should rely only on the count of replies seen

* The counters serve the same purpose, we only need to know the count of the actual replies rendered to the view in order to calculate the replyIndex

* Remove redundant check

authored by Eric Bailey and committed by GitHub 27926f09 fe5a623b

Changed files
+28 -28
src
state
queries
+14 -14
src/state/queries/usePostThread/traversal.ts
··· 135 135 } else if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) { 136 136 if (parentMetadata) { 137 137 /* 138 - * Set this value before incrementing the parent's repliesSeenCounter 138 + * Set this value before incrementing the `repliesSeenCounter` later 139 + * on, since `repliesSeenCounter` is 1-indexed and `replyIndex` is 140 + * 0-indexed. 139 141 */ 140 - metadata!.replyIndex = parentMetadata.repliesIndexCounter 141 - // Increment the parent's repliesIndexCounter 142 - parentMetadata.repliesIndexCounter += 1 142 + metadata!.replyIndex = parentMetadata.repliesSeenCounter 143 143 } 144 144 145 145 const post = views.threadPost({ ··· 193 193 storeTraversalMetadata(metadatas, childMetadata) 194 194 if (childParentMetadata) { 195 195 /* 196 - * Set this value before incrementing the parent's repliesIndexCounter 196 + * Set this value before incrementing the 197 + * `repliesSeenCounter` later on, since `repliesSeenCounter` 198 + * is 1-indexed and `replyIndex` is 0-indexed. 197 199 */ 198 200 childMetadata!.replyIndex = 199 - childParentMetadata.repliesIndexCounter 200 - childParentMetadata.repliesIndexCounter += 1 201 + childParentMetadata.repliesSeenCounter 201 202 } 202 203 203 204 const childPost = views.threadPost({ ··· 264 265 if (nextItem?.type === 'threadPost') 265 266 metadata.nextItemDepth = nextItem?.depth 266 267 267 - /* 268 - * Item is the last "sibling" if we know for sure we're out of 269 - * replies on the parent (even though this item itself may have its 270 - * own reply branches). 268 + /** 269 + * Item is also the last "sibling" if its index matches the total 270 + * number of replies we're actually able to render to the page. 271 271 */ 272 - const isLastSiblingByCounts = 272 + const isLastSiblingDueToMissingReplies = 273 273 metadata.replyIndex === 274 - metadata.parentMetadata.repliesIndexCounter - 1 274 + metadata.parentMetadata.repliesSeenCounter - 1 275 275 276 276 /* 277 277 * Item can also be the last "sibling" if we know we don't have a ··· 287 287 * Ok now we can set the last sibling state. 288 288 */ 289 289 metadata.isLastSibling = 290 - isLastSiblingByCounts || isImplicitlyLastSibling 290 + isImplicitlyLastSibling || isLastSiblingDueToMissingReplies 291 291 292 292 /* 293 293 * Item is the last "child" in a branch if there is no next item,
+14 -13
src/state/queries/usePostThread/types.ts
··· 193 193 */ 194 194 repliesUnhydrated: number 195 195 /** 196 - * The number of replies that have been seen so far in the traversal. 197 - * Excludes replies that are moderated in some way, since those are not 198 - * "seen" on first load. Use `repliesIndexCounter` for the total number of 199 - * replies that were hydrated in the response. 196 + * The number of replies that have been "seen" (actually able to be rendered) 197 + * so far in the traversal. Excludes replies that are moderated in some way, 198 + * since those are not "seen" on first load. 200 199 * 201 - * After traversal, we can use this to calculate if we actually got all the 202 - * replies we expected, or if some were blocked, etc. 200 + * We use this to compute the `replyIndex` values of the children of this 201 + * parent. E.g. if a reply is not hydrated on the response, or is moderated 202 + * in some way (including by the user), this value is not incremented. So 203 + * this represents the _actual_ index of the reply in the rendered view. 204 + * 205 + * Note: this is a "counter", not an "index". Because this value is 206 + * incremented starting from 0, it is 1-indexed. So to when comparing to the 207 + * `replyIndex`, you'll need to subtract 1 from this value. 203 208 */ 204 209 repliesSeenCounter: number 205 210 /** 206 - * The total number of replies to this post hydrated in this response. Used 207 - * for populating the `replyIndex` of the post by referencing this value on 208 - * the parent. 209 - */ 210 - repliesIndexCounter: number 211 - /** 212 - * The index-0-based index of this reply in the parent post's replies. 211 + * The index-0-based index of this reply in the parent post's replies. This 212 + * is computed from the `repliesSeenCounter` of the parent post, prior to it 213 + * being incremented for this reply. 213 214 */ 214 215 replyIndex: number 215 216 /**
-1
src/state/queries/usePostThread/utils.ts
··· 99 99 repliesCount, 100 100 repliesUnhydrated, 101 101 repliesSeenCounter: 0, 102 - repliesIndexCounter: 0, 103 102 replyIndex: 0, 104 103 skippedIndentIndices: new Set<number>(), 105 104 }