add user profile details via a svelte store this sets a standard for abstracting ui from data wrappers even when multiple calls are neededmaster
|
After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
||||
|
||||
exports[`Users/Header default smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded"> |
||||
<img class="my-0" |
||||
src="../test-profile-image.jpg" |
||||
alt="DanConwayDev" |
||||
> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
DanConwayDev |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Users/Header displayName without name smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded"> |
||||
<img class="my-0" |
||||
src="../test-profile-image.jpg" |
||||
alt="DanConwayDev" |
||||
> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
DanConwayDev |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Users/Header loading smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded skeleton"> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
<div class="w-24 h-4 skeleton"> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Users/Header name and displayName shows name smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded"> |
||||
<img class="my-0" |
||||
src="../test-profile-image.jpg" |
||||
alt="Dan" |
||||
> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
Dan |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Users/Header no image smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded bg-neutral"> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
DanConwayDev |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Users/Header not found smoke-test 1`] = ` |
||||
<div class="flex my-2"> |
||||
<div class="avatar flex-none"> |
||||
<div class="w-8 h-8 rounded bg-neutral"> |
||||
</div> |
||||
</div> |
||||
<div class="flex-auto pl-3 m-auto"> |
||||
npub18669... |
||||
</div> |
||||
</div> |
||||
`; |
||||
@ -1,31 +1,11 @@
@@ -1,31 +1,11 @@
|
||||
<script lang="ts" context="module"> |
||||
import type { NDKUserProfile } from "@nostr-dev-kit/ndk"; |
||||
|
||||
export interface Args { |
||||
repo_id: string; |
||||
name: string; |
||||
description: string; |
||||
git_server: string; |
||||
tags: string[]; |
||||
maintainers: User[]; |
||||
relays: string[]; |
||||
loading?: boolean; |
||||
} |
||||
export const defaults: Args = { |
||||
repo_id: "", |
||||
name: "", |
||||
description: "", |
||||
git_server: "", |
||||
tags: [], |
||||
maintainers: [], |
||||
relays: [], |
||||
loading: true, |
||||
}; |
||||
</script> |
||||
|
||||
<script lang="ts"> |
||||
import type { User } from "./users/type"; |
||||
import UserHeader from "./users/UserHeader.svelte"; |
||||
import type { User } from "$lib/components/users/type"; |
||||
import UserHeader from "$lib/components/users/UserHeader.svelte"; |
||||
import { defaults } from "./type"; |
||||
|
||||
export let { |
||||
repo_id, |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
import type { User } from "../users/type"; |
||||
|
||||
export interface Repo { |
||||
repo_id: string; |
||||
name: string; |
||||
description: string; |
||||
git_server: string; |
||||
tags: string[]; |
||||
maintainers: User[]; |
||||
relays: string[]; |
||||
loading: boolean; |
||||
} |
||||
export const defaults: Repo = { |
||||
repo_id: "", |
||||
name: "", |
||||
description: "", |
||||
git_server: "", |
||||
tags: [], |
||||
maintainers: [], |
||||
relays: [], |
||||
loading: true, |
||||
}; |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
import { NDKUser } from "@nostr-dev-kit/ndk"; |
||||
import { writable, type Unsubscriber, type Writable } from "svelte/store" |
||||
import { ndk } from "./ndk"; |
||||
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; |
||||
|
||||
export let selected_repo: Writable<Repo> = writable({ ...defaults }); |
||||
let selected_repo_id: string = ""; |
||||
|
||||
let maintainers_unsubscribers: Unsubscriber[] = []; |
||||
|
||||
export let ensureSelectedRepo = (repo_id: string) => { |
||||
if (selected_repo_id == repo_id) return selected_repo; |
||||
selected_repo_id = repo_id; |
||||
let sub = ndk.subscribe({ |
||||
kinds: [repo_kind], |
||||
'#d': [repo_id], |
||||
limit: 1, |
||||
}); |
||||
|
||||
sub.on("event", (event) => { |
||||
try { |
||||
if (event.kind == repo_kind && event.tagValue("d") == repo_id) { |
||||
selected_repo.set({ |
||||
loading: false, |
||||
repo_id: event.replaceableDTag(), |
||||
name: event.tagValue("name") || "", |
||||
description: event.tagValue("description") || "", |
||||
git_server: event.tagValue("git_server") || "", |
||||
tags: event.getMatchingTags("t") || [], |
||||
maintainers: event.getMatchingTags("p").map( |
||||
(t: string[]) => |
||||
({ |
||||
hexpubkey: t[1], |
||||
loading: true, |
||||
npub: "", |
||||
}) as User, |
||||
), |
||||
relays: event |
||||
.getMatchingTags("relay") |
||||
.map((t: string[]) => t[1]), |
||||
}); |
||||
let old_unsubscribers = maintainers_unsubscribers; |
||||
maintainers_unsubscribers = event |
||||
.getMatchingTags("p") |
||||
.map((t: string[]) => { |
||||
return ensureUser(t[1]).subscribe((u: User) => { |
||||
selected_repo.update((repo) => { |
||||
return { |
||||
...repo, |
||||
maintainers: repo.maintainers.map((m) => { |
||||
if (m.hexpubkey == u.hexpubkey) return { ...u }; |
||||
else return { ...m }; |
||||
}), |
||||
}; |
||||
}); |
||||
}) |
||||
}); |
||||
old_unsubscribers.forEach((unsubscriber) => unsubscriber()); |
||||
} |
||||
} catch { } |
||||
}); |
||||
sub.on("eose", () => { |
||||
selected_repo.update((repo) => { |
||||
return { |
||||
...repo, |
||||
loading: false, |
||||
} |
||||
}) |
||||
}); |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
import type { User } from "$lib/components/users/type"; |
||||
import { NDKUser } from "@nostr-dev-kit/ndk"; |
||||
import { writable, type Writable } from "svelte/store" |
||||
import { ndk } from "./ndk"; |
||||
|
||||
export let users: { [hexpubkey: string]: Writable<User>; } = {}; |
||||
|
||||
export let ensureUser = (hexpubkey: string): Writable<User> => { |
||||
if (!users[hexpubkey]) { |
||||
let u = ndk.getUser({ hexpubkey }); |
||||
|
||||
let base: User = { |
||||
loading: false, |
||||
hexpubkey, |
||||
npub: u.npub, |
||||
}; |
||||
|
||||
users[hexpubkey] = writable(base); |
||||
u.fetchProfile().then( |
||||
(p) => { |
||||
users[hexpubkey].update((u) => ({ |
||||
...u, |
||||
loading: false, |
||||
profile: p === null ? undefined : p, |
||||
})); |
||||
}, |
||||
() => { |
||||
users[hexpubkey].update((u) => ({ |
||||
...u, |
||||
loading: false, |
||||
})); |
||||
} |
||||
); |
||||
} |
||||
return users[hexpubkey]; |
||||
} |
||||
@ -1,39 +1,10 @@
@@ -1,39 +1,10 @@
|
||||
<script lang="ts"> |
||||
import type { Args } from "$lib/components/RepoDetails.svelte"; |
||||
import { defaults } from "$lib/components/RepoDetails.svelte"; |
||||
import RepoDetails from "$lib/components/RepoDetails.svelte"; |
||||
import { ndk } from "$lib/stores/ndk"; |
||||
import RepoDetails from "$lib/components/repo/RepoDetails.svelte"; |
||||
import { ensureSelectedRepo, selected_repo } from "$lib/stores/repo"; |
||||
|
||||
export let repo_id = ""; |
||||
|
||||
let repo: Args = { ...defaults }; |
||||
let loading: boolean = true; |
||||
let kind: number = 30317; |
||||
let sub = ndk.subscribe({ |
||||
kinds: [kind], |
||||
limit: 1, |
||||
}); |
||||
sub.on("event", (event) => { |
||||
try { |
||||
if (event.kind == kind && event.tagValue("d") == repo_id) |
||||
repo = { |
||||
repo_id: event.replaceableDTag(), |
||||
name: event.tagValue("name") || "", |
||||
description: event.tagValue("description") || "", |
||||
git_server: event.tagValue("git_server") || "", |
||||
tags: event.getMatchingTags("t") || [], |
||||
maintainers: event |
||||
.getMatchingTags("p") |
||||
.map((t: string[]) => t[1]), |
||||
relays: event |
||||
.getMatchingTags("relay") |
||||
.map((t: string[]) => t[1]), |
||||
}; |
||||
} catch {} |
||||
}); |
||||
sub.on("eose", () => { |
||||
if (loading == true) loading = false; |
||||
}); |
||||
ensureSelectedRepo(repo_id); |
||||
</script> |
||||
|
||||
<RepoDetails {...repo} {loading} /> |
||||
<RepoDetails {...$selected_repo} /> |
||||
|
||||