Barazo default frontend barazo.forum
at main 77 lines 2.0 kB view raw
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}