Browse Source

feat:(homepage): show repo maintainers

- update repo event maintainers format to reflect model used for
  multiple entries for a single tag used in nip34
- show all users claiming to be a maintainer of identifier on homepage
master
DanConwayDev 2 years ago
parent
commit
54c5024eb2
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. BIN
      __snapshots__/repo-summary-card--long-and-no-spaces.png
  2. BIN
      __snapshots__/repo-summary-card--long-details.png
  3. BIN
      __snapshots__/repo-summary-card--multiple-maintainers.png
  4. BIN
      __snapshots__/repo-summary-card--short-details.png
  5. 171
      __snapshots__/repo-summary-card.test.js.snap
  6. BIN
      __snapshots__/repo-summary-list--default.png
  7. BIN
      __snapshots__/repo-summary-list--multiple-maintainers.png
  8. BIN
      __snapshots__/repo-summary-list--no-title.png
  9. BIN
      __snapshots__/repo-summary-list--partially-loaded.png
  10. 370
      __snapshots__/repo-summary-list.test.js.snap
  11. 2
      src/lib/components/RepoSummaryCard.stories.svelte
  12. 22
      src/lib/components/RepoSummaryCard.svelte
  13. 15
      src/lib/components/ReposSummaryList.stories.svelte
  14. 4
      src/lib/components/ReposSummaryList.svelte
  15. 16
      src/lib/components/repo/vectors.ts
  16. 51
      src/lib/stores/repo.ts
  17. 102
      src/lib/wrappers/ReposRecent.svelte

BIN
__snapshots__/repo-summary-card--long-and-no-spaces.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
__snapshots__/repo-summary-card--long-details.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

BIN
__snapshots__/repo-summary-card--multiple-maintainers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
__snapshots__/repo-summary-card--short-details.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

171
__snapshots__/repo-summary-card.test.js.snap

@ -1,7 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Repo/Summary/Card Long Details smoke-test 1`] = ` exports[`Repo/Summary/Card Long Details smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Rather Long Display Name"
>
</div>
</div>
<div class="pl-0 inline-block">
Rather Long Display Name
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -14,7 +37,30 @@ exports[`Repo/Summary/Card Long Details smoke-test 1`] = `
`; `;
exports[`Repo/Summary/Card Long and No Spaces smoke-test 1`] = ` exports[`Repo/Summary/Card Long and No Spaces smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="DanConwayDev"
>
</div>
</div>
<div class="pl-0 inline-block">
DanConwayDev
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -26,8 +72,98 @@ exports[`Repo/Summary/Card Long and No Spaces smoke-test 1`] = `
</div> </div>
`; `;
exports[`Repo/Summary/Card Multiple Maintainers smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 5.975rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="DanConwayDev"
>
</div>
</div>
<div class="pl-0 inline-block">
DanConwayDev
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="sectore"
>
</div>
</div>
<div class="pl-0 inline-block">
sectore
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words"
href="/repo/"
>
Short Name
</a>
<p class="text-muted break-words text-sm">
short description
</p>
</div>
`;
exports[`Repo/Summary/Card No Details smoke-test 1`] = ` exports[`Repo/Summary/Card No Details smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5 skeleton">
</div>
</div>
<div class="pl-0 inline-block">
<div class="skeleton w-24 h-3">
</div>
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -39,7 +175,30 @@ exports[`Repo/Summary/Card No Details smoke-test 1`] = `
`; `;
exports[`Repo/Summary/Card Short Details smoke-test 1`] = ` exports[`Repo/Summary/Card Short Details smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -52,7 +211,9 @@ exports[`Repo/Summary/Card Short Details smoke-test 1`] = `
`; `;
exports[`Repo/Summary/Card loading smoke-test 1`] = ` exports[`Repo/Summary/Card loading smoke-test 1`] = `
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<div class="skeleton mb-2 h-5 w-40"> <div class="skeleton mb-2 h-5 w-40">
</div> </div>
<div class="w-100 skeleton h-4"> <div class="w-100 skeleton h-4">

BIN
__snapshots__/repo-summary-list--default.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 50 KiB

BIN
__snapshots__/repo-summary-list--multiple-maintainers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
__snapshots__/repo-summary-list--no-title.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
__snapshots__/repo-summary-list--partially-loaded.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 27 KiB

370
__snapshots__/repo-summary-list.test.js.snap

@ -8,7 +8,30 @@ exports[`Repo/Summary/List Default smoke-test 1`] = `
</h3> </h3>
</div> </div>
<div class> <div class>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -18,7 +41,30 @@ exports[`Repo/Summary/List Default smoke-test 1`] = `
short description short description
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Rather Long Display Name"
>
</div>
</div>
<div class="pl-0 inline-block">
Rather Long Display Name
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -28,7 +74,30 @@ exports[`Repo/Summary/List Default smoke-test 1`] = `
Lorem ipsum dolor sit amet, consectetur adipi... Lorem ipsum dolor sit amet, consectetur adipi...
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="DanConwayDev"
>
</div>
</div>
<div class="pl-0 inline-block">
DanConwayDev
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -38,6 +107,73 @@ exports[`Repo/Summary/List Default smoke-test 1`] = `
LoremipsumLoremipsumLoremipsumLoremipsumLorem... LoremipsumLoremipsumLoremipsumLoremipsumLorem...
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 5.975rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="DanConwayDev"
>
</div>
</div>
<div class="pl-0 inline-block">
DanConwayDev
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="sectore"
>
</div>
</div>
<div class="pl-0 inline-block">
sectore
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words"
href="/repo/"
>
Short Name
</a>
<p class="text-muted break-words text-sm">
short description
</p>
</div>
</div> </div>
</div> </div>
`; `;
@ -63,19 +199,25 @@ exports[`Repo/Summary/List Loading smoke-test 1`] = `
</h3> </h3>
</div> </div>
<div class> <div class>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<div class="skeleton mb-2 h-5 w-40"> <div class="skeleton mb-2 h-5 w-40">
</div> </div>
<div class="w-100 skeleton h-4"> <div class="w-100 skeleton h-4">
</div> </div>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<div class="skeleton mb-2 h-5 w-40"> <div class="skeleton mb-2 h-5 w-40">
</div> </div>
<div class="w-100 skeleton h-4"> <div class="w-100 skeleton h-4">
</div> </div>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<div class="skeleton mb-2 h-5 w-40"> <div class="skeleton mb-2 h-5 w-40">
</div> </div>
<div class="w-100 skeleton h-4"> <div class="w-100 skeleton h-4">
@ -85,10 +227,145 @@ exports[`Repo/Summary/List Loading smoke-test 1`] = `
</div> </div>
`; `;
exports[`Repo/Summary/List Multiple Maintainers smoke-test 1`] = `
<div class="min-width">
<div class="prose mb-3">
<h3>
Multiple Maintainers
</h3>
</div>
<div class>
<div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 5.975rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="DanConwayDev"
>
</div>
</div>
<div class="pl-0 inline-block">
DanConwayDev
</div>
</div>
</div>
</div>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="sectore"
>
</div>
</div>
<div class="pl-0 inline-block">
sectore
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words"
href="/repo/"
>
Short Name
</a>
<p class="text-muted break-words text-sm">
short description
</p>
</div>
<div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Rather Long Display Name"
>
</div>
</div>
<div class="pl-0 inline-block">
Rather Long Display Name
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words"
href="/repo/"
>
Long Name that goes on and on and on and on a...
</a>
<p class="text-muted break-words text-sm">
Lorem ipsum dolor sit amet, consectetur adipi...
</p>
</div>
</div>
</div>
`;
exports[`Repo/Summary/List No Title smoke-test 1`] = ` exports[`Repo/Summary/List No Title smoke-test 1`] = `
<div class="min-width"> <div class="min-width">
<div class> <div class>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -98,7 +375,30 @@ exports[`Repo/Summary/List No Title smoke-test 1`] = `
short description short description
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Rather Long Display Name"
>
</div>
</div>
<div class="pl-0 inline-block">
Rather Long Display Name
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -120,7 +420,30 @@ exports[`Repo/Summary/List Partially Loaded smoke-test 1`] = `
</h3> </h3>
</div> </div>
<div class> <div class>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Will"
>
</div>
</div>
<div class="pl-0 inline-block">
Will
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -130,7 +453,30 @@ exports[`Repo/Summary/List Partially Loaded smoke-test 1`] = `
short description short description
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<p class="text-muted float-right break-words text-sm">
<span>
</span>
<div class="text-right">
<div class="inline-block">
<div class="text-sm inline-block align-middle">
<div class="avatar inline-block align-middle">
<div class="rounded inline-block h-3.5 w-3.5">
<img class="my-0"
src="../test-profile-image.jpg"
alt="Rather Long Display Name"
>
</div>
</div>
<div class="pl-0 inline-block">
Rather Long Display Name
</div>
</div>
</div>
</div>
</p>
<a class="link-primary break-words" <a class="link-primary break-words"
href="/repo/" href="/repo/"
> >
@ -140,7 +486,9 @@ exports[`Repo/Summary/List Partially Loaded smoke-test 1`] = `
Lorem ipsum dolor sit amet, consectetur adipi... Lorem ipsum dolor sit amet, consectetur adipi...
</p> </p>
</div> </div>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div class="my-2 rounded-lg bg-base-200 p-4"
style="min-height: 3.325rem;"
>
<div class="skeleton mb-2 h-5 w-40"> <div class="skeleton mb-2 h-5 w-40">
</div> </div>
<div class="w-100 skeleton h-4"> <div class="w-100 skeleton h-4">

2
src/lib/components/RepoSummaryCard.stories.svelte

@ -24,3 +24,5 @@
<Story name="No Details" args={{}} /> <Story name="No Details" args={{}} />
<Story name="loading" args={{ loading: true }} /> <Story name="loading" args={{ loading: true }} />
<Story name="Multiple Maintainers" args={vectors.MulipleMaintainers} />

22
src/lib/components/RepoSummaryCard.svelte

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { summary_defaults } from './repo/type' import { summary_defaults } from './repo/type'
import UserHeader from './users/UserHeader.svelte'
export let { name, description, repo_id, maintainers, loading } = export let { name, description, repo_id, maintainers, loading } =
summary_defaults summary_defaults
@ -13,12 +14,27 @@
description.length > 50 ? description.slice(0, 45) + '...' : description description.length > 50 ? description.slice(0, 45) + '...' : description
</script> </script>
<div class="my-2 rounded-lg bg-base-200 p-4"> <div
class=" my-2 rounded-lg bg-base-200 p-4"
style={`min-height: ${maintainers.length * 1.325 + 2}rem;`}
>
{#if loading} {#if loading}
<div class="skeleton mb-2 h-5 w-40"></div> <div class="skeleton mb-2 h-5 w-40"></div>
<div class="w-100 skeleton h-4"></div> <div class="w-100 skeleton h-4"></div>
{:else} {:else}
<a class="link-primary break-words" href="/repo/{repo_id}">{short_name}</a> <p class="text-muted float-right break-words text-sm">
<p class="text-muted break-words text-sm">{short_descrption}</p> <span></span>
{#each maintainers as user}
<div class="text-right">
<UserHeader {user} inline={true} size="sm" />
</div>
{/each}
</p>
<a class="link-primary break-words" href="/repo/{encodeURI(repo_id)}"
>{short_name}</a
>
<p class="text-muted break-words text-sm">
{short_descrption}
</p>
{/if} {/if}
</div> </div>

15
src/lib/components/ReposSummaryList.stories.svelte

@ -19,7 +19,12 @@
name="Default" name="Default"
args={{ args={{
title: 'Featured Repositories', title: 'Featured Repositories',
repos: [vectors.Short, vectors.Long, vectors.LongNoSpaces], repos: [
vectors.Short,
vectors.Long,
vectors.LongNoSpaces,
vectors.MulipleMaintainers,
],
}} }}
/> />
@ -54,3 +59,11 @@
loading: true, loading: true,
}} }}
/> />
<Story
name="Multiple Maintainers"
args={{
title: 'Multiple Maintainers',
repos: [vectors.MulipleMaintainers, vectors.Long],
}}
/>

4
src/lib/components/ReposSummaryList.svelte

@ -17,8 +17,8 @@
<p class="prose">None</p> <p class="prose">None</p>
{:else} {:else}
<div class=""> <div class="">
{#each repos as { name, description, repo_id }} {#each repos as { name, description, repo_id, maintainers }}
<RepoSummaryCard {name} {description} {repo_id} /> <RepoSummaryCard {name} {description} {repo_id} {maintainers} />
{/each} {/each}
{#if loading} {#if loading}
<RepoSummaryCard loading={true} /> <RepoSummaryCard loading={true} />

16
src/lib/components/repo/vectors.ts

@ -5,16 +5,32 @@ export const RepoSummaryCardArgsVectors = {
Short: { Short: {
name: 'Short Name', name: 'Short Name',
description: 'short description', description: 'short description',
maintainers: [withName(UserVectors.default, 'Will')],
} as RepoSummary, } as RepoSummary,
Long: { Long: {
name: 'Long Name that goes on and on and on and on and on and on and on and on and on', name: 'Long Name that goes on and on and on and on and on and on and on and on and on',
description: description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nisl eget turpis congue molestie. Nulla vitae purus nec augue accumsan facilisis sed sed ligula. Vestibulum sed risus lacinia risus lacinia molestie. Ut lorem quam, consequat eget tempus in, rhoncus vel nunc. Duis efficitur a leo vel sodales. Nam id fermentum lacus. Etiam nec placerat velit. Praesent ac consectetur est. Aenean iaculis commodo enim.', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nisl eget turpis congue molestie. Nulla vitae purus nec augue accumsan facilisis sed sed ligula. Vestibulum sed risus lacinia risus lacinia molestie. Ut lorem quam, consequat eget tempus in, rhoncus vel nunc. Duis efficitur a leo vel sodales. Nam id fermentum lacus. Etiam nec placerat velit. Praesent ac consectetur est. Aenean iaculis commodo enim.',
maintainers: [withName(UserVectors.default, 'Rather Long Display Name')],
} as RepoSummary, } as RepoSummary,
LongNoSpaces: { LongNoSpaces: {
name: 'LongNameLongNameLongNameLongNameLongNameLongNameLongNameLongName', name: 'LongNameLongNameLongNameLongNameLongNameLongNameLongNameLongName',
description: description:
'LoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsum>', 'LoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsum>',
maintainers: [
{
...UserVectors.default,
},
],
} as RepoSummary,
MulipleMaintainers: {
name: 'Short Name',
description: 'short description',
maintainers: [
withName(UserVectors.default, 'Will'),
withName(UserVectors.default, 'DanConwayDev'),
withName(UserVectors.default, 'sectore'),
],
} as RepoSummary, } as RepoSummary,
} }
const base: Repo = { const base: Repo = {

51
src/lib/stores/repo.ts

@ -45,6 +45,24 @@ export const ensureSelectedRepo = async (repo_id: string): Promise<Repo> => {
sub.on('event', (event) => { sub.on('event', (event) => {
try { try {
if (event.kind == repo_kind && event.tagValue('d') == repo_id) { if (event.kind == repo_kind && event.tagValue('d') == repo_id) {
const maintainers = [
{
hexpubkey: event.pub_key,
loading: true,
npub: '',
} as User,
]
event.getMatchingTags('maintainers').forEach((t: string[]) => {
t.forEach((v, i) => {
if (i > 0 && v !== maintainers[0].hexpubkey) {
maintainers.push({
hexpubkey: v,
loading: true,
npub: '',
} as User)
}
})
})
selected_repo.set({ selected_repo.set({
loading: false, loading: false,
repo_id: event.replaceableDTag(), repo_id: event.replaceableDTag(),
@ -53,32 +71,23 @@ export const ensureSelectedRepo = async (repo_id: string): Promise<Repo> => {
description: event.tagValue('description') || '', description: event.tagValue('description') || '',
clone: event.tagValue('clone') || '', clone: event.tagValue('clone') || '',
tags: event.getMatchingTags('t') || [], tags: event.getMatchingTags('t') || [],
maintainers: event.getMatchingTags('p').map( maintainers,
(t: string[]) =>
({
hexpubkey: t[1],
loading: true,
npub: '',
}) as User
),
relays: event.getMatchingTags('relay').map((t: string[]) => t[1]), relays: event.getMatchingTags('relay').map((t: string[]) => t[1]),
}) })
const old_unsubscribers = maintainers_unsubscribers const old_unsubscribers = maintainers_unsubscribers
maintainers_unsubscribers = event maintainers_unsubscribers = maintainers.map((m: User) => {
.getMatchingTags('p') return ensureUser(m.hexpubkey).subscribe((u: User) => {
.map((t: string[]) => { selected_repo.update((repo) => {
return ensureUser(t[1]).subscribe((u: User) => { return {
selected_repo.update((repo) => { ...repo,
return { maintainers: repo.maintainers.map((m) => {
...repo, if (m.hexpubkey == u.hexpubkey) return { ...u }
maintainers: repo.maintainers.map((m) => { else return { ...m }
if (m.hexpubkey == u.hexpubkey) return { ...u } }),
else return { ...m } }
}),
}
})
}) })
}) })
})
old_unsubscribers.forEach((unsubscriber) => unsubscriber()) old_unsubscribers.forEach((unsubscriber) => unsubscriber())
} }
} catch {} } catch {}

102
src/lib/wrappers/ReposRecent.svelte

@ -1,10 +1,13 @@
<script lang="ts"> <script lang="ts">
import ReposSummaryList from '$lib/components/ReposSummaryList.svelte' import ReposSummaryList from '$lib/components/ReposSummaryList.svelte'
import type { RepoSummary } from '$lib/components/repo/type' import type { RepoSummary } from '$lib/components/repo/type'
import type { User } from '$lib/components/users/type'
import { repo_kind } from '$lib/kinds' import { repo_kind } from '$lib/kinds'
import { ndk } from '$lib/stores/ndk' import { ndk } from '$lib/stores/ndk'
import { ensureUser } from '$lib/stores/users'
import type { NDKEvent } from '@nostr-dev-kit/ndk' import type { NDKEvent } from '@nostr-dev-kit/ndk'
import { onDestroy } from 'svelte' import { onDestroy } from 'svelte'
import type { Unsubscriber } from 'svelte/store'
export let limit: number = 10 export let limit: number = 10
@ -14,33 +17,87 @@
kinds: [repo_kind], kinds: [repo_kind],
limit, limit,
}) })
let maintainers_unsubscribers: Unsubscriber[] = []
sub.on('event', (event: NDKEvent) => { sub.on('event', (event: NDKEvent) => {
if (repos.length < limit) { if (repos.length < limit) {
try { try {
if ( if (event.kind == repo_kind) {
event.kind == repo_kind && const maintainers = [
!repos.some(
(r) =>
r.repo_id == event.replaceableDTag() &&
event.created_at &&
r.created_at > event.created_at
)
)
repos = [
...repos.filter(
(r) =>
!event.created_at ||
r.repo_id !== event.replaceableDTag() ||
r.created_at > event.created_at
),
{ {
name: event.tagValue('name') || '', hexpubkey: event.pubkey,
description: event.tagValue('description') || '', loading: true,
repo_id: event.replaceableDTag(), npub: '',
maintainers: [], } as User,
created_at: event.created_at || 0,
},
] ]
event.getMatchingTags('maintainers').forEach((t: string[]) => {
t.forEach((v, i) => {
if (i > 0 && v !== maintainers[0].hexpubkey) {
maintainers.push({
hexpubkey: v,
loading: true,
npub: '',
} as User)
}
})
})
// not duplicate name
if (!repos.some((r) => r.repo_id == event.replaceableDTag())) {
repos = [
...repos,
{
name: event.tagValue('name') || '',
description: event.tagValue('description') || '',
repo_id: event.replaceableDTag(),
maintainers,
created_at: event.created_at || 0,
},
]
} else {
// duplicate name
repos = [
...repos.map((r) => {
if (event.created_at && r.repo_id == event.replaceableDTag()) {
let new_maintainers = maintainers.filter(
(m) =>
!r.maintainers.some((o) => o.hexpubkey == m.hexpubkey)
)
return {
name:
r.created_at < event.created_at
? event.tagValue('name') || r.name
: r.name,
description:
r.created_at < event.created_at
? event.tagValue('description') || r.description
: r.description,
repo_id: r.repo_id,
maintainers: [...r.maintainers, ...new_maintainers],
created_at:
r.created_at < event.created_at
? event.created_at
: r.created_at,
}
} else return { ...r }
}),
]
}
// get maintainers profile
maintainers.forEach((m) => {
maintainers_unsubscribers.push(
ensureUser(m.hexpubkey).subscribe((u: User) => {
repos = repos.map((r) => {
return {
...r,
maintainers: r.maintainers.map((m) => {
if (m.hexpubkey == u.hexpubkey) return { ...u }
else return { ...m }
}),
}
})
})
)
})
}
} catch {} } catch {}
} else if (loading == true) loading = false } else if (loading == true) loading = false
}) })
@ -49,6 +106,7 @@
}) })
onDestroy(() => { onDestroy(() => {
maintainers_unsubscribers.forEach((unsubscriber) => unsubscriber())
sub.stop() sub.stop()
}) })
</script> </script>

Loading…
Cancel
Save