forked from open-webui/open-webui
		
	feat: image upload support
This commit is contained in:
		
							parent
							
								
									fb1f8b167c
								
							
						
					
					
						commit
						9b12cdcf83
					
				
					 4 changed files with 84 additions and 57 deletions
				
			
		| 
						 | 
				
			
			@ -14,7 +14,7 @@
 | 
			
		|||
 | 
			
		||||
	export let files = [];
 | 
			
		||||
 | 
			
		||||
	export let fileUploadEnabled = false;
 | 
			
		||||
	export let fileUploadEnabled = true;
 | 
			
		||||
	export let speechRecognitionEnabled = true;
 | 
			
		||||
	export let speechRecognitionListening = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,40 +84,40 @@
 | 
			
		|||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div class="fixed bottom-0 w-full bg-white dark:bg-gray-800">
 | 
			
		||||
	<div class=" absolute right-0 left-0 bottom-0 mb-20">
 | 
			
		||||
		<div class="max-w-3xl px-2.5 pt-2.5 -mb-0.5 mx-auto inset-x-0">
 | 
			
		||||
			{#if messages.length == 0 && suggestionPrompts.length !== 0}
 | 
			
		||||
<div class="fixed bottom-0 w-full">
 | 
			
		||||
	<div class="px-2.5 pt-2.5 -mb-0.5 mx-auto inset-x-0 bg-transparent flex justify-center">
 | 
			
		||||
		{#if messages.length == 0 && suggestionPrompts.length !== 0}
 | 
			
		||||
			<div class="max-w-3xl">
 | 
			
		||||
				<Suggestions {suggestionPrompts} {submitPrompt} />
 | 
			
		||||
			{/if}
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
 | 
			
		||||
			{#if autoScroll === false && messages.length > 0}
 | 
			
		||||
				<div class=" flex justify-center mb-4">
 | 
			
		||||
					<button
 | 
			
		||||
						class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
 | 
			
		||||
						on:click={() => {
 | 
			
		||||
							autoScroll = true;
 | 
			
		||||
							window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
 | 
			
		||||
						}}
 | 
			
		||||
		{#if autoScroll === false && messages.length > 0}
 | 
			
		||||
			<div class=" flex justify-center mb-4">
 | 
			
		||||
				<button
 | 
			
		||||
					class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
 | 
			
		||||
					on:click={() => {
 | 
			
		||||
						autoScroll = true;
 | 
			
		||||
						window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
 | 
			
		||||
					}}
 | 
			
		||||
				>
 | 
			
		||||
					<svg
 | 
			
		||||
						xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
						viewBox="0 0 20 20"
 | 
			
		||||
						fill="currentColor"
 | 
			
		||||
						class="w-5 h-5"
 | 
			
		||||
					>
 | 
			
		||||
						<svg
 | 
			
		||||
							xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
							viewBox="0 0 20 20"
 | 
			
		||||
							fill="currentColor"
 | 
			
		||||
							class="w-5 h-5"
 | 
			
		||||
						>
 | 
			
		||||
							<path
 | 
			
		||||
								fill-rule="evenodd"
 | 
			
		||||
								d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
 | 
			
		||||
								clip-rule="evenodd"
 | 
			
		||||
							/>
 | 
			
		||||
						</svg>
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			{/if}
 | 
			
		||||
		</div>
 | 
			
		||||
						<path
 | 
			
		||||
							fill-rule="evenodd"
 | 
			
		||||
							d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
 | 
			
		||||
							clip-rule="evenodd"
 | 
			
		||||
						/>
 | 
			
		||||
					</svg>
 | 
			
		||||
				</button>
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
	</div>
 | 
			
		||||
	<div>
 | 
			
		||||
	<div class="bg-white dark:bg-gray-800">
 | 
			
		||||
		<div class="max-w-3xl px-2.5 -mb-0.5 mx-auto inset-x-0">
 | 
			
		||||
			<div class="bg-gradient-to-t from-white dark:from-gray-800 from-40% pb-2">
 | 
			
		||||
				<input
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +136,7 @@
 | 
			
		|||
								}
 | 
			
		||||
							];
 | 
			
		||||
							inputFiles = null;
 | 
			
		||||
							filesInputElement.value = '';
 | 
			
		||||
						};
 | 
			
		||||
 | 
			
		||||
						if (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@
 | 
			
		|||
	export let sendPrompt: Function;
 | 
			
		||||
	export let regenerateResponse: Function;
 | 
			
		||||
 | 
			
		||||
	export let bottomPadding = false;
 | 
			
		||||
	export let autoScroll;
 | 
			
		||||
	export let selectedModels;
 | 
			
		||||
	export let history = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +32,13 @@
 | 
			
		|||
		})();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	$: if (autoScroll && bottomPadding) {
 | 
			
		||||
		(async () => {
 | 
			
		||||
			await tick();
 | 
			
		||||
			window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
 | 
			
		||||
		})();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const speakMessage = (message) => {
 | 
			
		||||
		const speak = new SpeechSynthesisUtterance(message);
 | 
			
		||||
		speechSynthesis.speak(speak);
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +192,8 @@
 | 
			
		|||
			parentId: history.messages[messageId].parentId,
 | 
			
		||||
			childrenIds: [],
 | 
			
		||||
			role: 'user',
 | 
			
		||||
			content: userPrompt
 | 
			
		||||
			content: userPrompt,
 | 
			
		||||
			...(history.messages[messageId].files && { files: history.messages[messageId].files })
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		let messageParentId = history.messages[messageId].parentId;
 | 
			
		||||
| 
						 | 
				
			
			@ -425,6 +434,18 @@
 | 
			
		|||
								class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-p:my-0 prose-p:-mb-4 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-6 prose-li:-mb-4 whitespace-pre-line"
 | 
			
		||||
							>
 | 
			
		||||
								{#if message.role == 'user'}
 | 
			
		||||
									{#if message.files}
 | 
			
		||||
										<div class="my-3 w-full flex overflow-x-auto space-x-2">
 | 
			
		||||
											{#each message.files as file}
 | 
			
		||||
												<div>
 | 
			
		||||
													{#if file.type === 'image'}
 | 
			
		||||
														<img src={file.url} alt="input" class=" max-h-96 rounded-lg" />
 | 
			
		||||
													{/if}
 | 
			
		||||
												</div>
 | 
			
		||||
											{/each}
 | 
			
		||||
										</div>
 | 
			
		||||
									{/if}
 | 
			
		||||
 | 
			
		||||
									{#if message?.edit === true}
 | 
			
		||||
										<div class=" w-full">
 | 
			
		||||
											<textarea
 | 
			
		||||
| 
						 | 
				
			
			@ -458,17 +479,6 @@
 | 
			
		|||
										</div>
 | 
			
		||||
									{:else}
 | 
			
		||||
										<div class="w-full">
 | 
			
		||||
											{#if message.files}
 | 
			
		||||
												<div class="my-3">
 | 
			
		||||
													{#each message.files as file}
 | 
			
		||||
														<div>
 | 
			
		||||
															{#if file.type === 'image'}
 | 
			
		||||
																<img src={file.url} alt="input" class=" max-h-96" />
 | 
			
		||||
															{/if}
 | 
			
		||||
														</div>
 | 
			
		||||
													{/each}
 | 
			
		||||
												</div>
 | 
			
		||||
											{/if}
 | 
			
		||||
											<pre id="user-message">{message.content}</pre>
 | 
			
		||||
 | 
			
		||||
											<div class=" flex justify-start space-x-1">
 | 
			
		||||
| 
						 | 
				
			
			@ -889,4 +899,8 @@
 | 
			
		|||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	{/each}
 | 
			
		||||
 | 
			
		||||
	{#if bottomPadding}
 | 
			
		||||
		<div class=" mb-10" />
 | 
			
		||||
	{/if}
 | 
			
		||||
{/if}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue