From 09028b69a48fb79c3065854b22fdf412f9912373 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Wed, 23 Oct 2024 14:20:24 -0700 Subject: [PATCH] Work on thread detail page --- src/app.css | 2 +- src/app/commands.ts | 58 +++++++++---- src/app/components/ChannelMessage.svelte | 47 ++--------- .../ChannelMessageMenuButton.svelte | 4 +- src/app/components/ChannelThread.svelte | 31 ++----- src/app/components/ChatMessage.svelte | 31 +------ src/app/components/Profile.svelte | 3 +- src/app/components/Reactions.svelte | 42 ++++++++++ src/app/components/ThreadCreate.svelte | 2 +- src/app/components/ThreadItem.svelte | 42 ++++++++-- src/app/components/ThreadReply.svelte | 82 +++++++++++++++++++ src/app/routes.ts | 2 + .../spaces/[relay]/threads/+page.svelte | 25 +++--- .../spaces/[relay]/threads/[id]/+page.svelte | 62 ++++++++++++++ tailwind.config.js | 1 + 15 files changed, 300 insertions(+), 134 deletions(-) create mode 100644 src/app/components/Reactions.svelte create mode 100644 src/app/components/ThreadReply.svelte create mode 100644 src/routes/spaces/[relay]/threads/[id]/+page.svelte diff --git a/src/app.css b/src/app.css index c98acb2..35e154b 100644 --- a/src/app.css +++ b/src/app.css @@ -181,7 +181,7 @@ } .note-editor .tiptap[contenteditable="true"] { - @apply input input-bordered h-auto min-h-32 p-[.65rem] pb-6; + @apply input input-bordered h-auto min-h-32 p-[.65rem] pb-6 rounded-box; } .tiptap pre code { diff --git a/src/app/commands.ts b/src/app/commands.ts index 0222ad8..16dd492 100644 --- a/src/app/commands.ts +++ b/src/app/commands.ts @@ -46,6 +46,7 @@ import { loadRelay, } from "@welshman/app" import { + REPLY, tagRoom, userMembership, MEMBERSHIPS, @@ -301,31 +302,52 @@ export const sendWrapped = async ({ ) } -export const makeReaction = ({ - event, - content, - tags = [], -}: { +export type ReactionParams = { event: TrustedEvent content: string tags?: string[][] -}) => - createEvent(REACTION, { - content, - tags: [...tags, ...tagReactionTo(event)], - }) +} -export const publishReaction = ({ - relays, - event, - content, - tags = [], -}: { - relays: string[] +export const makeReaction = ({event, content, tags = []}: ReactionParams) => + createEvent(REACTION, {content, tags: [...tags, ...tagReactionTo(event)]}) + +export const publishReaction = ({relays, ...params}: ReactionParams & {relays: string[]}) => + publishThunk({event: makeReaction(params), relays}) + +export type ReplyParams = { event: TrustedEvent content: string tags?: string[][] -}) => publishThunk({event: makeReaction({event, content, tags}), relays}) +} + +export const makeReply = ({event, content, tags = []}: ReplyParams) => { + const seenRoots = new Set() + + for (const [raw, ...tag] of event.tags.filter(t => t[0].match(/^K|E|A|I$/i))) { + const T = raw.toUpperCase() + const t = raw.toLowerCase() + + if (seenRoots.has(T)) { + tags.push([t, ...tag]) + } else { + tags.push([T, ...tag]) + seenRoots.add(T) + } + } + + if (seenRoots.size === 0) { + tags.push(["K", String(event.kind)]) + tags.push(["E", event.id]) + } else { + tags.push(["k", String(event.kind)]) + tags.push(["e", event.id]) + } + + return createEvent(REPLY, {content, tags}) +} + +export const publishReply = ({relays, ...params}: ReplyParams & {relays: string[]}) => + publishThunk({event: makeReply(params), relays}) export const makeDelete = ({event}: {event: TrustedEvent}) => createEvent(DELETE, {tags: [["k", String(event.kind)], ...tagEvent(event)]}) diff --git a/src/app/components/ChannelMessage.svelte b/src/app/components/ChannelMessage.svelte index 07be1e0..bd93e96 100644 --- a/src/app/components/ChannelMessage.svelte +++ b/src/app/components/ChannelMessage.svelte @@ -1,29 +1,25 @@
diff --git a/src/app/components/Reactions.svelte b/src/app/components/Reactions.svelte new file mode 100644 index 0000000..68abefc --- /dev/null +++ b/src/app/components/Reactions.svelte @@ -0,0 +1,42 @@ + + +{#if $reactions.length > 0 || $replies.length > 0} +
+ {#if $replies.length > 0 && showReplies} +
+ + {$replies.length} +
+ {/if} + {#each groupBy( e => e.content, uniqBy(e => e.pubkey + e.content, $reactions), ).entries() as [content, events]} + {@const isOwn = events.some(e => e.pubkey === $pubkey)} + {@const onClick = () => onReactionClick(content, events)} + + {/each} +
+{/if} diff --git a/src/app/components/ThreadCreate.svelte b/src/app/components/ThreadCreate.svelte index 5f58394..d9e54bb 100644 --- a/src/app/components/ThreadCreate.svelte +++ b/src/app/components/ThreadCreate.svelte @@ -37,7 +37,7 @@
Create a Thread
-
Share your thoughts, or start a discussion.
+
Share a link, or start a discussion.
diff --git a/src/app/components/ThreadItem.svelte b/src/app/components/ThreadItem.svelte index 1ff8dac..aed6856 100644 --- a/src/app/components/ThreadItem.svelte +++ b/src/app/components/ThreadItem.svelte @@ -1,14 +1,42 @@ -
- -
- + +
+ +

+ {formatTimestamp(event.created_at)} +

+
+
+ +
+
+ + {$replies.length} {$replies.length === 1 ? 'reply' : 'replies'} +
+
+ Active {formatTimestampRelative(lastActive)} +
- -
+
+ diff --git a/src/app/components/ThreadReply.svelte b/src/app/components/ThreadReply.svelte new file mode 100644 index 0000000..32ee7f8 --- /dev/null +++ b/src/app/components/ThreadReply.svelte @@ -0,0 +1,82 @@ + + +{#if visible} + +
+
+ +
+ +
+ + + + + +{:else} +
+ +
+{/if} diff --git a/src/app/routes.ts b/src/app/routes.ts index 10f7b5d..eb0c2f2 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -13,6 +13,8 @@ export const makeSpacePath = (url: string, extra = "") => { export const makeChatPath = (pubkeys: string[]) => `/chat/${makeChatId(pubkeys)}` +export const makeThreadPath = (url: string, eventId: string) => `/spaces/${encodeRelay(url)}/threads/${eventId}` + export const getPrimaryNavItem = ($page: Page) => $page.route?.id?.split("/")[1] export const getPrimaryNavItemIndex = ($page: Page) => { diff --git a/src/routes/spaces/[relay]/threads/+page.svelte b/src/routes/spaces/[relay]/threads/+page.svelte index f7d1b0f..9115cc0 100644 --- a/src/routes/spaces/[relay]/threads/+page.svelte +++ b/src/routes/spaces/[relay]/threads/+page.svelte @@ -1,10 +1,10 @@ + +
+ {#each sortBy(e => -e.created_at, $replies) as reply (reply.id)} + +
+ + +
+
+ {/each} + +
+ + +
+
+ +
+ diff --git a/tailwind.config.js b/tailwind.config.js index ca7942d..01237ad 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -29,6 +29,7 @@ export default { dark: { ...themes["dark"], primary: process.env.VITE_PLATFORM_ACCENT, + "primary-content": "#EAE7FF", }, }, ],