Barazo default frontend
barazo.forum
1import type { Reply } from '@/lib/api/types'
2
3export interface ReplyTreeNode {
4 reply: Reply
5 children: ReplyTreeNode[]
6}
7
8/**
9 * Build a tree of replies from a flat array.
10 *
11 * Direct replies to the topic (parentUri matches topicUri or rootUri)
12 * become root nodes. Others attach to their parent. If a reply's parent
13 * is not in the array, it becomes a root (orphan promotion).
14 *
15 * Input order is preserved: children appear in the same relative order
16 * they had in the flat array.
17 */
18export function buildReplyTree(replies: Reply[], topicUri: string): ReplyTreeNode[] {
19 if (replies.length === 0) return []
20
21 const nodeMap = new Map<string, ReplyTreeNode>()
22 const roots: ReplyTreeNode[] = []
23
24 // First pass: create all nodes
25 for (const reply of replies) {
26 nodeMap.set(reply.uri, { reply, children: [] })
27 }
28
29 // Second pass: link children to parents
30 for (const reply of replies) {
31 const node = nodeMap.get(reply.uri)!
32 const isDirectReply = reply.parentUri === topicUri || reply.parentUri === reply.rootUri
33
34 if (isDirectReply) {
35 roots.push(node)
36 } else {
37 const parent = nodeMap.get(reply.parentUri)
38 if (parent) {
39 parent.children.push(node)
40 } else {
41 // Orphan: parent not in array, promote to root
42 roots.push(node)
43 }
44 }
45 }
46
47 return roots
48}
49
50/**
51 * Count all descendants (children, grandchildren, etc.) of a node.
52 */
53export function countDescendants(node: ReplyTreeNode): number {
54 let count = node.children.length
55 for (const child of node.children) {
56 count += countDescendants(child)
57 }
58 return count
59}
60
61/**
62 * Flatten a reply tree into depth-first order.
63 * Useful for rendering a flat list with indentation or for counting.
64 */
65export function flattenReplyTree(roots: ReplyTreeNode[]): Reply[] {
66 const result: Reply[] = []
67
68 function walk(nodes: ReplyTreeNode[]) {
69 for (const node of nodes) {
70 result.push(node.reply)
71 walk(node.children)
72 }
73 }
74
75 walk(roots)
76 return result
77}