diff --git a/src/lib/components/prs/PRDetails.svelte b/src/lib/components/prs/PRDetails.svelte new file mode 100644 index 0000000..4920075 --- /dev/null +++ b/src/lib/components/prs/PRDetails.svelte @@ -0,0 +1,47 @@ + + +
+
+ {#if loading} +
+
+
+ {:else} +

Author

+ + {/if} +
+ +
+ {#if loading} +
+
+
+ {:else} +

Status

+ + {/if} +
+ +
+ {#if loading} +
+
+ {:else} +

Labels

+ {#each labels as label} +
{label}
+ {/each} + {/if} +
+
diff --git a/src/lib/components/prs/StatusSelector.svelte b/src/lib/components/prs/StatusSelector.svelte new file mode 100644 index 0000000..2b0edc6 --- /dev/null +++ b/src/lib/components/prs/StatusSelector.svelte @@ -0,0 +1,157 @@ + + +{#if loading} +
+{:else} + +{/if} diff --git a/src/lib/components/prs/type.ts b/src/lib/components/prs/type.ts index 7ccb39f..1ae76ef 100644 --- a/src/lib/components/prs/type.ts +++ b/src/lib/components/prs/type.ts @@ -37,9 +37,22 @@ export const summaries_defaults: PRSummaries = { loading: true, }; +export type PRStatus = "Draft" | "Open" | "Merged" | "Closed"; + +export function isPRStatus(potential_status: string | undefined): potential_status is PRStatus { + return !!potential_status + && ( + potential_status == "Draft" + || potential_status == "Open" + || potential_status == "Merged" + || potential_status == "Closed" + ) +} export interface PRFull { summary: PRSummary; pr_event: NDKEvent | undefined; + status: PRStatus; + labels: string[]; events: Event[]; loading: boolean; } @@ -47,6 +60,8 @@ export interface PRFull { export const full_defaults: PRFull = { summary: { ...summary_defaults }, pr_event: undefined, + status: "Open", + labels: [], events: [], loading: true, }; diff --git a/src/lib/kinds.ts b/src/lib/kinds.ts new file mode 100644 index 0000000..ea15593 --- /dev/null +++ b/src/lib/kinds.ts @@ -0,0 +1,7 @@ +export let pr_status_kind = 19871987; + +export let repo_kind = 30317; + +export let pr_kind = 318; + +export let patch_kind = 317; diff --git a/src/lib/stores/PR.ts b/src/lib/stores/PR.ts index 69037ec..9ede801 100644 --- a/src/lib/stores/PR.ts +++ b/src/lib/stores/PR.ts @@ -3,9 +3,9 @@ import { writable, type Unsubscriber, type Writable } from "svelte/store" import { ndk } from "./ndk"; import type { User } from "$lib/components/users/type"; import { ensureUser } from "./users"; -import { type PRFull, full_defaults } from "$lib/components/prs/type"; +import { type PRFull, full_defaults, isPRStatus, type PRStatus } from "$lib/components/prs/type"; +import { pr_kind, pr_status_kind } from "$lib/kinds"; -let pr_kind: number = 318; export let selected_pr_full: Writable = writable({ ...full_defaults }); @@ -13,12 +13,21 @@ let selected_repo_id: string = ""; let selected_pr_id: string = ""; let pr_summary_author_unsubsriber: Unsubscriber | undefined; +export let selected_pr_replies: Writable = writable([]); + +let selected_pr_status_date = 0; + export let ensurePRFull = (repo_id: string, pr_id: string) => { if (selected_pr_id == pr_id) return; - if (pr_id == "") return selected_pr_full.set({ ...full_defaults }); + if (pr_id == "") { + selected_pr_full.set({ ...full_defaults }); + return; + } selected_repo_id = repo_id; selected_pr_id = pr_id; + selected_pr_status_date = 0; + selected_pr_replies.set([]); selected_pr_full.update(full => { return { @@ -90,6 +99,44 @@ export let ensurePRFull = (repo_id: string, pr_id: string) => { ...full.summary, loading: false, }, + }; + }); + }); + + let sub_replies = ndk.subscribe({ + "#e": [pr_id], + }); + + sub_replies.on("event", (event: NDKEvent) => { + if (event.kind == pr_status_kind + && event.created_at && selected_pr_status_date < event.created_at + && event.getMatchingTags("t").length === 1 + && event.getMatchingTags("t")[0].length > 1 + ) { + let potential_status = event.getMatchingTags("t")[0][1]; + + if (isPRStatus(potential_status)) { + selected_pr_status_date = event.created_at; + selected_pr_full.update(full => { + return { + ...full, + status: potential_status as PRStatus, + }; + }); + } + } + selected_pr_replies.update(replies => { + return [ + ...replies, + event, + ]; + }); + }); + + sub.on("eose", () => { + selected_pr_full.update(full => { + return { + ...full, loading: false, }; }); diff --git a/src/lib/stores/repo.ts b/src/lib/stores/repo.ts index 18469bd..6466fab 100644 --- a/src/lib/stores/repo.ts +++ b/src/lib/stores/repo.ts @@ -5,9 +5,7 @@ import type { Repo } from "$lib/components/repo/type"; import { defaults } from "$lib/components/repo/type"; import type { User } from "$lib/components/users/type"; import { ensureUser, users } from "./users"; - - -let repo_kind: number = 30317; +import { repo_kind } from "$lib/kinds"; export let selected_repo: Writable = writable({ ...defaults }); let selected_repo_id: string = ""; diff --git a/src/lib/wrappers/EventCard.svelte b/src/lib/wrappers/EventCard.svelte index e3e167e..2e54b52 100644 --- a/src/lib/wrappers/EventCard.svelte +++ b/src/lib/wrappers/EventCard.svelte @@ -3,6 +3,7 @@ import Kind317 from "$lib/components/events/content/Kind317.svelte"; import type { User } from "$lib/components/users/type"; import { defaults as user_defaults } from "$lib/components/users/type"; + import { patch_kind } from "$lib/kinds"; import { ensureUser } from "$lib/stores/users"; import type { NDKEvent } from "@nostr-dev-kit/ndk"; import { onDestroy } from "svelte"; @@ -20,7 +21,7 @@ - {#if event.kind == 317} + {#if event.kind == patch_kind} {:else} {event.content} diff --git a/src/lib/wrappers/ReposRecent.svelte b/src/lib/wrappers/ReposRecent.svelte index 7fbf599..5d7fa28 100644 --- a/src/lib/wrappers/ReposRecent.svelte +++ b/src/lib/wrappers/ReposRecent.svelte @@ -1,21 +1,21 @@ - {#each $replies as event} + {#each $replies_store as event} {/each} diff --git a/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte b/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte index f3024ab..8e2b224 100644 --- a/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte +++ b/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte @@ -1,9 +1,14 @@