Fix to an edge case with feed re-ordering for threads (#172)
This commit is contained in:
@@ -569,11 +569,46 @@ function preprocessFeed(feed: FeedViewPost[]): FeedViewPostWithThreadMeta[] {
|
|||||||
reorg.unshift(item)
|
reorg.unshift(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// phase two: identify the positions of the threads
|
// phase two: reorder the feed so that the timestamp of the
|
||||||
|
// last post in a thread establishes its ordering
|
||||||
|
let threadSlices: Slice[] = identifyThreadSlices(reorg)
|
||||||
|
for (const slice of threadSlices) {
|
||||||
|
const removed: FeedViewPostWithThreadMeta[] = reorg.splice(
|
||||||
|
slice.index,
|
||||||
|
slice.length,
|
||||||
|
)
|
||||||
|
const targetDate = new Date(ts(removed[removed.length - 1]))
|
||||||
|
let newIndex = reorg.findIndex(item => new Date(ts(item)) < targetDate)
|
||||||
|
if (newIndex === -1) {
|
||||||
|
newIndex = reorg.length
|
||||||
|
}
|
||||||
|
reorg.splice(newIndex, 0, ...removed)
|
||||||
|
slice.index = newIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
// phase three: compress any threads that are longer than 3 posts
|
||||||
|
let removedCount = 0
|
||||||
|
// phase 2 moved posts around, so we need to re-identify the slice indices
|
||||||
|
threadSlices = identifyThreadSlices(reorg)
|
||||||
|
for (const slice of threadSlices) {
|
||||||
|
if (slice.length > 3) {
|
||||||
|
reorg.splice(slice.index - removedCount + 1, slice.length - 3)
|
||||||
|
if (reorg[slice.index - removedCount]) {
|
||||||
|
// ^ sanity check
|
||||||
|
reorg[slice.index - removedCount]._isThreadChildElided = true
|
||||||
|
}
|
||||||
|
removedCount += slice.length - 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reorg
|
||||||
|
}
|
||||||
|
|
||||||
|
function identifyThreadSlices(feed: FeedViewPost[]): Slice[] {
|
||||||
let activeSlice = -1
|
let activeSlice = -1
|
||||||
let threadSlices: Slice[] = []
|
let threadSlices: Slice[] = []
|
||||||
for (let i = 0; i < reorg.length; i++) {
|
for (let i = 0; i < feed.length; i++) {
|
||||||
const item = reorg[i] as FeedViewPostWithThreadMeta
|
const item = feed[i] as FeedViewPostWithThreadMeta
|
||||||
if (activeSlice === -1) {
|
if (activeSlice === -1) {
|
||||||
if (item._isThreadParent) {
|
if (item._isThreadParent) {
|
||||||
activeSlice = i
|
activeSlice = i
|
||||||
@@ -590,39 +625,9 @@ function preprocessFeed(feed: FeedViewPost[]): FeedViewPostWithThreadMeta[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activeSlice !== -1) {
|
if (activeSlice !== -1) {
|
||||||
threadSlices.push({index: activeSlice, length: reorg.length - activeSlice})
|
threadSlices.push({index: activeSlice, length: feed.length - activeSlice})
|
||||||
}
|
}
|
||||||
|
return threadSlices
|
||||||
// phase three: reorder the feed so that the timestamp of the
|
|
||||||
// last post in a thread establishes its ordering
|
|
||||||
for (const slice of threadSlices) {
|
|
||||||
const removed: FeedViewPostWithThreadMeta[] = reorg.splice(
|
|
||||||
slice.index,
|
|
||||||
slice.length,
|
|
||||||
)
|
|
||||||
const targetDate = new Date(ts(removed[removed.length - 1]))
|
|
||||||
let newIndex = reorg.findIndex(item => new Date(ts(item)) < targetDate)
|
|
||||||
if (newIndex === -1) {
|
|
||||||
newIndex = reorg.length
|
|
||||||
}
|
|
||||||
reorg.splice(newIndex, 0, ...removed)
|
|
||||||
slice.index = newIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// phase four: compress any threads that are longer than 3 posts
|
|
||||||
let removedCount = 0
|
|
||||||
for (const slice of threadSlices) {
|
|
||||||
if (slice.length > 3) {
|
|
||||||
reorg.splice(slice.index - removedCount + 1, slice.length - 3)
|
|
||||||
if (reorg[slice.index - removedCount]) {
|
|
||||||
// ^ sanity check
|
|
||||||
reorg[slice.index - removedCount]._isThreadChildElided = true
|
|
||||||
}
|
|
||||||
removedCount += slice.length - 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return reorg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: mutates `feed`
|
// WARNING: mutates `feed`
|
||||||
|
|||||||
Reference in New Issue
Block a user