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.
222 lines
6.2 KiB
222 lines
6.2 KiB
import { NDKRelaySet, type NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk' |
|
import { writable, type Unsubscriber, type Writable } from 'svelte/store' |
|
import { base_relays, ndk } from './ndk' |
|
import type { User } from '$lib/components/users/type' |
|
import { ensureUser } from './users' |
|
import { |
|
type ProposalFull, |
|
full_defaults, |
|
} from '$lib/components/proposals/type' |
|
import { proposal_status_kinds, proposal_status_open } from '$lib/kinds' |
|
import { awaitSelectedRepoCollection } from './repo' |
|
import { extractPatchMessage } from '$lib/components/events/content/utils' |
|
import { goto } from '$app/navigation' |
|
import { selectRepoFromCollection } from '$lib/components/repo/utils' |
|
|
|
export const selected_proposal_full: Writable<ProposalFull> = writable({ |
|
...full_defaults, |
|
}) |
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
|
let selected_proposal_repo_id: string = '' |
|
let selected_proposal_id: string = '' |
|
let proposal_summary_author_unsubsriber: Unsubscriber | undefined |
|
|
|
export const selected_proposal_replies: Writable<NDKEvent[]> = writable([]) |
|
|
|
let selected_proposal_status_date = 0 |
|
|
|
let sub: NDKSubscription |
|
|
|
let sub_replies: NDKSubscription |
|
|
|
export const ensureProposalFull = ( |
|
repo_identifier: string, |
|
proposal_id: string |
|
) => { |
|
if (selected_proposal_id == proposal_id) return |
|
if (proposal_id == '') { |
|
selected_proposal_full.set({ ...full_defaults }) |
|
selected_proposal_replies.set([]) |
|
return |
|
} |
|
|
|
if (sub) sub.stop() |
|
if (sub_replies) sub_replies.stop() |
|
|
|
selected_proposal_repo_id = repo_identifier |
|
selected_proposal_id = proposal_id |
|
selected_proposal_status_date = 0 |
|
selected_proposal_replies.set([]) |
|
|
|
selected_proposal_full.set({ |
|
...full_defaults, |
|
summary: { |
|
...full_defaults.summary, |
|
id: proposal_id, |
|
repo_identifier: repo_identifier, |
|
loading: true, |
|
}, |
|
loading: true, |
|
}) |
|
if (proposal_summary_author_unsubsriber) proposal_summary_author_unsubsriber() |
|
proposal_summary_author_unsubsriber = undefined |
|
|
|
new Promise(async (r) => { |
|
const repo_collection = await awaitSelectedRepoCollection(repo_identifier) |
|
const repo = selectRepoFromCollection(repo_collection) |
|
const relays_to_use = |
|
repo && repo.relays.length > 3 |
|
? repo.relays |
|
: [...base_relays].concat(repo ? repo.relays : []) |
|
|
|
sub = ndk.subscribe( |
|
{ |
|
ids: [proposal_id], |
|
limit: 50, |
|
}, |
|
{ |
|
closeOnEose: true, |
|
}, |
|
NDKRelaySet.fromRelayUrls(relays_to_use, ndk) |
|
) |
|
|
|
sub.on('event', (event: NDKEvent) => { |
|
try { |
|
if (event.id == proposal_id) { |
|
const event_repo_id = event.tagValue('a')?.split(':')[2] |
|
if (event_repo_id && event_repo_id !== repo_identifier) { |
|
goto( |
|
`/repo/${encodeURIComponent(event_repo_id)}/proposal/${proposal_id}` |
|
) |
|
} |
|
selected_proposal_full.update((full) => { |
|
return { |
|
...full, |
|
proposal_event: event, |
|
summary: { |
|
...full.summary, |
|
title: ( |
|
event.tagValue('name') || |
|
event.tagValue('description') || |
|
extractPatchMessage(event.content) || |
|
'' |
|
).split('\n')[0], |
|
descritpion: event.tagValue('description') || '', |
|
created_at: event.created_at, |
|
comments: 0, |
|
author: { |
|
hexpubkey: event.pubkey, |
|
loading: true, |
|
npub: '', |
|
}, |
|
loading: false, |
|
}, |
|
} |
|
}) |
|
|
|
proposal_summary_author_unsubsriber = ensureUser( |
|
event.pubkey |
|
).subscribe((u: User) => { |
|
selected_proposal_full.update((full) => { |
|
return { |
|
...full, |
|
summary: { |
|
...full.summary, |
|
author: event.pubkey == u.hexpubkey ? u : full.summary.author, |
|
}, |
|
} |
|
}) |
|
}) |
|
} |
|
} catch {} |
|
}) |
|
|
|
sub.on('eose', () => { |
|
selected_proposal_full.update((full) => { |
|
const updated = { |
|
...full, |
|
summary: { |
|
...full.summary, |
|
loading: false, |
|
}, |
|
} |
|
if (full.loading === false) { |
|
r({ ...updated }) |
|
} |
|
return updated |
|
}) |
|
}) |
|
|
|
sub_replies = ndk.subscribe( |
|
{ |
|
'#e': [proposal_id], |
|
}, |
|
{ |
|
closeOnEose: false, |
|
}, |
|
NDKRelaySet.fromRelayUrls(relays_to_use, ndk) |
|
) |
|
|
|
const process_replies = (event: NDKEvent) => { |
|
if ( |
|
event.kind && |
|
proposal_status_kinds.includes(event.kind) && |
|
event.created_at && |
|
selected_proposal_status_date < event.created_at |
|
) { |
|
selected_proposal_status_date = event.created_at |
|
selected_proposal_full.update((full) => { |
|
return { |
|
...full, |
|
summary: { |
|
...full.summary, |
|
status: event.kind, |
|
// this wont be 0 as we are ensuring it is not undefined above |
|
status_date: event.created_at || 0, |
|
}, |
|
} |
|
}) |
|
} |
|
selected_proposal_replies.update((replies) => { |
|
return [...replies, event] |
|
}) |
|
if (event.tags.some((t) => t.length > 1 && t[1] === 'revision-root')) { |
|
const sub_revision_replies = ndk.subscribe( |
|
{ |
|
ids: [proposal_id], |
|
limit: 50, |
|
}, |
|
{ |
|
closeOnEose: true, |
|
}, |
|
NDKRelaySet.fromRelayUrls(relays_to_use, ndk) |
|
) |
|
sub_revision_replies.on('event', (event: NDKEvent) => { |
|
process_replies(event) |
|
}) |
|
} |
|
} |
|
|
|
sub_replies.on('event', (event: NDKEvent) => { |
|
process_replies(event) |
|
}) |
|
|
|
sub_replies.on('eose', () => { |
|
selected_proposal_full.update((full) => { |
|
const updated = { |
|
...full, |
|
summary: { |
|
...full.summary, |
|
status: full.summary.status || proposal_status_open, |
|
}, |
|
loading: false, |
|
} |
|
if (full.summary.loading === false) { |
|
r({ ...updated }) |
|
} |
|
return updated |
|
}) |
|
}) |
|
}) |
|
}
|
|
|