From cea4e86c343cd7889798845252b47ffe32f27441 Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Sun, 25 May 2025 01:39:24 +0200
Subject: [PATCH] add image support
---
package-lock.json | 1 +
package.json | 1 +
src/lib/components/ChatInput.svelte | 65 ++++++++-
src/lib/components/ChatMessage.svelte | 16 ++-
src/lib/components/ChatMessageThread.svelte | 2 +-
src/lib/components/Image.svelte | 38 +++++
src/lib/components/ReplyMessage.svelte | 2 +-
src/lib/components/TimelineView.svelte | 24 +++-
.../rich-text-editor/RichTextEditor.svelte | 135 ++++++++----------
src/lib/schema.ts | 6 +-
.../channel/[channelId]/+page.svelte | 27 +++-
.../thread/[threadId]/+page.svelte | 19 ++-
12 files changed, 234 insertions(+), 102 deletions(-)
create mode 100644 src/lib/components/Image.svelte
diff --git a/package-lock.json b/package-lock.json
index 933dea1..6200766 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,7 @@
"@tiptap/extension-underline": "^2.12.0",
"@tiptap/starter-kit": "^2.12.0",
"@use-gesture/vanilla": "^10.3.1",
+ "bits-ui": "^1.7.0",
"jazz-browser-media-images": "^0.14.8",
"jazz-inspector-element": "^0.14.0",
"jazz-richtext-tiptap": "^0.1.15",
diff --git a/package.json b/package.json
index 51dabca..56d291f 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,7 @@
"@tiptap/extension-underline": "^2.12.0",
"@tiptap/starter-kit": "^2.12.0",
"@use-gesture/vanilla": "^10.3.1",
+ "bits-ui": "^1.7.0",
"jazz-browser-media-images": "^0.14.8",
"jazz-inspector-element": "^0.14.0",
"jazz-richtext-tiptap": "^0.1.15",
diff --git a/src/lib/components/ChatInput.svelte b/src/lib/components/ChatInput.svelte
index 58326d9..537bfed 100644
--- a/src/lib/components/ChatInput.svelte
+++ b/src/lib/components/ChatInput.svelte
@@ -1,10 +1,13 @@
{#if me?.root?.joinedSpaces?.some((space) => space?.id === route.spaceId)}
{#if replyTo}
@@ -69,11 +88,47 @@
{/if}
-
+
+ {#if images && images.length > 0}
+
+ {#each images as image}
+
+
+
+
+ {/each}
+
+ {/if}
+ {#if processingImage}
+
+ Processing image...
+
+ {/if}
+
+
{:else}
diff --git a/src/lib/components/ChatMessage.svelte b/src/lib/components/ChatMessage.svelte
index 63baf57..42d15c7 100644
--- a/src/lib/components/ChatMessage.svelte
+++ b/src/lib/components/ChatMessage.svelte
@@ -1,5 +1,5 @@
+
+
diff --git a/src/lib/components/ReplyMessage.svelte b/src/lib/components/ReplyMessage.svelte
index 885ec49..d488b8c 100644
--- a/src/lib/components/ReplyMessage.svelte
+++ b/src/lib/components/ReplyMessage.svelte
@@ -22,7 +22,7 @@
{#if message.current}
diff --git a/src/lib/components/TimelineView.svelte b/src/lib/components/TimelineView.svelte
index 4c0a710..c8c13cb 100644
--- a/src/lib/components/TimelineView.svelte
+++ b/src/lib/components/TimelineView.svelte
@@ -6,6 +6,7 @@
import { page } from '$app/state';
import { setContext } from 'svelte';
import { view } from '../../routes/[spaceId]/view.svelte';
+ import { ScrollArea } from '@fuxui/base';
let viewport: HTMLDivElement = $state(null!);
let virtualizer: Virtualizer
| undefined = $state();
@@ -54,12 +55,21 @@
});
-
+
diff --git a/src/lib/components/rich-text-editor/RichTextEditor.svelte b/src/lib/components/rich-text-editor/RichTextEditor.svelte
index c97b406..c5a88bc 100644
--- a/src/lib/components/rich-text-editor/RichTextEditor.svelte
+++ b/src/lib/components/rich-text-editor/RichTextEditor.svelte
@@ -7,9 +7,14 @@
import Underline from '@tiptap/extension-underline';
import Typography from '@tiptap/extension-typography';
import { RichTextLink } from './RichTextLink';
- import { cn } from '@fuxui/base';
+ import { Button, cn } from '@fuxui/base';
import { ImageUploadNode } from './image-upload/ImageUploadNode';
import { initKeyboardShortcutHandler } from './onEnter';
+ import { ImageList } from '$lib/schema';
+ import type { Loaded } from 'jazz-tools';
+ import { createImage } from 'jazz-browser-media-images';
+ import { publicGroup } from '$lib/utils';
+ import { Portal } from 'bits-ui';
let {
content = $bindable({}),
@@ -19,7 +24,8 @@
class: className,
onupdate,
htmlContent = $bindable(''),
- onEnter,
+ processImageFile,
+ onEnter
}: {
content?: Content;
placeholder?: string;
@@ -30,6 +36,7 @@
ontransaction?: () => void;
htmlContent?: string;
onEnter: () => void;
+ processImageFile: (file: File) => void;
} = $props();
let hasFocus = true;
@@ -57,12 +64,6 @@
return '';
}
}),
- // Image.configure({
- // HTMLAttributes: {
- // class: 'max-w-full object-contain relative rounded-2xl'
- // },
- // allowBase64: true
- // }),
Underline.configure({}),
RichTextLink.configure({
openOnClick: false,
@@ -70,19 +71,7 @@
defaultProtocol: 'https'
}),
Typography.configure(),
- // ImageUploadNode.configure({
- // upload: async (file, onProgress, abortSignal) => {
- // console.log('uploading image', file);
- // // wait 2 seconds
- // for(let i = 0; i < 10; i++) {
- // await new Promise((resolve) => setTimeout(resolve, 200));
- // onProgress?.({ progress: i / 10 });
- // }
-
- // return 'https://picsum.photos/200/300';
- // }
- // }),
- initKeyboardShortcutHandler({ onEnter: onEnter }),
+ initKeyboardShortcutHandler({ onEnter: onEnter })
];
editor = new Editor({
@@ -106,51 +95,10 @@
},
content: ``
});
-
});
- // Flag to track whether a file is being dragged over the drop area
let isDragOver = $state(false);
- // Store local image files for later upload
- let localImages: Map = $state(new Map());
-
- // Track which image URLs in the editor are local previews
- let localImageUrls: Set = $state(new Set());
-
- // Process image file to create a local preview
- async function processImageFile(file: File) {
- if (!editor) {
- console.warn('Tiptap editor not initialized');
- return;
- }
-
- try {
- const localUrl = URL.createObjectURL(file);
-
- localImages.set(localUrl, file);
- localImageUrls.add(localUrl);
-
- //editor.commands.setImageUploadNode();
- editor.chain().focus().setImageUploadNode(
- {
- preview: localUrl
- }
- ).run();
-
- // wait 2 seconds
- // await new Promise((resolve) => setTimeout(resolve, 500));
-
- // content = editor.getJSON();
-
- // console.log('replacing image url in content');
- // replaceImageUrlInContent(content, localUrl, 'https://picsum.photos/200/300');
- // editor.commands.setContent(content);
- } catch (error) {
- console.error('Error creating image preview:', error);
- }
- }
-
const handlePaste = (event: ClipboardEvent) => {
const items = event.clipboardData?.items;
if (!items) return;
@@ -169,11 +117,13 @@
event.preventDefault();
event.stopPropagation();
isDragOver = true;
+ console.log('drag over');
}
function handleDragLeave(event: DragEvent) {
event.preventDefault();
event.stopPropagation();
isDragOver = false;
+ console.log('drag leave');
}
function handleDrop(event: DragEvent) {
event.preventDefault();
@@ -184,27 +134,60 @@
if (file?.type.startsWith('image/')) {
processImageFile(file);
}
+ console.log('drop');
}
onDestroy(() => {
- for (const localUrl of localImageUrls) {
- URL.revokeObjectURL(localUrl);
- }
-
editor?.destroy();
});
-
-
-
+
+
+{#if isDragOver}
+
+
+ Drop image to add it to your message
+
+
+{/if}
+
+
+
+
+
+
+