浏览代码

refac: tts input

Timothy Jaeryang Baek 3 月之前
父节点
当前提交
0db8bedf45

+ 3 - 1
src/lib/components/channel/MessageInput.svelte

@@ -613,9 +613,11 @@
 					}}
 					onConfirm={async (data) => {
 						const { text, filename } = data;
-						content = `${content}${text} `;
 						recording = false;
 
+						await tick();
+						insertTextAtCursor(text);
+
 						await tick();
 
 						if (chatInputElement) {

+ 4 - 10
src/lib/components/chat/MessageInput.svelte

@@ -325,15 +325,7 @@
 			replaceCommandWithText(text);
 		} else {
 			if ($settings?.richTextInput ?? true) {
-				const selection = window.getSelection();
-				if (selection && selection.rangeCount > 0) {
-					const range = selection.getRangeAt(0);
-					range.deleteContents();
-					range.insertNode(document.createTextNode(text));
-					range.collapse(false);
-					selection.removeAllRanges();
-					selection.addRange(range);
-				}
+				chatInputElement?.insertContent(text);
 			} else {
 				const cursor = chatInput.selectionStart;
 				prompt = prompt.slice(0, cursor) + text + prompt.slice(cursor);
@@ -966,10 +958,12 @@
 							}}
 							onConfirm={async (data) => {
 								const { text, filename } = data;
-								prompt = `${prompt}${text} `;
 
 								recording = false;
 
+								await tick();
+								insertTextAtCursor(text);
+
 								await tick();
 								document.getElementById('chat-input')?.focus();
 

+ 61 - 5
src/lib/components/common/RichTextInput.svelte

@@ -50,7 +50,6 @@
 
 	import { onMount, onDestroy, tick, getContext } from 'svelte';
 	import { createEventDispatcher } from 'svelte';
-	import { socket } from '$lib/stores';
 
 	const i18n = getContext('i18n');
 	const eventDispatch = createEventDispatcher();
@@ -60,7 +59,7 @@
 	import { receiveTransaction, sendableSteps, getVersion } from 'prosemirror-collab';
 	import { Step } from 'prosemirror-transform';
 	import { Decoration, DecorationSet } from 'prosemirror-view';
-	import { Editor } from '@tiptap/core';
+	import { Editor, Extension } from '@tiptap/core';
 
 	import { AIAutocompletion } from './RichTextInput/AutoCompletion.js';
 	import History from '@tiptap/extension-history';
@@ -100,6 +99,10 @@
 
 	export let editor = null;
 
+	export let socket = null;
+	export let user = null;
+	export let documentId = '';
+
 	export let className = 'input-prose';
 	export let placeholder = 'Type here...';
 	export let link = false;
@@ -111,6 +114,7 @@
 	export let json = false;
 	export let raw = false;
 	export let editable = true;
+	export let collaboration = false;
 
 	export let showFormattingButtons = true;
 
@@ -146,9 +150,9 @@
 				update: (view, prevState) => {
 					const sendable = sendableSteps(view.state);
 					if (sendable) {
-						$socket.emit('document_steps', {
+						socket.emit('document_steps', {
 							document_id: documentId,
-							user_id: userId,
+							user_id: user?.id,
 							version: sendable.version,
 							steps: sendable.steps.map((step) => step.toJSON()),
 							clientID: sendable.clientID
@@ -159,8 +163,33 @@
 		});
 	};
 
+	function initializeCollaboration() {
+		if (!socket || !user || !documentId) {
+			console.warn('Collaboration not initialized: missing socket, user, or documentId');
+			return;
+		}
+
+		socket.emit('join_document', {
+			document_id: documentId,
+			user_id: user?.id,
+			user_name: user?.name,
+			user_color: user?.color
+		});
+
+		socket.on('document_steps', handleDocumentSteps);
+		socket.on('document_state', handleDocumentState);
+		socket.on('user_joined', handleUserJoined);
+		socket.on('user_left', handleUserLeft);
+		socket.on('connect', () => {
+			isConnected = true;
+		});
+		socket.on('disconnect', () => {
+			isConnected = false;
+		});
+	}
+
 	function handleDocumentSteps(data) {
-		if (data.user_id !== userId && editor) {
+		if (data.user_id !== user?.id && editor) {
 			const steps = data.steps.map((stepJSON) => Step.fromJSON(editor.schema, stepJSON));
 			const tr = receiveTransaction(editor.state, steps, data.clientID);
 
@@ -550,6 +579,10 @@
 
 		console.log('content', content);
 
+		if (collaboration) {
+			initializeCollaboration();
+		}
+
 		editor = new Editor({
 			element: element,
 			extensions: [
@@ -621,6 +654,17 @@
 								}
 							})
 						]
+					: []),
+
+				...(collaboration
+					? [
+							Extension.create({
+								name: 'socketCollaboration',
+								addProseMirrorPlugins() {
+									return [collaborationPlugin()];
+								}
+							})
+						]
 					: [])
 			],
 			content: content,
@@ -828,6 +872,18 @@
 	});
 
 	onDestroy(() => {
+		if (socket) {
+			socket.off('document_steps', handleDocumentSteps);
+			socket.off('document_state', handleDocumentState);
+			socket.off('user_joined', handleUserJoined);
+			socket.off('user_left', handleUserLeft);
+
+			socket.emit('leave_document', {
+				document_id: documentId,
+				user_id: userId
+			});
+		}
+
 		if (editor) {
 			editor.destroy();
 		}