From c7b46233b2e5b67da4b5e2b2d014baf1e9a90979 Mon Sep 17 00:00:00 2001 From: April Hall Date: Tue, 25 Feb 2025 10:25:48 -0500 Subject: [PATCH] feat: Message context menus --- prodServer.ts | 1 + src/lib/components/message.svelte | 73 +++++++++++++------ .../context-menu-checkbox-item.svelte | 35 +++++++++ .../context-menu/context-menu-content.svelte | 21 ++++++ .../ui/context-menu/context-menu-item.svelte | 31 ++++++++ .../ui/context-menu/context-menu-label.svelte | 16 ++++ .../context-menu-radio-group.svelte | 11 +++ .../context-menu-radio-item.svelte | 35 +++++++++ .../context-menu-separator.svelte | 11 +++ .../context-menu/context-menu-shortcut.svelte | 13 ++++ .../context-menu-sub-content.svelte | 23 ++++++ .../context-menu-sub-trigger.svelte | 32 ++++++++ src/lib/components/ui/context-menu/index.ts | 49 +++++++++++++ src/lib/functions/websocketConfig.ts | 1 + src/lib/types/index.ts | 2 + .../(main)/channel/[channel]/+page.server.ts | 1 + .../(main)/channel/[channel]/+page.svelte | 4 +- 17 files changed, 333 insertions(+), 26 deletions(-) create mode 100644 src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-content.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-label.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-radio-group.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-radio-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-separator.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-shortcut.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-sub-content.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/context-menu/index.ts diff --git a/prodServer.ts b/prodServer.ts index 1e75030..edcfa71 100644 --- a/prodServer.ts +++ b/prodServer.ts @@ -25,6 +25,7 @@ io.on('connection', async (socket) => { const sender = authdb.getUser(msg.id); io!.emit('message', { user: sender.username, + uid: msg.id, message: msg.content, imageSrc: sender.image, channel: msg.channel, diff --git a/src/lib/components/message.svelte b/src/lib/components/message.svelte index 1bcf207..0331006 100644 --- a/src/lib/components/message.svelte +++ b/src/lib/components/message.svelte @@ -2,33 +2,58 @@ import { type TypeMessage } from '$lib/types'; import Prose from '$lib/components/prose.svelte'; import renderMarkdown from '$lib/functions/renderMarkdown'; - const { message, imageSrc, user, timestamp }: TypeMessage = $props(); + import * as ContextMenu from '$lib/components/ui/context-menu'; + + const { message, imageSrc, user, timestamp, uid }: TypeMessage = $props(); + let epoch: number = Math.floor(timestamp.getTime() / 1000); + + function copy(itemName: string, content: string | number) { + navigator.clipboard + .writeText(content as string) + .then(() => { + console.info(`Successfully copied ${itemName} to clipboard`); + // dispatchToast('Successfully copied to clipboard.', true); + }) + .catch((e) => { + console.error(`Error copying ${itemName}: ${(e as Error).message}`); + // dispatchToast('Copying failed. (See console)', false); + }); + } -
-
-
- Profile image for {user} + + +
+
+ Profile image for {user} +
-
-
-

- {user} - · - {timestamp.toLocaleDateString('en-US', { - year: 'numeric', - month: 'short', - day: 'numeric', - hour12: true, - hour: 'numeric', - minute: 'numeric', - })} -

- {@html renderMarkdown(message)} -
-
+
+

+ {user} + · + {timestamp.toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour12: true, + hour: 'numeric', + minute: 'numeric', + })} +

+ {@html renderMarkdown(message)} +
+ + + copy('username', user)}>Copy Username + copy('user ID', uid)}>Copy User ID + + copy('message', message)}>Copy message content + copy('timestamp', epoch)}>Copy message epoch + +