aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-01-20 00:05:30 -0800
committerAdam Soltys <[email protected]>2025-01-20 00:05:33 -0800
commit494fa791c93297917cf3247b561d736934de805c (patch)
treeb92bbbabe7eed8cde7b9d251cfcb08221689cc83
parent684d5fe5643d481c4904a1323ae0a257c267b87b (diff)
downloadcoinos-ui-494fa791c93297917cf3247b561d736934de805c.tar.gz
coinos-ui-494fa791c93297917cf3247b561d736934de805c.zip
nostr routes
-rwxr-xr-xbun.lockbbin192133 -> 192538 bytes
-rw-r--r--package.json5
-rw-r--r--src/components/Event.svelte67
-rw-r--r--src/lib/store.ts1
-rw-r--r--src/routes/(app)/[username]/(profile)/notes/+page.svelte39
-rw-r--r--src/routes/(app)/e/[id]/+page.server.ts8
-rw-r--r--src/routes/(app)/e/[id]/+page.svelte55
-rw-r--r--src/routes/(app)/firehose/+page.svelte48
-rw-r--r--src/routes/(app)/thread/[id]/+page.server.ts12
-rw-r--r--src/routes/(app)/thread/[id]/+page.svelte16
10 files changed, 195 insertions, 56 deletions
diff --git a/bun.lockb b/bun.lockb
index da442cb4..b6e1db74 100755
--- a/bun.lockb
+++ b/bun.lockb
Binary files differ
diff --git a/package.json b/package.json
index a22d3954..d95249e2 100644
--- a/package.json
+++ b/package.json
@@ -66,5 +66,8 @@
"lint": "prettier --check .",
"format": "prettier --write ."
},
- "type": "module"
+ "type": "module",
+ "dependencies": {
+ "ws": "^8.18.0"
+ }
}
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} &mdash; {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} &mdash; {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>