You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.3 KiB
70 lines
2.3 KiB
import type { ThreadTreeNode } from '$lib/components/events/type' |
|
import type { NDKEvent } from '@nostr-dev-kit/ndk' |
|
|
|
export const getParentId = (reply: NDKEvent): string | undefined => { |
|
const t = |
|
reply.tags.find((tag) => tag.length === 4 && tag[3] === 'reply') || |
|
reply.tags.find((tag) => tag.length === 4 && tag[3] === 'root') || |
|
// include events that don't use nip 10 markers |
|
reply.tags.find((tag) => tag.length < 4 && tag[0] === 'e') |
|
return t ? t[1] : undefined |
|
} |
|
|
|
export const createThreadTree = (replies: NDKEvent[]): ThreadTreeNode[] => { |
|
const hashTable: { [key: string]: ThreadTreeNode } = Object.create(null) |
|
replies.forEach( |
|
(reply) => (hashTable[reply.id] = { event: reply, child_nodes: [] }) |
|
) |
|
const thread_tree: ThreadTreeNode[] = [] |
|
replies.forEach((reply) => { |
|
const reply_parent_id = getParentId(reply) |
|
if (reply_parent_id && hashTable[reply_parent_id]) { |
|
hashTable[reply_parent_id].child_nodes.push(hashTable[reply.id]) |
|
hashTable[reply_parent_id].child_nodes.sort( |
|
(a, b) => (a.event.created_at || 0) - (b.event.created_at || 0) |
|
) |
|
} else thread_tree.push(hashTable[reply.id]) |
|
}) |
|
return thread_tree |
|
} |
|
|
|
export const splitIntoRevisionThreadTrees = ( |
|
tree: ThreadTreeNode |
|
): ThreadTreeNode[] => { |
|
const thread_revision_trees: ThreadTreeNode[] = [ |
|
{ |
|
...tree, |
|
child_nodes: [...tree?.child_nodes], |
|
}, |
|
] |
|
thread_revision_trees[0].child_nodes = [ |
|
...thread_revision_trees[0].child_nodes.filter((n) => { |
|
if (n.event.tags.some((t) => t.length > 1 && t[1] === 'revision-root')) { |
|
thread_revision_trees.push(n) |
|
return false |
|
} |
|
return true |
|
}), |
|
] |
|
return thread_revision_trees.sort( |
|
(a, b) => (a.event.created_at || 0) - (b.event.created_at || 0) |
|
) |
|
} |
|
|
|
export const getThreadTrees = ( |
|
type: 'proposal' | 'issue', |
|
event: NDKEvent | undefined, |
|
replies: NDKEvent[] | undefined |
|
): ThreadTreeNode[] => { |
|
if (event) { |
|
const all_trees = createThreadTree(replies ? [event, ...replies] : [event]) |
|
const event_tree = all_trees.find((t) => t.event.id === event.id) |
|
if (event_tree) { |
|
// TODO: add 'mentions' and secondary references with a 'metioned event wrapper' |
|
if (type === 'proposal') return splitIntoRevisionThreadTrees(event_tree) |
|
return [event_tree] |
|
} |
|
} |
|
|
|
return [] |
|
}
|
|
|