Browse Source

fix: update pr status accross app

- move status from PRFull into PRSummary
- fetch statuses when fetching pr summaries
- ensure status gets displayed accurately across the app
master
DanConwayDev 2 years ago
parent
commit
fd73f0952b
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. BIN
      __snapshots__/prs-list-item--status-closed.png
  2. BIN
      __snapshots__/prs-list-item--status-draft.png
  3. BIN
      __snapshots__/prs-list-item--status-loading.png
  4. BIN
      __snapshots__/prs-list-item--status-merged.png
  5. 143
      __snapshots__/prs-list-item.test.js.snap
  6. 4
      __snapshots__/prs-status.test.js.snap
  7. 4
      src/lib/components/prs/PRDetails.svelte
  8. 16
      src/lib/components/prs/PRHeader.svelte
  9. 8
      src/lib/components/prs/PRsListItem.stories.svelte
  10. 54
      src/lib/components/prs/PRsListItem.svelte
  11. 22
      src/lib/components/prs/Status.svelte
  12. 13
      src/lib/components/prs/StatusSelector.svelte
  13. 6
      src/lib/components/prs/icons.ts
  14. 6
      src/lib/components/prs/type.ts
  15. 36
      src/lib/components/prs/vectors.ts
  16. 13
      src/lib/stores/PR.ts
  17. 71
      src/lib/stores/PRs.ts
  18. 1
      src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte

BIN
__snapshots__/prs-list-item--status-closed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
__snapshots__/prs-list-item--status-draft.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
__snapshots__/prs-list-item--status-loading.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
__snapshots__/prs-list-item--status-merged.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

143
__snapshots__/prs-list-item.test.js.snap

@ -139,6 +139,149 @@ exports[`PRs/List/Item Short Details smoke-test 1`] = ` @@ -139,6 +139,149 @@ exports[`PRs/List/Item Short Details smoke-test 1`] = `
</li>
`;
exports[`PRs/List/Item Status Closed smoke-test 1`] = `
<li class="flex p-2 pt-4 hover:bg-neutral-700 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
>
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 5.5a.75.75 0 0 1 .75.75v3.378a2.251 2.251 0 1 1-1.5 0V7.25a.75.75 0 0 1 .75-.75m-2.03-5.273a.75.75 0 0 1 1.06 0l.97.97l.97-.97a.748.748 0 0 1 1.265.332a.75.75 0 0 1-.205.729l-.97.97l.97.97a.751.751 0 0 1-.018 1.042a.751.751 0 0 1-1.042.018l-.97-.97l-.97.97a.749.749 0 0 1-1.275-.326a.749.749 0 0 1 .215-.734l.97-.97l-.97-.97a.75.75 0 0 1 0-1.06ZM2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5">
</path>
</svg>
<a href="/repo//pr/"
class="ml-3 overflow-hidden grow text-xs text-neutral-content"
>
<div class="text-sm text-base-content">
short title
</div>
<ul class="pt-2">
<li class="align-middle inline mr-3">
<svg xmlns="http://www.w3.org/2000/svg"
class="h-3 w-3 pt-0 flex-none fill-base-content inline-block"
viewbox="0 0 16 16"
>
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z">
</path>
</svg>
2
</li>
<li class="inline mr-3">
opened 7 days ago
</li>
<li class="inline">
DanConwayDev
</li>
</ul>
</a>
</li>
`;
exports[`PRs/List/Item Status Draft smoke-test 1`] = `
<li class="flex p-2 pt-4 hover:bg-neutral-700 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
>
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 14a2.25 2.25 0 1 1 0-4.5a2.25 2.25 0 0 1 0 4.5M2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5M14 7.5a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0m0-4.25a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0">
</path>
</svg>
<a href="/repo//pr/"
class="ml-3 overflow-hidden grow text-xs text-neutral-content"
>
<div class="text-sm text-base-content">
short title
</div>
<ul class="pt-2">
<li class="align-middle inline mr-3">
<svg xmlns="http://www.w3.org/2000/svg"
class="h-3 w-3 pt-0 flex-none fill-base-content inline-block"
viewbox="0 0 16 16"
>
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z">
</path>
</svg>
2
</li>
<li class="inline mr-3">
opened 7 days ago
</li>
<li class="inline">
DanConwayDev
</li>
</ul>
</a>
</li>
`;
exports[`PRs/List/Item Status Loading smoke-test 1`] = `
<li class="flex p-2 pt-4 hover:bg-neutral-700 cursor-pointer">
<div class="h-5 w-5 pt-1 flex-none skeleton">
</div>
<a href="/repo//pr/"
class="ml-3 overflow-hidden grow text-xs text-neutral-content"
>
<div class="text-sm text-base-content">
short title
</div>
<ul class="pt-2">
<li class="align-middle inline mr-3">
<svg xmlns="http://www.w3.org/2000/svg"
class="h-3 w-3 pt-0 flex-none fill-base-content inline-block"
viewbox="0 0 16 16"
>
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z">
</path>
</svg>
2
</li>
<li class="inline mr-3">
opened 7 days ago
</li>
<li class="inline">
DanConwayDev
</li>
</ul>
</a>
</li>
`;
exports[`PRs/List/Item Status Merged smoke-test 1`] = `
<li class="flex p-2 pt-4 hover:bg-neutral-700 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-primary"
>
<path d="M5.45 5.154A4.25 4.25 0 0 0 9.25 7.5h1.378a2.251 2.251 0 1 1 0 1.5H9.25A5.734 5.734 0 0 1 5 7.123v3.505a2.25 2.25 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.95-.218M4.25 13.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5m8.5-4.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5M5 3.25a.75.75 0 1 0 0 .005z">
</path>
</svg>
<a href="/repo//pr/"
class="ml-3 overflow-hidden grow text-xs text-neutral-content"
>
<div class="text-sm text-base-content">
short title
</div>
<ul class="pt-2">
<li class="align-middle inline mr-3">
<svg xmlns="http://www.w3.org/2000/svg"
class="h-3 w-3 pt-0 flex-none fill-base-content inline-block"
viewbox="0 0 16 16"
>
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z">
</path>
</svg>
2
</li>
<li class="inline mr-3">
opened 7 days ago
</li>
<li class="inline">
DanConwayDev
</li>
</ul>
</a>
</li>
`;
exports[`PRs/List/Item loading smoke-test 1`] = `
<li class="flex p-2 pt-4 ">
<div class="h-5 w-5 pt-1 flex-none skeleton">

4
__snapshots__/prs-status.test.js.snap

@ -33,7 +33,7 @@ exports[`PRs/Status Draft smoke-test 1`] = ` @@ -33,7 +33,7 @@ exports[`PRs/Status Draft smoke-test 1`] = `
`;
exports[`PRs/Status Loading smoke-test 1`] = `
<div class="skeleton w-28 h-8 rounded-md">
<div class="skeleton w-24 h-8 rounded-md inline-block align-middle">
</div>
`;
@ -68,7 +68,7 @@ exports[`PRs/Status Open Edit Mode smoke-test 1`] = ` @@ -68,7 +68,7 @@ exports[`PRs/Status Open Edit Mode smoke-test 1`] = `
Open
<svg xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 24 24"
class="h-5 w-5s flex-none fill-success-content"
class="h-5 w-5 flex-none fill-success-content"
>
<path fill="currentColor"
d="M11.646 15.146L5.854 9.354a.5.5 0 0 1 .353-.854h11.586a.5.5 0 0 1 .353.854l-5.793 5.792a.5.5 0 0 1-.707 0"

4
src/lib/components/prs/PRDetails.svelte

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
import UserHeader from "../users/UserHeader.svelte";
import StatusSelector from "./StatusSelector.svelte";
export let { summary, status, labels, loading } = { ...full_defaults };
export let { summary, labels, loading } = { ...full_defaults };
</script>
<div class="max-w-md">
@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
{:else}
<h4>Status</h4>
<StatusSelector
{status}
status={summary.status}
repo_id={summary.repo_id}
pr_id={summary.id}
/>

16
src/lib/components/prs/PRHeader.svelte

@ -10,8 +10,18 @@ @@ -10,8 +10,18 @@
import Status from "./Status.svelte";
dayjs.extend(relativeTime);
export let { title, id, repo_id, comments, author, created_at, loading } =
summary_defaults;
export let {
title,
descritpion,
id,
repo_id,
comments,
status,
status_date,
author,
created_at,
loading,
} = summary_defaults;
let short_title: string;
let created_at_ago: string;
let author_name = "";
@ -51,7 +61,7 @@ @@ -51,7 +61,7 @@
</div>
<div class="pt-1">
<div class="inline mr-3 align-middle">
<Status status="Open" />
<Status {status} />
</div>
<div class="inline mr-3 align-middle">
opened {created_at_ago}

8
src/lib/components/prs/PRsListItem.stories.svelte

@ -23,4 +23,12 @@ @@ -23,4 +23,12 @@
<Story name="Author Loading" args={vectors.AuthorLoading} />
<Story name="Status Loading" args={vectors.StatusLoading} />
<Story name="Status Draft" args={vectors.StatusDraft} />
<Story name="Status Closed" args={vectors.StatusClosed} />
<Story name="Status Merged" args={vectors.StatusMerged} />
<Story name="loading" args={{ loading: true }} />

54
src/lib/components/prs/PRsListItem.svelte

@ -6,10 +6,19 @@ @@ -6,10 +6,19 @@
import relativeTime from "dayjs/plugin/relativeTime";
import { summary_defaults } from "./type";
import { getName } from "../users/type";
import { pr_icon_path } from "./icons";
dayjs.extend(relativeTime);
export let { title, id, repo_id, comments, author, created_at, loading } =
summary_defaults;
export let {
title,
id,
repo_id,
comments,
status,
author,
created_at,
loading,
} = summary_defaults;
let short_title: string;
let created_at_ago: string;
let author_name = "";
@ -31,28 +40,37 @@ @@ -31,28 +40,37 @@
>
<!-- <figure class="p-4 pl-0 text-color-primary"> -->
<!-- http://icon-sets.iconify.design/octicon/git-pull-request-16/ -->
{#if loading}
{#if loading || !status}
<div class="h-5 w-5 pt-1 flex-none skeleton"></div>
{:else}
{:else if status === "Open"}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-success"
><path
d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25m5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354M3.75 2.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m0 9.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m8.25.75a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0"
/>
</svg>
><path d={pr_icon_path.open} /></svg
>
{:else if status === "Closed"}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
><path d={pr_icon_path.close} /></svg
>
{:else if status === "Draft"}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
><path d={pr_icon_path.draft} /></svg
>
{:else if status === "Merged"}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-primary"
><path d={pr_icon_path.merge} /></svg
>
{/if}
<!-- <svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
class="fill-base-content"
><path
d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 14a2.25 2.25 0 1 1 0-4.5a2.25 2.25 0 0 1 0 4.5M2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5M14 7.5a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0m0-4.25a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0"
/></svg
> -->
<a
href="/repo/{repo_id}/pr/{id}"
class="ml-3 overflow-hidden grow text-xs text-neutral-content"

22
src/lib/components/prs/Status.svelte

@ -1,10 +1,12 @@ @@ -1,10 +1,12 @@
<script lang="ts">
import { pr_icon_path } from "./icons";
export let status: string | undefined = undefined;
export let edit_mode = false;
</script>
{#if !status}
<div class="skeleton w-28 h-8 rounded-md"></div>
<div class="skeleton w-24 h-8 rounded-md inline-block align-middle"></div>
{:else}
<div
tabIndex={0}
@ -21,9 +23,7 @@ @@ -21,9 +23,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 18 18"
class="h-5 w-5 pt-1 flex-none fill-success-content"
><path
d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25m5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354M3.75 2.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m0 9.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m8.25.75a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0"
/>
><path d={pr_icon_path.open} />
</svg>
Open
{:else if status === "Merged"}
@ -32,9 +32,7 @@ @@ -32,9 +32,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-primary-content"
><path
d="M5.45 5.154A4.25 4.25 0 0 0 9.25 7.5h1.378a2.251 2.251 0 1 1 0 1.5H9.25A5.734 5.734 0 0 1 5 7.123v3.505a2.25 2.25 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.95-.218M4.25 13.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5m8.5-4.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5M5 3.25a.75.75 0 1 0 0 .005z"
/></svg
><path d={pr_icon_path.merge} /></svg
>
Merged
{:else if status === "Closed"}
@ -43,9 +41,7 @@ @@ -43,9 +41,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
><path
d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 5.5a.75.75 0 0 1 .75.75v3.378a2.251 2.251 0 1 1-1.5 0V7.25a.75.75 0 0 1 .75-.75m-2.03-5.273a.75.75 0 0 1 1.06 0l.97.97l.97-.97a.748.748 0 0 1 1.265.332a.75.75 0 0 1-.205.729l-.97.97l.97.97a.751.751 0 0 1-.018 1.042a.751.751 0 0 1-1.042.018l-.97-.97l-.97.97a.749.749 0 0 1-1.275-.326a.749.749 0 0 1 .215-.734l.97-.97l-.97-.97a.75.75 0 0 1 0-1.06ZM2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5"
/></svg
><path d={pr_icon_path.close} /></svg
>
Closed
{:else if status === "Draft"}
@ -54,9 +50,7 @@ @@ -54,9 +50,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
class="h-5 w-5 pt-1 flex-none fill-neutral-content"
><path
d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 14a2.25 2.25 0 1 1 0-4.5a2.25 2.25 0 0 1 0 4.5M2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5M14 7.5a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0m0-4.25a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0"
/></svg
><path d={pr_icon_path.draft} /></svg
>
Draft
{:else}
@ -66,7 +60,7 @@ @@ -66,7 +60,7 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="h-5 w-5s flex-none fill-success-content"
class="h-5 w-5 flex-none fill-success-content"
><path
fill="currentColor"
d="M11.646 15.146L5.854 9.354a.5.5 0 0 1 .353-.854h11.586a.5.5 0 0 1 .353.854l-5.793 5.792a.5.5 0 0 1-.707 0"

13
src/lib/components/prs/StatusSelector.svelte

@ -2,13 +2,13 @@ @@ -2,13 +2,13 @@
import { ndk } from "$lib/stores/ndk";
import { NDKEvent, NDKRelaySet, type NDKTag } from "@nostr-dev-kit/ndk";
import type { PRStatus } from "./type";
import { selected_pr_full } from "$lib/stores/PR";
import { selected_pr_full, selected_pr_replies } from "$lib/stores/PR";
import { pr_status_kind } from "$lib/kinds";
import { getUserRelays, logged_in_user } from "$lib/stores/users";
import { selected_repo } from "$lib/stores/repo";
import Status from "$lib/components/prs/Status.svelte";
export let status: PRStatus = "Draft";
export let status: PRStatus | undefined = undefined;
export let repo_id: string = "";
export let pr_id: string = "";
@ -54,15 +54,20 @@ @@ -54,15 +54,20 @@
if (pr_full.summary.id !== pr_id) return pr_full;
return {
...pr_full,
status: new_status,
summary: {
...pr_full.summary,
status: new_status,
status_date: event.created_at || 0,
},
};
});
selected_pr_replies.update((responses) => [...responses, event]);
loading = false;
} catch {}
}
</script>
{#if loading}
{#if loading || !status}
<Status />
{:else}
<div class="dropdown">

6
src/lib/components/prs/icons.ts

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
export let pr_icon_path = {
open: "M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25m5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354M3.75 2.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m0 9.5a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m8.25.75a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0",
close: "M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 5.5a.75.75 0 0 1 .75.75v3.378a2.251 2.251 0 1 1-1.5 0V7.25a.75.75 0 0 1 .75-.75m-2.03-5.273a.75.75 0 0 1 1.06 0l.97.97l.97-.97a.748.748 0 0 1 1.265.332a.75.75 0 0 1-.205.729l-.97.97l.97.97a.751.751 0 0 1-.018 1.042a.751.751 0 0 1-1.042.018l-.97-.97l-.97.97a.749.749 0 0 1-1.275-.326a.749.749 0 0 1 .215-.734l.97-.97l-.97-.97a.75.75 0 0 1 0-1.06ZM2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5",
draft: "M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1m9.5 14a2.25 2.25 0 1 1 0-4.5a2.25 2.25 0 0 1 0 4.5M2.5 3.25a.75.75 0 1 0 1.5 0a.75.75 0 0 0-1.5 0M3.25 12a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5m9.5 0a.75.75 0 1 0 0 1.5a.75.75 0 0 0 0-1.5M14 7.5a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0m0-4.25a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0",
merge: "M5.45 5.154A4.25 4.25 0 0 0 9.25 7.5h1.378a2.251 2.251 0 1 1 0 1.5H9.25A5.734 5.734 0 0 1 5 7.123v3.505a2.25 2.25 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.95-.218M4.25 13.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5m8.5-4.5a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5M5 3.25a.75.75 0 1 0 0 .005z",
};

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

@ -9,6 +9,8 @@ export interface PRSummary { @@ -9,6 +9,8 @@ export interface PRSummary {
repo_id: string;
id: string;
comments: number;
status: undefined | PRStatus,
status_date: number,
author: User;
created_at: number | undefined;
loading: boolean;
@ -20,6 +22,8 @@ export const summary_defaults: PRSummary = { @@ -20,6 +22,8 @@ export const summary_defaults: PRSummary = {
repo_id: "",
id: "",
comments: 0,
status: undefined,
status_date: 0,
author: { ...user_defaults },
created_at: 0,
loading: true,
@ -51,7 +55,6 @@ export function isPRStatus(potential_status: string | undefined): potential_stat @@ -51,7 +55,6 @@ export function isPRStatus(potential_status: string | undefined): potential_stat
export interface PRFull {
summary: PRSummary;
pr_event: NDKEvent | undefined;
status: PRStatus;
labels: string[];
events: Event[];
loading: boolean;
@ -60,7 +63,6 @@ export interface PRFull { @@ -60,7 +63,6 @@ export interface PRFull {
export const full_defaults: PRFull = {
summary: { ...summary_defaults },
pr_event: undefined,
status: "Open",
labels: [],
events: [],
loading: true,

36
src/lib/components/prs/vectors.ts

@ -5,19 +5,23 @@ import { UserVectors } from "../users/vectors"; @@ -5,19 +5,23 @@ import { UserVectors } from "../users/vectors";
dayjs.extend(relativeTime);
let Short = {
title: "short title",
author: { ...UserVectors.default },
created_at: dayjs().subtract(7, 'days').unix(),
comments: 2,
status: "Open",
loading: false,
} as PRSummary;
export let PRsListItemArgsVectors = {
Short: {
title: "short title",
author: { ...UserVectors.default },
created_at: dayjs().subtract(7, 'days').unix(),
comments: 2,
loading: false,
} as PRSummary,
Short,
Long: {
title: "rather long title that goes on and on and on and on and on and on and on and on and on and on and on and on and on and on and on",
author: { ...UserVectors.default },
created_at: dayjs().subtract(1, 'minute').unix(),
comments: 0,
status: "Open",
loading: false,
} as PRSummary,
LongNoSpaces: {
@ -25,6 +29,7 @@ export let PRsListItemArgsVectors = { @@ -25,6 +29,7 @@ export let PRsListItemArgsVectors = {
author: { ...UserVectors.default },
created_at: dayjs().subtract(3, 'month').subtract(3, 'days').unix(),
comments: 1,
status: "Open",
loading: false,
} as PRSummary,
AuthorLoading: {
@ -32,6 +37,23 @@ export let PRsListItemArgsVectors = { @@ -32,6 +37,23 @@ export let PRsListItemArgsVectors = {
author: { ...UserVectors.loading },
created_at: dayjs().subtract(3, 'month').subtract(3, 'days').unix(),
comments: 1,
status: "Open",
loading: false,
} as PRSummary,
StatusLoading: {
...Short,
status: undefined,
} as PRSummary,
StatusDraft: {
...Short,
status: "Draft",
} as PRSummary,
StatusClosed: {
...Short,
status: "Closed",
} as PRSummary,
StatusMerged: {
...Short,
status: "Merged",
} as PRSummary,
};

13
src/lib/stores/PR.ts

@ -145,7 +145,12 @@ export let ensurePRFull = (repo_id: string, pr_id: string) => { @@ -145,7 +145,12 @@ export let ensurePRFull = (repo_id: string, pr_id: string) => {
selected_pr_full.update(full => {
return {
...full,
status: potential_status as PRStatus,
summary: {
...full.summary,
status: potential_status as PRStatus,
// this wont be 0 as we are ensuring it is not undefined above
status_date: event.created_at || 0,
},
};
});
}
@ -158,10 +163,14 @@ export let ensurePRFull = (repo_id: string, pr_id: string) => { @@ -158,10 +163,14 @@ export let ensurePRFull = (repo_id: string, pr_id: string) => {
});
});
sub.on("eose", () => {
sub_replies.on("eose", () => {
selected_pr_full.update(full => {
let updated = {
...full,
summary: {
...full.summary,
status: full.summary.status || "Open",
},
loading: false,
};
if (full.summary.loading === false) {

71
src/lib/stores/PRs.ts

@ -1,11 +1,13 @@ @@ -1,11 +1,13 @@
import { NDKRelaySet, type NDKEvent, NDKSubscription } from "@nostr-dev-kit/ndk";
import { writable, type Unsubscriber, type Writable } from "svelte/store"
import { ndk } from "./ndk";
import { summary_defaults } from "$lib/components/prs/type";
import { isPRStatus, summary_defaults } from "$lib/components/prs/type";
import type { User } from "$lib/components/users/type";
import { ensureUser } from "./users";
import type { PRSummaries } from "$lib/components/prs/type";
import type { PRStatus, PRSummaries } from "$lib/components/prs/type";
import { ensureSelectedRepo } from "./repo";
import { pr_status_kind } from "$lib/kinds";
import type { Repo } from "$lib/components/repo/type";
export let pr_summaries: Writable<PRSummaries> = writable({
id: "",
@ -104,6 +106,7 @@ export let ensurePRSummaries = async (repo_id: string) => { @@ -104,6 +106,7 @@ export let ensurePRSummaries = async (repo_id: string) => {
});
sub.on("eose", () => {
pr_summaries.update(prs => {
getAndUpdatePRStatus(prs, repo);
return {
...prs,
loading: false,
@ -111,3 +114,67 @@ export let ensurePRSummaries = async (repo_id: string) => { @@ -111,3 +114,67 @@ export let ensurePRSummaries = async (repo_id: string) => {
});
});
}
let sub_statuses: NDKSubscription;
function getAndUpdatePRStatus(prs: PRSummaries, repo: Repo): void {
if (sub_statuses) sub_statuses.stop();
sub_statuses = ndk.subscribe(
{
kinds: [pr_status_kind],
"#e": prs.summaries.map(pr => pr.id),
'#r': [`r-${prs.id}`],
},
{
closeOnEose: false,
},
NDKRelaySet.fromRelayUrls(repo.relays, ndk),
);
sub_statuses.on("event", (event: NDKEvent) => {
let tagged_pr_event = event.tagValue('e');
if (event.kind == pr_status_kind
&& tagged_pr_event
&& 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)) {
pr_summaries.update(prs => {
return {
...prs,
summaries: prs.summaries.map(o => {
if (
o.id === tagged_pr_event
&& event.created_at
&& o.status_date < event.created_at
) {
return {
...o,
status: potential_status as PRStatus,
status_date: event.created_at,
}
}
return o;
}),
}
});
}
}
});
sub_statuses.on("eose", () => {
pr_summaries.update(prs => {
return {
...prs,
summaries: prs.summaries.map(o => ({
...o,
status: o.status || "Open",
})),
}
});
});
}

1
src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte

@ -75,7 +75,6 @@ @@ -75,7 +75,6 @@
<div class="w-1/3 ml-2 prose hidden md:flex">
<PrDetails
summary={$selected_pr_full.summary}
status={$selected_pr_full.status}
labels={$selected_pr_full.labels}
loading={$selected_pr_full.loading}
/>

Loading…
Cancel
Save