3 changed files with 135 additions and 9 deletions
@ -1,6 +1,12 @@ |
|||||||
|
import type { NDKEvent } from '@nostr-dev-kit/ndk' |
||||||
import type { User } from '../users/type' |
import type { User } from '../users/type' |
||||||
|
|
||||||
export interface Event { |
export interface Event { |
||||||
author: User |
author: User |
||||||
content: unknown |
content: unknown |
||||||
} |
} |
||||||
|
|
||||||
|
export interface ThreadTreeNode { |
||||||
|
event: NDKEvent |
||||||
|
child_nodes: ThreadTreeNode[] |
||||||
|
} |
||||||
|
|||||||
@ -1,31 +1,48 @@ |
|||||||
<script lang="ts"> |
<script lang="ts"> |
||||||
import { ndk } from '$lib/stores/ndk' |
|
||||||
import type { NDKEvent } from '@nostr-dev-kit/ndk' |
import type { NDKEvent } from '@nostr-dev-kit/ndk' |
||||||
import EventCard from './EventCard.svelte' |
import EventCard from './EventCard.svelte' |
||||||
import ThreadWrapper from '$lib/components/events/ThreadWrapper.svelte' |
import ThreadWrapper from '$lib/components/events/ThreadWrapper.svelte' |
||||||
import { writable } from 'svelte/store' |
import { writable } from 'svelte/store' |
||||||
import ComposeReply from './ComposeReply.svelte' |
import ComposeReply from './ComposeReply.svelte' |
||||||
|
import type { ThreadTreeNode } from '$lib/components/events/type' |
||||||
|
import ThreadTree from './ThreadTree.svelte' |
||||||
|
|
||||||
export let event: NDKEvent |
export let event: NDKEvent |
||||||
export let type: 'proposal' | 'issue' = 'proposal' |
export let type: 'proposal' | 'issue' = 'proposal' |
||||||
|
|
||||||
export let replies: NDKEvent[] | undefined = undefined |
export let replies: NDKEvent[] | undefined = undefined |
||||||
|
|
||||||
let replies_store = replies |
const getParentId = (reply: NDKEvent): string | undefined => { |
||||||
? writable(replies) |
let t = reply.tags.find((tag) => tag.length === 4 && tag[3] === 'reply') |
||||||
: ndk.storeSubscribe({ |
return t ? t[1] : undefined |
||||||
'#e': [event.id], |
} |
||||||
}) |
|
||||||
|
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) => { |
||||||
|
let reply_parent_id = getParentId(reply) |
||||||
|
if (reply_parent_id && hashTable[reply_parent_id]) |
||||||
|
hashTable[reply_parent_id].child_nodes.push(hashTable[reply.id]) |
||||||
|
else thread_tree.push(hashTable[reply.id]) |
||||||
|
}) |
||||||
|
return thread_tree |
||||||
|
} |
||||||
|
|
||||||
|
let thread_tree_store = writable(createThreadTree(replies ? replies : [])) |
||||||
$: { |
$: { |
||||||
if (replies) replies_store.set(replies) |
if (replies) thread_tree_store.set(createThreadTree(replies)) |
||||||
} |
} |
||||||
</script> |
</script> |
||||||
|
|
||||||
<EventCard {type} {event} /> |
<EventCard {type} {event} /> |
||||||
|
|
||||||
<ThreadWrapper> |
<ThreadWrapper> |
||||||
{#each $replies_store as event} |
{#each $thread_tree_store as tree} |
||||||
<EventCard {type} {event} /> |
<ThreadTree {type} {tree} /> |
||||||
{/each} |
{/each} |
||||||
<ComposeReply {type} reply_to_event_id={event.id} /> |
<ComposeReply {type} reply_to_event_id={event.id} /> |
||||||
</ThreadWrapper> |
</ThreadWrapper> |
||||||
|
|||||||
@ -0,0 +1,103 @@ |
|||||||
|
<script lang="ts"> |
||||||
|
import EventCard from './EventCard.svelte' |
||||||
|
import ThreadWrapper from '$lib/components/events/ThreadWrapper.svelte' |
||||||
|
import type { ThreadTreeNode } from '$lib/components/events/type' |
||||||
|
|
||||||
|
export let tree: ThreadTreeNode |
||||||
|
export let type: 'proposal' | 'issue' = 'proposal' |
||||||
|
</script> |
||||||
|
|
||||||
|
<EventCard {type} event={tree.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each tree.child_nodes as layer1} |
||||||
|
<EventCard {type} event={layer1.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer1.child_nodes as layer2} |
||||||
|
<EventCard {type} event={layer2.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer2.child_nodes as layer3} |
||||||
|
<EventCard {type} event={layer3.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer3.child_nodes as layer4} |
||||||
|
<EventCard {type} event={layer4.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer4.child_nodes as layer5} |
||||||
|
<EventCard {type} event={layer5.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer5.child_nodes as layer6} |
||||||
|
<EventCard {type} event={layer6.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer6.child_nodes as layer7} |
||||||
|
<EventCard {type} event={layer7.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer7.child_nodes as layer8} |
||||||
|
<EventCard {type} event={layer8.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer8.child_nodes as layer9} |
||||||
|
<EventCard {type} event={layer9.event} /> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer9.child_nodes as layer10} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer10.event} |
||||||
|
/> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer10.child_nodes as layer11} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer11.event} |
||||||
|
/> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer11.child_nodes as layer12} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer12.event} |
||||||
|
/> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer12.child_nodes as layer13} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer13.event} |
||||||
|
/> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer13.child_nodes as layer14} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer14.event} |
||||||
|
/> |
||||||
|
<ThreadWrapper> |
||||||
|
{#each layer14.child_nodes as layer15} |
||||||
|
<EventCard |
||||||
|
{type} |
||||||
|
event={layer15.event} |
||||||
|
/> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
|
{/each} |
||||||
|
</ThreadWrapper> |
||||||
Loading…
Reference in new issue