Browse Source

feat: add threaded replies

for proposals and issues
master
DanConwayDev 2 years ago
parent
commit
fe1c6d34cc
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. 6
      src/lib/components/events/type.ts
  2. 35
      src/lib/wrappers/Thread.svelte
  3. 103
      src/lib/wrappers/ThreadTree.svelte

6
src/lib/components/events/type.ts

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
import type { NDKEvent } from '@nostr-dev-kit/ndk'
import type { User } from '../users/type'
export interface Event {
author: User
content: unknown
}
export interface ThreadTreeNode {
event: NDKEvent
child_nodes: ThreadTreeNode[]
}

35
src/lib/wrappers/Thread.svelte

@ -1,31 +1,48 @@ @@ -1,31 +1,48 @@
<script lang="ts">
import { ndk } from '$lib/stores/ndk'
import type { NDKEvent } from '@nostr-dev-kit/ndk'
import EventCard from './EventCard.svelte'
import ThreadWrapper from '$lib/components/events/ThreadWrapper.svelte'
import { writable } from 'svelte/store'
import ComposeReply from './ComposeReply.svelte'
import type { ThreadTreeNode } from '$lib/components/events/type'
import ThreadTree from './ThreadTree.svelte'
export let event: NDKEvent
export let type: 'proposal' | 'issue' = 'proposal'
export let replies: NDKEvent[] | undefined = undefined
let replies_store = replies
? writable(replies)
: ndk.storeSubscribe({
'#e': [event.id],
})
const getParentId = (reply: NDKEvent): string | undefined => {
let t = reply.tags.find((tag) => tag.length === 4 && tag[3] === 'reply')
return t ? t[1] : undefined
}
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>
<EventCard {type} {event} />
<ThreadWrapper>
{#each $replies_store as event}
<EventCard {type} {event} />
{#each $thread_tree_store as tree}
<ThreadTree {type} {tree} />
{/each}
<ComposeReply {type} reply_to_event_id={event.id} />
</ThreadWrapper>

103
src/lib/wrappers/ThreadTree.svelte

@ -0,0 +1,103 @@ @@ -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…
Cancel
Save