diff options
| author | Adam Soltys <[email protected]> | 2025-01-20 00:05:30 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-01-20 00:05:33 -0800 |
| commit | 494fa791c93297917cf3247b561d736934de805c (patch) | |
| tree | b92bbbabe7eed8cde7b9d251cfcb08221689cc83 /src | |
| parent | 684d5fe5643d481c4904a1323ae0a257c267b87b (diff) | |
| download | coinos-ui-494fa791c93297917cf3247b561d736934de805c.tar.gz coinos-ui-494fa791c93297917cf3247b561d736934de805c.zip | |
nostr routes
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/Event.svelte | 67 | ||||
| -rw-r--r-- | src/lib/store.ts | 1 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/notes/+page.svelte | 39 | ||||
| -rw-r--r-- | src/routes/(app)/e/[id]/+page.server.ts | 8 | ||||
| -rw-r--r-- | src/routes/(app)/e/[id]/+page.svelte | 55 | ||||
| -rw-r--r-- | src/routes/(app)/firehose/+page.svelte | 48 | ||||
| -rw-r--r-- | src/routes/(app)/thread/[id]/+page.server.ts | 12 | ||||
| -rw-r--r-- | src/routes/(app)/thread/[id]/+page.svelte | 16 |
8 files changed, 191 insertions, 55 deletions
diff --git a/src/components/Event.svelte b/src/components/Event.svelte new file mode 100644 index 00000000..289da0b1 --- /dev/null +++ b/src/components/Event.svelte @@ -0,0 +1,67 @@ +<script> + import Avatar from "$comp/Avatar.svelte"; + import Media from "$comp/Media.svelte"; + import { goto } from "$app/navigation"; + + let { event, minimal } = $props(); + let { author, parts, zaps, names } = $derived(event); + let go = () => goto(`/e/${event.id}`); + console.log(event.tags); +</script> + +<div class="space-y-5"> + <div class="flex gap-2 items-center"> + <Avatar user={author} size={16} /> + <a href={`/${author.pubkey}/notes`} class="contents"> + <div> + <div class="font-bold"> + {author.display} — {author.username} + </div> + {#if author.lud16} + <div class="flex items-center"> + <iconify-icon + noobserver + icon="ph:lightning-fill" + class="text-yellow-300" + ></iconify-icon> + {author.lud16} + </div> + {/if} + </div> + </a> + </div> + + <div class="text-2xl space-y-5 break-words" onclick={go}> + {#each parts as { type, value }, i} + {#if type === "text"} + {value} + {:else if type === "link" && !minimal} + <Media {value} /> + {:else if type.match(/^nostr:np(rofile|ub)$/)} + <a href={`/${value.pubkey}`} class="font-bold">@{names[value.pubkey]}</a + > + {/if} + {/each} + </div> +</div> + +{#if !minimal} + <a href={`/send/zap/${event.pubkey}/${event.id}`} class="btn btn-accent"> + <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300" + ></iconify-icon> + Zap + </a> +{/if} + +{#if zaps?.length} + <div class="flex flex-wrap gap-2"> + {#each zaps as { amount, user }} + <a href={`/${user.pubkey}`}> + <div class="flex gap-1 items-center"> + <Avatar {user} size={8} disabled={true} /> + <div>{amount}</div> + </div> + </a> + {/each} + </div> +{/if} diff --git a/src/lib/store.ts b/src/lib/store.ts index 23b38ace..9b57b05d 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -56,6 +56,7 @@ export const invoice = writable(); export const last = writable(); export const loginRedirect = writable(); export const decrypted = persistLocal("decrypted", {}); +export const ignore = persistLocal("ignore", []); export const mnemonic = persistSession("mnemonic"); export const newPayment = persistLocal("newPayment"); export const password = writable<string | undefined>(); diff --git a/src/routes/(app)/[username]/(profile)/notes/+page.svelte b/src/routes/(app)/[username]/(profile)/notes/+page.svelte new file mode 100644 index 00000000..0591a881 --- /dev/null +++ b/src/routes/(app)/[username]/(profile)/notes/+page.svelte @@ -0,0 +1,39 @@ +<script lang="ts"> + import Event from "$comp/Event.svelte"; + import { get, post } from "$lib/utils"; + import { onMount } from "svelte"; + import { Relay } from "nostr-tools/relay"; + import { ignore } from "$lib/store"; + + let { data } = $props(); + let { subject } = $derived(data); + let events = $state([]); + onMount(async () => { + const relay = await Relay.connect("wss://relay.primal.net"); + const subscription = relay.subscribe( + [{ kinds: [1], authors: [subject.pubkey], limit: 20 }], + { + async onevent(event) { + // console.log(event); + const { parts, names } = await post("/post/parseEvent", { event }); + event.author = await get(`/api/users/${event.pubkey}`); + event.parts = parts; + event.names = names; + let { content, pubkey } = event; + events.push(event); + if (events.length > 20) events.shift(); + }, + }, + ); + }); +</script> + +<div class="container px-4 max-w-xl mx-auto space-y-5"> + <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold"> + Events + </h1> + + {#each events as event} + <Event {event} minimal={true} /> + {/each} +</div> diff --git a/src/routes/(app)/e/[id]/+page.server.ts b/src/routes/(app)/e/[id]/+page.server.ts index 78e3ea6e..ad692893 100644 --- a/src/routes/(app)/e/[id]/+page.server.ts +++ b/src/routes/(app)/e/[id]/+page.server.ts @@ -5,10 +5,12 @@ export async function load({ params }) { try { const event = await get(`/event/${params.id}`); const { parts, names } = await post("/parseEvent", { event }); - const author = await get(`/users/${event.pubkey}`); - const zaps = await get(`/zaps/${params.id}`); + event.parts = parts; + event.names = names; + event.author = await get(`/users/${event.pubkey}`); + event.zaps = await get(`/zaps/${params.id}`); - return { author, event, names, parts, zaps }; + return { event }; } catch (e) { console.log(e); error(500, { message: "Failed to get event" }); diff --git a/src/routes/(app)/e/[id]/+page.svelte b/src/routes/(app)/e/[id]/+page.svelte index 62b220a2..323fc55b 100644 --- a/src/routes/(app)/e/[id]/+page.svelte +++ b/src/routes/(app)/e/[id]/+page.svelte @@ -1,9 +1,8 @@ <script> - import Avatar from "$comp/Avatar.svelte"; - import Media from "$comp/Media.svelte"; + import Event from "$comp/Event.svelte"; let { data } = $props(); - let { author, event, names, parts, zaps } = $derived(data); + let { event } = $derived(data); let zap = () => {}; </script> @@ -13,53 +12,5 @@ Event </h1> - <div class="space-y-5"> - <div class="flex gap-2 items-center"> - <Avatar user={author} size={16} /> - <a href={`/${author.pubkey}`} class="contents"> - <div> - <div class="font-bold"> - {author.display} — {author.username} - </div> - <div class="flex items-center"> - <iconify-icon - noobserver - icon="ph:lightning-fill" - class="text-yellow-300" - ></iconify-icon> - {author.lud16} - </div> - </div> - </a> - </div> - - <div class="text-2xl space-y-5 break-words"> - {#each parts as { type, value }, i} - {#if type === "text"} - {value} - {:else if type === "link"} - <Media {value} /> - {:else if type.match(/^nostr:np(rofile|ub)$/)} - <a href={`/${value.pubkey}`} class="font-bold" - >@{names[value.pubkey]}</a - > - {/if} - {/each} - </div> - </div> - <a href={`/send/zap/${event.pubkey}/${event.id}`} class="btn btn-accent"> - <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300" - ></iconify-icon> - Zap - </a> - <div class="flex flex-wrap gap-2"> - {#each zaps as { amount, user }} - <a href={`/${user.pubkey}`}> - <div class="flex gap-1 items-center"> - <Avatar {user} size={8} disabled={true} /> - <div>{amount}</div> - </div> - </a> - {/each} - </div> + <Event {event} /> </div> diff --git a/src/routes/(app)/firehose/+page.svelte b/src/routes/(app)/firehose/+page.svelte new file mode 100644 index 00000000..1cf2324e --- /dev/null +++ b/src/routes/(app)/firehose/+page.svelte @@ -0,0 +1,48 @@ +<script lang="ts"> + import Event from "$comp/Event.svelte"; + import { get, post } from "$lib/utils"; + import { onMount } from "svelte"; + import { Relay } from "nostr-tools/relay"; + import { ignore } from "$lib/store"; + + let events = $state([]); + let paused = $state(); + let pause = (e) => { + e.preventDefault(); + e.stopPropagation(); + paused = true; + }; + let unpause = (e) => { + e.preventDefault(); + e.stopPropagation(); + paused = false; + }; + + onMount(async () => { + const relay = await Relay.connect("wss://relay.primal.net"); + const subscription = relay.subscribe([{ kinds: [1], limit: 20 }], { + async onevent(event) { + if (paused) return; + const { parts, names } = await post("/post/parseEvent", { event }); + event.author = await get(`/api/users/${event.pubkey}`); + event.parts = parts; + event.names = names; + let { content, pubkey } = event; + events.push(event); + if (events.length > 20) events.shift(); + }, + }); + }); +</script> + +<div class="container px-4 max-w-xl mx-auto space-y-5"> + <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold"> + Events + </h1> + + <div onpointerenter={pause} onpointerleave={unpause}> + {#each events as event} + <Event {event} minimal={true} /> + {/each} + </div> +</div> diff --git a/src/routes/(app)/thread/[id]/+page.server.ts b/src/routes/(app)/thread/[id]/+page.server.ts new file mode 100644 index 00000000..931e9cb8 --- /dev/null +++ b/src/routes/(app)/thread/[id]/+page.server.ts @@ -0,0 +1,12 @@ +import { get } from "$lib/utils"; +import { error } from "@sveltejs/kit"; + +export async function load({ params }) { + try { + const thread = await get(`/thread/${params.id}`); + return { thread }; + } catch (e) { + console.log(e); + error(500, { message: "Failed to get thread" }); + } +} diff --git a/src/routes/(app)/thread/[id]/+page.svelte b/src/routes/(app)/thread/[id]/+page.svelte new file mode 100644 index 00000000..25c911fc --- /dev/null +++ b/src/routes/(app)/thread/[id]/+page.svelte @@ -0,0 +1,16 @@ +<script> + import Event from "$comp/Event.svelte"; + + let { data } = $props(); + let { thread } = $derived(data); +</script> + +<div class="container px-4 max-w-xl mx-auto space-y-5"> + <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold"> + Thread + </h1> + + {#each thread as event} + <Event {event} /> + {/each} +</div> |
