Skip to content

Commit 5cdd576

Browse files
fix: sort comments for proper threads ordering
1 parent 766d02a commit 5cdd576

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

src/routes/[pid=pid]/[org]/[repo]/[id=number]/PageRenderer.svelte

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,71 @@
133133
]
134134
: [])
135135
]);
136+
137+
/**
138+
* Sort comments for discussions so that they simply have to be indented
139+
* if answers to properly look like threads of comments.
140+
*
141+
* @param comments the input comments
142+
* @returns the sorted comments
143+
*/
144+
function sortComments(comments: Props["comments"]): Props["comments"] {
145+
// Check if the array contains tree items (with parent_id)
146+
// We only need to check the first item since we know all items are of the same type
147+
const hasParentId = comments[0] && "parent_id" in comments[0];
148+
149+
// If these are simple items, just sort by date and return
150+
if (!hasParentId) {
151+
return (comments as IssueDetails["comments"]).sort(
152+
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
153+
);
154+
}
155+
156+
// We know we're dealing with TreeItems at this point
157+
const discussionComments = comments as DiscussionDetails["comments"];
158+
159+
// Create a map to store children by their parent_id for quick lookup
160+
const childrenMap = new Map<
161+
DiscussionDetails["comments"][number]["parent_id"],
162+
DiscussionDetails["comments"]
163+
>();
164+
165+
// Populate the map with empty arrays
166+
childrenMap.set(null, []);
167+
for (const comment of discussionComments) {
168+
if (!childrenMap.has(comment.id)) {
169+
childrenMap.set(comment.id, []);
170+
}
171+
}
172+
173+
// Add items to their parent's children array
174+
for (const comment of discussionComments) {
175+
const parentArray = childrenMap.get(comment.parent_id) || [];
176+
parentArray.push(comment);
177+
}
178+
179+
// Sort children arrays by creation date
180+
for (const children of childrenMap.values()) {
181+
children.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
182+
}
183+
184+
// Recursively build the result array in the correct order
185+
const result: DiscussionDetails["comments"] = [];
186+
187+
function traverseTree(parentId: DiscussionDetails["comments"][number]["parent_id"]) {
188+
const children = childrenMap.get(parentId) || [];
189+
190+
for (const child of children) {
191+
result.push(child);
192+
traverseTree(child.id);
193+
}
194+
}
195+
196+
// Start traversal from the root
197+
traverseTree(null);
198+
199+
return result;
200+
}
136201
</script>
137202

138203
<div class="container py-8">
@@ -297,7 +362,7 @@
297362
label="Comments"
298363
secondaryLabel="{info.comments} comment{info.comments > 1 ? 's' : ''}"
299364
>
300-
{#each comments as comment, i (comment.id)}
365+
{#each sortComments(comments) as comment, i (comment.id)}
301366
{@const isAnswer =
302367
"parent_id" in comment && comment.parent_id ? comment.parent_id !== info.id : false}
303368
{#if !isAnswer && i > 0}

0 commit comments

Comments
 (0)