浏览代码

enh: make large text as file toggleable

Timothy Jaeryang Baek 5 月之前
父节点
当前提交
9ea1c45641

+ 24 - 18
src/lib/components/chat/MessageInput.svelte

@@ -91,7 +91,7 @@
 		});
 	};
 
-	const uploadFileHandler = async (file) => {
+	const uploadFileHandler = async (file, fullContext: boolean = false) => {
 		if ($_user?.role !== 'admin' && !($_user?.permissions?.chat?.file_upload ?? true)) {
 			toast.error($i18n.t('You do not have permission to upload files.'));
 			return null;
@@ -110,7 +110,8 @@
 			status: 'uploading',
 			size: file.size,
 			error: '',
-			itemId: tempItemId
+			itemId: tempItemId,
+			...(fullContext ? { context: 'full' } : {})
 		};
 
 		if (fileItem.size == 0) {
@@ -619,6 +620,7 @@
 												id="chat-input"
 												trim={true}
 												placeholder={placeholder ? placeholder : $i18n.t('Send a Message')}
+												largeTextAsFile={$settings?.largeTextAsFile ?? false}
 												bind:value={prompt}
 												shiftEnter={!$mobile ||
 													!(
@@ -773,16 +775,18 @@
 
 																reader.readAsDataURL(blob);
 															} else if (item.type === 'text/plain') {
-																e.preventDefault();
-																const text = await clipboardData.getData('text/plain');
+																if ($settings?.largeTextAsFile ?? false) {
+																	e.preventDefault();
+																	const text = await clipboardData.getData('text/plain');
 
-																if (text.length > PASTED_TEXT_CHARACTER_LIMIT) {
-																	const blob = new Blob([text], { type: 'text/plain' });
-																	const file = new File([blob], `Pasted_Text_${Date.now()}.txt`, {
-																		type: 'text/plain'
-																	});
+																	if (text.length > PASTED_TEXT_CHARACTER_LIMIT) {
+																		const blob = new Blob([text], { type: 'text/plain' });
+																		const file = new File([blob], `Pasted_Text_${Date.now()}.txt`, {
+																			type: 'text/plain'
+																		});
 
-																	await uploadFileHandler(file);
+																		await uploadFileHandler(file, true);
+																	}
 																}
 															}
 														}
@@ -961,16 +965,18 @@
 
 															reader.readAsDataURL(blob);
 														} else if (item.type === 'text/plain') {
-															e.preventDefault();
-															const text = await clipboardData.getData('text/plain');
+															if ($settings?.largeTextAsFile ?? false) {
+																e.preventDefault();
+																const text = await clipboardData.getData('text/plain');
 
-															if (text.length > PASTED_TEXT_CHARACTER_LIMIT) {
-																const blob = new Blob([text], { type: 'text/plain' });
-																const file = new File([blob], `Pasted_Text_${Date.now()}.txt`, {
-																	type: 'text/plain'
-																});
+																if (text.length > PASTED_TEXT_CHARACTER_LIMIT) {
+																	const blob = new Blob([text], { type: 'text/plain' });
+																	const file = new File([blob], `Pasted_Text_${Date.now()}.txt`, {
+																		type: 'text/plain'
+																	});
 
-																await uploadFileHandler(file);
+																	await uploadFileHandler(file, true);
+																}
 															}
 														}
 													}

+ 30 - 0
src/lib/components/chat/Settings/Interface.svelte

@@ -31,6 +31,7 @@
 	let defaultModelId = '';
 	let showUsername = false;
 	let richTextInput = true;
+	let largeTextAsFile = false;
 
 	let landingPageMode = '';
 	let chatBubble = true;
@@ -139,6 +140,11 @@
 		saveSettings({ richTextInput });
 	};
 
+	const toggleLargeTextAsFile = async () => {
+		largeTextAsFile = !largeTextAsFile;
+		saveSettings({ largeTextAsFile });
+	};
+
 	const toggleResponseAutoCopy = async () => {
 		const permission = await navigator.clipboard
 			.readText()
@@ -188,6 +194,8 @@
 		voiceInterruption = $settings.voiceInterruption ?? false;
 
 		richTextInput = $settings.richTextInput ?? true;
+		largeTextAsFile = $settings.largeTextAsFile ?? false;
+
 		landingPageMode = $settings.landingPageMode ?? '';
 		chatBubble = $settings.chatBubble ?? true;
 		widescreenMode = $settings.widescreenMode ?? false;
@@ -480,6 +488,28 @@
 				</div>
 			</div>
 
+			<div>
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs">
+						{$i18n.t('Paste Large Text as File')}
+					</div>
+
+					<button
+						class="p-1 px-3 text-xs flex rounded transition"
+						on:click={() => {
+							toggleLargeTextAsFile();
+						}}
+						type="button"
+					>
+						{#if largeTextAsFile === true}
+							<span class="ml-2 self-center">{$i18n.t('On')}</span>
+						{:else}
+							<span class="ml-2 self-center">{$i18n.t('Off')}</span>
+						{/if}
+					</button>
+				</div>
+			</div>
+
 			<div>
 				<div class=" py-0.5 flex w-full justify-between">
 					<div class=" self-center text-xs">

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

@@ -27,6 +27,7 @@
 
 	export let className = 'input-prose';
 	export let shiftEnter = false;
+	export let largeTextAsFile = false;
 
 	export let id = '';
 	export let value = '';
@@ -413,11 +414,13 @@
 						// Extract plain text from clipboard and paste it without formatting
 						const plainText = event.clipboardData.getData('text/plain');
 						if (plainText) {
-							if (plainText.length > PASTED_TEXT_CHARACTER_LIMIT) {
-								// Dispatch paste event to parent component
-								eventDispatch('paste', { event });
-								event.preventDefault();
-								return true;
+							if (largeTextAsFile) {
+								if (plainText.length > PASTED_TEXT_CHARACTER_LIMIT) {
+									// Dispatch paste event to parent component
+									eventDispatch('paste', { event });
+									event.preventDefault();
+									return true;
+								}
 							}
 
 							const modifiedText = handleTabIndentation(plainText);