From 8698dcc359837ac48981fd13d1572681e0ac2bef Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 8 Oct 2024 11:39:16 -0700 Subject: [PATCH] Rough out chat --- README.md | 2 +- package.json | 10 +- src/app.css | 9 +- src/app/commands.ts | 92 ++++++++---- src/app/components/ChannelCompose.svelte | 7 +- src/app/components/ChannelMessage.svelte | 49 ++----- .../ChannelMessageEmojiButton.svelte | 13 +- src/app/components/ChannelThread.svelte | 28 ++-- src/app/components/ChatMessage.svelte | 114 +++++++++++++++ .../components/ChatMessageEmojiButton.svelte | 62 ++++++++ src/app/components/ChatStart.svelte | 6 +- src/app/components/Content.svelte | 24 ++-- src/app/components/ContentLinkBlock.svelte | 9 +- src/app/components/ContentMention.svelte | 4 +- src/app/components/ContentQuote.svelte | 11 +- src/app/components/ContentToken.svelte | 3 - src/app/components/InfoHandle.svelte | 13 +- src/app/components/InfoRelay.svelte | 8 +- src/app/components/NoteCard.svelte | 8 +- src/app/components/PeopleItem.svelte | 33 +++-- src/app/components/PrimaryNav.svelte | 1 - src/app/components/Profile.svelte | 28 ++-- src/app/components/ProfileCircle.svelte | 4 +- src/app/components/ProfileCircles.svelte | 3 +- src/app/components/ProfileMultiSelect.svelte | 46 +++--- src/app/components/RelayAdd.svelte | 11 +- src/app/components/RelayItem.svelte | 13 +- src/app/components/SpaceAdd.svelte | 1 - src/app/components/ThreadItem.svelte | 8 +- src/app/modal.ts | 6 +- src/app/state.ts | 92 ++++++++---- src/lib/components/Avatar.svelte | 2 +- src/lib/components/Collapse.svelte | 8 +- src/lib/components/Drawer.svelte | 7 +- src/lib/components/EmojiPicker.svelte | 8 +- src/lib/components/Icon.svelte | 4 +- src/lib/components/ModalBox.svelte | 2 +- src/lib/components/SecondaryNav.svelte | 2 +- src/lib/components/Tippy.svelte | 18 +-- src/lib/components/WotScore.svelte | 4 +- src/lib/editor/EditEvent.svelte | 13 +- src/lib/editor/EditMention.svelte | 2 +- src/lib/editor/SuggestionProfile.svelte | 2 +- src/lib/editor/Suggestions.svelte | 6 +- src/lib/editor/util.ts | 44 +++--- src/routes/+layout.svelte | 4 +- src/routes/discover/+page.svelte | 2 +- src/routes/discover/themes/+page.svelte | 5 +- src/routes/home/+layout.svelte | 32 +++-- src/routes/home/+page.svelte | 5 +- src/routes/home/[chat]/+page.svelte | 136 ++++++++++++++++++ src/routes/home/notes/+page.svelte | 64 ++++----- src/routes/home/people/+page.svelte | 23 ++- src/routes/settings/+page.svelte | 39 ++--- src/routes/settings/about/+page.svelte | 6 +- src/routes/settings/profile/+page.svelte | 60 ++++---- src/routes/settings/relays/+page.svelte | 42 +++--- src/routes/spaces/[nrelay]/+layout.svelte | 2 +- .../spaces/[nrelay]/[[room]]/+page.svelte | 10 +- 59 files changed, 833 insertions(+), 437 deletions(-) create mode 100644 src/app/components/ChatMessage.svelte create mode 100644 src/app/components/ChatMessageEmojiButton.svelte create mode 100644 src/routes/home/[chat]/+page.svelte diff --git a/README.md b/README.md index 6cde226c..ade48b1d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A discord-like nostr client based on the idea of "relays as groups". WIP. - [ ] Profile settings - [ ] Relay settings ------- +--- - [ ] Add person drawer with info and recent notes, where you can follow/mute them. Maybe same stuff as person search - [ ] If the user isn't following anyone, show warning/fallback on people/notes pages diff --git a/package.json b/package.json index 92170e28..2a01c0ea 100644 --- a/package.json +++ b/package.json @@ -48,13 +48,13 @@ "@tiptap/extension-text": "^2.6.6", "@tiptap/suggestion": "^2.6.4", "@types/throttle-debounce": "^5.0.2", - "@welshman/app": "^0.0.7", "@welshman/content": "^0.0.11", "@welshman/lib": "^0.0.19", - "@welshman/net": "^0.0.23", - "@welshman/signer": "^0.0.6", - "@welshman/store": "^0.0.8", - "@welshman/util": "^0.0.34", + "@welshman/util": "^0.0.36", + "@welshman/store": "^0.0.9", + "@welshman/net": "^0.0.24", + "@welshman/signer": "^0.0.7", + "@welshman/app": "^0.0.11", "daisyui": "^4.12.10", "date-picker-svelte": "^2.13.0", "emoji-picker-element": "^1.22.8", diff --git a/src/app.css b/src/app.css index 3e5e0ea5..254c36aa 100644 --- a/src/app.css +++ b/src/app.css @@ -51,11 +51,13 @@ --secondary: oklch(var(--s)); } -.bg-alt, .bg-alt .bg-alt .bg-alt { +.bg-alt, +.bg-alt .bg-alt .bg-alt { @apply bg-base-100; } -.bg-alt .bg-alt, .bg-alt .bg-alt .bg-alt .bg-alt { +.bg-alt .bg-alt, +.bg-alt .bg-alt .bg-alt .bg-alt { @apply bg-base-300; } @@ -139,7 +141,8 @@ @apply link-content; } -.link-content, [tag] { +.link-content, +[tag] { @apply max-w-full overflow-hidden text-ellipsis whitespace-nowrap rounded bg-neutral px-1 text-neutral-content no-underline; } diff --git a/src/app/commands.ts b/src/app/commands.ts index 9d5d702b..f21dd8cb 100644 --- a/src/app/commands.ts +++ b/src/app/commands.ts @@ -1,9 +1,24 @@ -import {uniqBy, sleep, chunk, equals, nthNe, choice, append} from "@welshman/lib" -import {DELETE, PROFILE, INBOX_RELAYS, RELAYS, MUTES, FOLLOWS, REACTION, isSignedEvent, getPubkeyTagValues, createEvent, displayProfile, normalizeRelayUrl} from "@welshman/util" -import type {TrustedEvent} from "@welshman/util" +import {get} from "svelte/store" +import {ctx, uniqBy, uniq, sleep, chunk, equals, choice, append} from "@welshman/lib" +import { + DELETE, + PROFILE, + INBOX_RELAYS, + RELAYS, + MUTES, + FOLLOWS, + REACTION, + isSignedEvent, + createEvent, + displayProfile, + normalizeRelayUrl, +} from "@welshman/util" +import type {TrustedEvent, EventTemplate} from "@welshman/util" import type {SubscribeRequestWithHandlers} from "@welshman/net" +import {Nip59, stamp} from "@welshman/signer" import { pubkey, + signer, repository, makeThunk, publishThunk, @@ -19,7 +34,7 @@ import { tagPubkey, tagReactionTo, getRelayUrls, - getInboxRelaySelections, + userInboxRelaySelections, } from "@welshman/app" import {tagRoom, MEMBERSHIPS, INDEXER_RELAYS} from "@app/state" @@ -157,7 +172,7 @@ export const setRelayPolicy = (url: string, read: boolean, write: boolean) => }) export const setInboxRelayPolicy = (url: string, enabled: boolean) => { - const urls = getRelayUrls(getInboxRelaySelections(pubkey.get()!)) + const urls = getRelayUrls(get(userInboxRelaySelections)) // Only update inbox policies if they already exist or we're adding them if (enabled || urls.includes(url)) { @@ -179,7 +194,7 @@ export const joinRelay = async (url: string, claim?: string) => { makeThunk({ event: createEvent(28934, {tags: [["claim", claim]]}), relays: [url], - }) + }), ) } @@ -189,27 +204,56 @@ export const joinRelay = async (url: string, claim?: string) => { // Actions -export const publishReaction = ({relays, event, content, tags = []}: { - relays: string[] - event: TrustedEvent, - content: string, - tags?: string[][] +export const sendWrapped = async ({ + template, + pubkeys, +}: { + template: EventTemplate + pubkeys: string[] }) => { - const reaction = createEvent(REACTION, { + const nip59 = Nip59.fromSigner(signer.get()!) + + await Promise.all( + uniq(pubkeys).map(async recipient => { + const rumor = await nip59.wrap(recipient, stamp(template)) + const thunk = makeThunk({ + event: rumor.wrap, + relays: ctx.app.router.PublishMessage(recipient).getUrls(), + }) + + return publishThunk(thunk) + }), + ) +} + +export const makeReaction = ({ + event, + content, + tags = [], +}: { + event: TrustedEvent + content: string + tags?: string[][] +}) => + createEvent(REACTION, { content, - tags: [ - ...tags, - ...tagReactionTo(event), - ], + tags: [...tags, ...tagReactionTo(event)], }) - publishThunk(makeThunk({event: reaction, relays})) -} +export const publishReaction = ({ + relays, + event, + content, + tags = [], +}: { + relays: string[] + event: TrustedEvent + content: string + tags?: string[][] +}) => publishThunk(makeThunk({event: makeReaction({event, content, tags}), relays})) -export const publishDelete = ({relays, event}: {relays: string[], event: TrustedEvent}) => { - const deleteEvent = createEvent(DELETE, { - tags: [["k", String(event.kind)], ...tagEvent(event)], - }) +export const makeDelete = ({event}: {event: TrustedEvent}) => + createEvent(DELETE, {tags: [["k", String(event.kind)], ...tagEvent(event)]}) - publishThunk(makeThunk({event: deleteEvent, relays})) -} +export const publishDelete = ({relays, event}: {relays: string[]; event: TrustedEvent}) => + publishThunk(makeThunk({event: makeDelete({event}), relays})) diff --git a/src/app/components/ChannelCompose.svelte b/src/app/components/ChannelCompose.svelte index 48e6ff74..8df7dc20 100644 --- a/src/app/components/ChannelCompose.svelte +++ b/src/app/components/ChannelCompose.svelte @@ -3,12 +3,9 @@ import type {Readable} from "svelte/store" import {writable} from "svelte/store" import {createEditor, type Editor, EditorContent} from "svelte-tiptap" - import {createEvent} from "@welshman/util" - import {publishThunk, makeThunk} from "@welshman/app" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" import {getEditorOptions, getEditorTags, addFile} from "@lib/editor" - import {MESSAGE} from "@app/state" import {getPubkeyHints} from "@app/commands" export let onSubmit @@ -27,7 +24,9 @@ } onMount(() => { - editor = createEditor(getEditorOptions({submit, loading, getPubkeyHints, submitOnEnter: true, autofocus: true})) + editor = createEditor( + getEditorOptions({submit, loading, getPubkeyHints, submitOnEnter: true, autofocus: true}), + ) }) diff --git a/src/app/components/ChannelMessage.svelte b/src/app/components/ChannelMessage.svelte index e2b09dba..4442ae49 100644 --- a/src/app/components/ChannelMessage.svelte +++ b/src/app/components/ChannelMessage.svelte @@ -1,9 +1,4 @@ - + {/each} + + {/if} + + + diff --git a/src/app/components/ChatMessageEmojiButton.svelte b/src/app/components/ChatMessageEmojiButton.svelte new file mode 100644 index 00000000..065522f1 --- /dev/null +++ b/src/app/components/ChatMessageEmojiButton.svelte @@ -0,0 +1,62 @@ + + + + +
+ + +
diff --git a/src/app/components/ChatStart.svelte b/src/app/components/ChatStart.svelte index dd2d99ee..952f165f 100644 --- a/src/app/components/ChatStart.svelte +++ b/src/app/components/ChatStart.svelte @@ -1,8 +1,6 @@ - + {/each} diff --git a/src/routes/home/+layout.svelte b/src/routes/home/+layout.svelte index e627bde2..c328879e 100644 --- a/src/routes/home/+layout.svelte +++ b/src/routes/home/+layout.svelte @@ -1,8 +1,8 @@
diff --git a/src/routes/home/[chat]/+page.svelte b/src/routes/home/[chat]/+page.svelte new file mode 100644 index 00000000..354271e4 --- /dev/null +++ b/src/routes/home/[chat]/+page.svelte @@ -0,0 +1,136 @@ + + + + +
+
+
+
+ {#if others.length === 1} + + + {:else} + +

+ + and {others.length - 1} + {others.length > 2 ? "others" : "other"} +

+ {/if} +
+
+
+
+ {#each elements as { type, id, value, showPubkey } (id)} + {#if type === "date"} + {value} + {:else} +
+ +
+ {/if} + {/each} +

+ + {#if loading} + Looking for messages... + {:else} + End of message history + {/if} + +

+
+
+ +
+
diff --git a/src/routes/home/notes/+page.svelte b/src/routes/home/notes/+page.svelte index 20960616..8b257114 100644 --- a/src/routes/home/notes/+page.svelte +++ b/src/routes/home/notes/+page.svelte @@ -1,48 +1,47 @@ -
{#await loading}
diff --git a/src/routes/home/people/+page.svelte b/src/routes/home/people/+page.svelte index 347418f5..49557b67 100644 --- a/src/routes/home/people/+page.svelte +++ b/src/routes/home/people/+page.svelte @@ -1,25 +1,23 @@ -

People

Get the latest from people in your network

diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index 49be2627..8514e5b3 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -1,26 +1,17 @@