Replying to Avatar verbiricha

From ef62256d050161fdfccafd2111005ab46c4f49dd Mon Sep 17 00:00:00 2001

From: Alejandro Gómez

Date: Mon, 22 Apr 2024 12:54:38 +0200

Subject: [PATCH] repo bookmarking

---

src/lib/components/AsyncButton.svelte | 21 +++++++++++++++++++++

src/lib/components/repo/RepoDetails.svelte | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--

src/lib/components/stars/icons.ts | 11 +++++++++++

src/lib/components/stars/type.ts | 13 +++++++++++++

src/lib/kinds.ts | 2 ++

src/lib/promise.ts | 3 +++

src/lib/stores/Issues.ts | 2 +-

src/lib/stores/Proposal.ts | 2 +-

src/lib/stores/Stargazers.ts | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

src/lib/wrappers/RepoMenu.svelte | 33 ++++++++++++++++++++++++++++++++-

src/lib/wrappers/RepoPageWrapper.svelte | 2 ++

src/routes/repo/[repo_id]/stargazers/+page.svelte | 34 ++++++++++++++++++++++++++++++++++

src/routes/repo/[repo_id]/stargazers/+page.ts | 5 +++++

13 files changed, 317 insertions(+), 5 deletions(-)

create mode 100644 src/lib/components/AsyncButton.svelte

create mode 100644 src/lib/components/stars/icons.ts

create mode 100644 src/lib/components/stars/type.ts

create mode 100644 src/lib/promise.ts

create mode 100644 src/lib/stores/Stargazers.ts

create mode 100644 src/routes/repo/[repo_id]/stargazers/+page.svelte

create mode 100644 src/routes/repo/[repo_id]/stargazers/+page.ts

diff --git a/src/lib/components/AsyncButton.svelte b/src/lib/components/AsyncButton.svelte

new file mode 100644

index 0000000..a750834

--- /dev/null

+++ b/src/lib/components/AsyncButton.svelte

@@ -0,0 +1,21 @@

+

+

+

diff --git a/src/lib/components/repo/RepoDetails.svelte b/src/lib/components/repo/RepoDetails.svelte

index 9be1f41..287ed68 100644

--- a/src/lib/components/repo/RepoDetails.svelte

+++ b/src/lib/components/repo/RepoDetails.svelte

@@ -1,6 +1,14 @@

-

+

+

+

{#if name == identifier}

{#if loading}

@@ -66,6 +156,32 @@

{identifier}

{/if}

{/if}

+

+ {#if ref}

+

+

+ xmlns="http://www.w3.org/2000/svg"

+ viewBox="0 0 16 16"

+ class={`w-4 h-4 mr-2 ${isStarred ? "fill-yellow-500" : "fill-gray-400"}`}

+ >

+ {#if isStarred}

+ {#each star_icon_path.filled as p}

+

+ {/each}

+ {:else}

+ {#each star_icon_path.outline as p}

+

+ {/each}

+ {/if}

+

+ {#if isStarred}

+ Unstar

+ {:else}

+ Star

+ {/if}

+

+ {/if}

+

{#if loading}

diff --git a/src/lib/components/stars/icons.ts b/src/lib/components/stars/icons.ts

new file mode 100644

index 0000000..73c465a

--- /dev/null

+++ b/src/lib/components/stars/icons.ts

@@ -0,0 +1,11 @@

+// icon are MIT licenced

+export const star_icon_path = {

+ // https://icon-sets.iconify.design/gravity-ui/star/

+ outline: [

+ "m9.194 5l.351.873l.94.064l3.197.217l-2.46 2.055l-.722.603l.23.914l.782 3.108l-2.714-1.704L8 10.629l-.798.5l-2.714 1.705l.782-3.108l.23-.914l-.723-.603l-2.46-2.055l3.198-.217l.94-.064l.35-.874L8 2.025zm-7.723-.292l3.943-.268L6.886.773C7.29-.231 8.71-.231 9.114.773l1.472 3.667l3.943.268c1.08.073 1.518 1.424.688 2.118L12.185 9.36l.964 3.832c.264 1.05-.886 1.884-1.802 1.31L8 12.4l-3.347 2.101c-.916.575-2.066-.26-1.802-1.309l.964-3.832L.783 6.826c-.83-.694-.391-2.045.688-2.118",

+ ],

+ // https://icon-sets.iconify.design/gravity-ui/star-fill/

+ filled: [

+ "M6.886.773C7.29-.231 8.71-.231 9.114.773l1.472 3.667l3.943.268c1.08.073 1.518 1.424.688 2.118L12.185 9.36l.964 3.832c.264 1.05-.886 1.884-1.802 1.31L8 12.4l-3.347 2.101c-.916.575-2.066-.26-1.802-1.309l.964-3.832L.783 6.826c-.83-.694-.391-2.045.688-2.118l3.943-.268z",

+ ],

+}

diff --git a/src/lib/components/stars/type.ts b/src/lib/components/stars/type.ts

new file mode 100644

index 0000000..f076086

--- /dev/null

+++ b/src/lib/components/stars/type.ts

@@ -0,0 +1,13 @@

+import type { NDKEvent } from '@nostr-dev-kit/ndk'

+

+export interface Stargazers {

+ id: string | undefined

+ events: NDKEvent[]

+ loading: boolean;

+}

+

+export const stars_defaults: Stargazers = {

+ id: '',

+ events: [],

+ loading: true,

+}

diff --git a/src/lib/kinds.ts b/src/lib/kinds.ts

index fd65cf2..06cd21b 100644

--- a/src/lib/kinds.ts

+++ b/src/lib/kinds.ts

@@ -27,3 +27,5 @@ export const repo_kind: number = 30617

export const patch_kind: number = 1617

export const issue_kind: number = 1621

+

+export const bookmarks_kind: number = 10617

diff --git a/src/lib/promise.ts b/src/lib/promise.ts

new file mode 100644

index 0000000..1577059

--- /dev/null

+++ b/src/lib/promise.ts

@@ -0,0 +1,3 @@

+export function timeout(ms: number) {

+ return new Promise((resolve) => setTimeout(resolve, ms))

+}

diff --git a/src/lib/stores/Issues.ts b/src/lib/stores/Issues.ts

index 23b6023..ba229fb 100644

--- a/src/lib/stores/Issues.ts

+++ b/src/lib/stores/Issues.ts

@@ -34,7 +34,7 @@ let selected_repo_id: string | undefined = ''

let sub: NDKSubscription

export const ensureIssueSummaries = async (repo_id: string | undefined) => {

- if (selected_repo_id == repo_id) return

+ if (selected_repo_id === repo_id) return

issue_summaries.set({

id: repo_id,

summaries: [],

diff --git a/src/lib/stores/Proposal.ts b/src/lib/stores/Proposal.ts

index c92d5f7..7aad603 100644

--- a/src/lib/stores/Proposal.ts

+++ b/src/lib/stores/Proposal.ts

@@ -109,7 +109,7 @@ export const ensureProposalFull = (

created_at: event.created_at,

comments: 0,

author: {

- hexpubkey: event.pubkey,

+ pubkey: event.pubkey,

loading: true,

npub: '',

},

diff --git a/src/lib/stores/Stargazers.ts b/src/lib/stores/Stargazers.ts

new file mode 100644

index 0000000..fbf5a11

--- /dev/null

+++ b/src/lib/stores/Stargazers.ts

@@ -0,0 +1,74 @@

+import {

+ NDKRelaySet,

+ type NDKEvent,

+ NDKSubscription,

+ type NDKFilter,

+} from '@nostr-dev-kit/ndk'

+import { writable, type Writable } from 'svelte/store'

+import { awaitSelectedRepoCollection } from './repo'

+import { selectRepoFromCollection } from '$lib/components/repo/utils'

+import { base_relays, ndk } from './ndk'

+import { repo_kind, bookmarks_kind } from '$lib/kinds'

+import { stars_defaults, type Stargazers } from '$lib/components/stars/type'

+

+export const stargazers: Writable = writable(stars_defaults)

+

+let selected_repo_id: string | undefined = ''

+

+let sub: NDKSubscription

+

+export async function fetchStargazers(repo_id: string | undefined) {

+ if (selected_repo_id === repo_id) return

+ selected_repo_id = repo_id;

+ stargazers.set({

+ id: repo_id,

+ events: [],

+ loading: true,

+ })

+ if (sub) sub.stop()

+ if (repo_id) {

+ const repo_collection = await awaitSelectedRepoCollection(repo_id)

+ const repo = selectRepoFromCollection(repo_collection)

+ if (!repo) {

+ // TODO: display error info bar

+ return

+ }

+ const relays_to_use =

+ repo.relays.length > 3

+ ? repo.relays

+ : [...base_relays].concat(repo.relays)

+

+ // todo: relays usually return max 500 results, if a repo is very popular, we may need to paginate

+ const filter = {

+ kinds: [bookmarks_kind],

+ '#a': repo.maintainers.map((m) => `${repo_kind}:${m}:${repo.identifier}`),

+ }

+

+ sub = ndk.subscribe(

+ filter,

+ {

+ closeOnEose: false,

+ },

+ NDKRelaySet.fromRelayUrls(relays_to_use, ndk)

+ )

+

+ sub.on('event', (event: NDKEvent) => {

+ stargazers.update((stars) => {

+ return {

+ ...stars,

+ events: stars.events.concat([event]),

+ loading: false,

+ }

+ })

+ })

+

+ sub.on('eose', () => {

+ stargazers.update((stars) => {

+ return {

+ ...stars,

+ loading: false,

+ }

+ })

+ })

+ }

+}

diff --git a/src/lib/wrappers/RepoMenu.svelte b/src/lib/wrappers/RepoMenu.svelte

index a5958be..df9e477 100644

--- a/src/lib/wrappers/RepoMenu.svelte

+++ b/src/lib/wrappers/RepoMenu.svelte

@@ -1,17 +1,23 @@

-

+

{#if !$selected_repo_readme.failed}

@@ -66,6 +72,31 @@

{/if}

+

+ href={`/repo/${identifier}/stargazers`}

+ class="tab"

+ class:tab-active={selected_tab === 'stargazers'}

+ >

+

+ xmlns="http://www.w3.org/2000/svg"

+ viewBox="0 0 16 16"

+ class={`mb-1 mr-1 h-4 w-4 flex-none fill-base-content pt-1 ${isStarred ? "fill-yellow-500" : "opacity-50"}`}

+ >

+ {#if isStarred}

+ {#each star_icon_path.filled as p}

+

+ {/each}

+ {:else}

+ {#each star_icon_path.outline as p}

+

+ {/each}

+ {/if}

+

+ Stars

+

+ {$stargazers.events.length}

+

+

diff --git a/src/lib/wrappers/RepoPageWrapper.svelte b/src/lib/wrappers/RepoPageWrapper.svelte

index 76107b8..d9618cd 100644

--- a/src/lib/wrappers/RepoPageWrapper.svelte

+++ b/src/lib/wrappers/RepoPageWrapper.svelte

@@ -9,6 +9,7 @@

import Container from '$lib/components/Container.svelte'

import { ensureProposalSummaries } from '$lib/stores/Proposals'

import { ensureIssueSummaries } from '$lib/stores/Issues'

+ import { fetchStargazers } from '$lib/stores/Stargazers'

import type { RepoPage } from '$lib/components/repo/type'

export let identifier = ''

@@ -18,6 +19,7 @@

ensureSelectedRepoCollection(identifier)

ensureProposalSummaries(identifier)

ensureIssueSummaries(identifier)

+ fetchStargazers(identifier)

let repo_error = false

diff --git a/src/routes/repo/[repo_id]/stargazers/+page.svelte b/src/routes/repo/[repo_id]/stargazers/+page.svelte

new file mode 100644

index 0000000..e77188d

--- /dev/null

+++ b/src/routes/repo/[repo_id]/stargazers/+page.svelte

@@ -0,0 +1,34 @@

+

+

+

+ {#if !$stargazers.loading }

+

+ {#if $stargazers.events.length === 0}

+

+ there aren't any stargazers yet

+

+ {:else}

+

+ {#each $stargazers.events as event}

+

+ {/each}

+

+ {/if}

+

+ {/if}

+

diff --git a/src/routes/repo/[repo_id]/stargazers/+page.ts b/src/routes/repo/[repo_id]/stargazers/+page.ts

new file mode 100644

index 0000000..c70bf13

--- /dev/null

+++ b/src/routes/repo/[repo_id]/stargazers/+page.ts

@@ -0,0 +1,5 @@

+export const load = ({ params }: { params: { repo_id: string } }) => {

+ return {

+ repo_id: decodeURIComponent(params.repo_id),

+ }

+}

--

libgit2 1.7.2

I just zapped this commit using amethyst:

nostr:nevent1qqs9y5n56zdfzfnzc7xn3j8q6wjsyduyqgcdrd99vzc8lrh3lj9ekqspz3mhxw309akx7cmpd35x7um58g6rsd3e9upzqla9dawkjc4trc7dgf88trpsq2uxvhmmpkxua607nc5g6a634sv5qvzqqqqx2ysvuleu

Reply to this note

Please Login to reply.

Discussion

I need to add zapping support so we can don't directly in gitworkshop.