forked from open-webui/open-webui
		
	Merge branch 'main' into release-notes-modal
This commit is contained in:
		
						commit
						8fac9de269
					
				
					 14 changed files with 426 additions and 108 deletions
				
			
		| 
						 | 
				
			
			@ -222,6 +222,34 @@
 | 
			
		|||
			scrollToBottom();
 | 
			
		||||
		}, 100);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// TODO: change delete behaviour
 | 
			
		||||
	// const deleteMessageAndDescendants = async (messageId: string) => {
 | 
			
		||||
	// 	if (history.messages[messageId]) {
 | 
			
		||||
	// 		history.messages[messageId].deleted = true;
 | 
			
		||||
 | 
			
		||||
	// 		for (const childId of history.messages[messageId].childrenIds) {
 | 
			
		||||
	// 			await deleteMessageAndDescendants(childId);
 | 
			
		||||
	// 		}
 | 
			
		||||
	// 	}
 | 
			
		||||
	// };
 | 
			
		||||
 | 
			
		||||
	// const triggerDeleteMessageRecursive = async (messageId: string) => {
 | 
			
		||||
	// 	await deleteMessageAndDescendants(messageId);
 | 
			
		||||
	// 	await updateChatById(localStorage.token, chatId, { history });
 | 
			
		||||
	// 	await chats.set(await getChatList(localStorage.token));
 | 
			
		||||
	// };
 | 
			
		||||
 | 
			
		||||
	const messageDeleteHandler = async (messageId) => {
 | 
			
		||||
		if (history.messages[messageId]) {
 | 
			
		||||
			history.messages[messageId].deleted = true;
 | 
			
		||||
 | 
			
		||||
			for (const childId of history.messages[messageId].childrenIds) {
 | 
			
		||||
				history.messages[childId].deleted = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		await updateChatById(localStorage.token, chatId, { history });
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if messages.length == 0}
 | 
			
		||||
| 
						 | 
				
			
			@ -230,99 +258,103 @@
 | 
			
		|||
	<div class=" pb-10">
 | 
			
		||||
		{#key chatId}
 | 
			
		||||
			{#each messages as message, messageIdx}
 | 
			
		||||
				<div class=" w-full">
 | 
			
		||||
					<div
 | 
			
		||||
						class="flex flex-col justify-between px-5 mb-3 {$settings?.fullScreenMode ?? null
 | 
			
		||||
							? 'max-w-full'
 | 
			
		||||
							: 'max-w-3xl'} mx-auto rounded-lg group"
 | 
			
		||||
					>
 | 
			
		||||
						{#if message.role === 'user'}
 | 
			
		||||
							<UserMessage
 | 
			
		||||
								user={$user}
 | 
			
		||||
								{message}
 | 
			
		||||
								siblings={message.parentId !== null
 | 
			
		||||
									? history.messages[message.parentId]?.childrenIds ?? []
 | 
			
		||||
									: Object.values(history.messages)
 | 
			
		||||
											.filter((message) => message.parentId === null)
 | 
			
		||||
											.map((message) => message.id) ?? []}
 | 
			
		||||
								{confirmEditMessage}
 | 
			
		||||
								{showPreviousMessage}
 | 
			
		||||
								{showNextMessage}
 | 
			
		||||
								{copyToClipboard}
 | 
			
		||||
							/>
 | 
			
		||||
				{#if !message.deleted}
 | 
			
		||||
					<div class=" w-full">
 | 
			
		||||
						<div
 | 
			
		||||
							class="flex flex-col justify-between px-5 mb-3 {$settings?.fullScreenMode ?? null
 | 
			
		||||
								? 'max-w-full'
 | 
			
		||||
								: 'max-w-3xl'} mx-auto rounded-lg group"
 | 
			
		||||
						>
 | 
			
		||||
							{#if message.role === 'user'}
 | 
			
		||||
								<UserMessage
 | 
			
		||||
									on:delete={() => messageDeleteHandler(message.id)}
 | 
			
		||||
									user={$user}
 | 
			
		||||
									{message}
 | 
			
		||||
									isFirstMessage={messageIdx === 0}
 | 
			
		||||
									siblings={message.parentId !== null
 | 
			
		||||
										? history.messages[message.parentId]?.childrenIds ?? []
 | 
			
		||||
										: Object.values(history.messages)
 | 
			
		||||
												.filter((message) => message.parentId === null)
 | 
			
		||||
												.map((message) => message.id) ?? []}
 | 
			
		||||
									{confirmEditMessage}
 | 
			
		||||
									{showPreviousMessage}
 | 
			
		||||
									{showNextMessage}
 | 
			
		||||
									{copyToClipboard}
 | 
			
		||||
								/>
 | 
			
		||||
 | 
			
		||||
							{#if messages.length - 1 === messageIdx && processing !== ''}
 | 
			
		||||
								<div class="flex my-2.5 ml-12 items-center w-fit space-x-2.5">
 | 
			
		||||
									<div class=" dark:text-blue-100">
 | 
			
		||||
										<svg
 | 
			
		||||
											class=" w-4 h-4 translate-y-[0.5px]"
 | 
			
		||||
											fill="currentColor"
 | 
			
		||||
											viewBox="0 0 24 24"
 | 
			
		||||
											xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
											><style>
 | 
			
		||||
												.spinner_qM83 {
 | 
			
		||||
													animation: spinner_8HQG 1.05s infinite;
 | 
			
		||||
												}
 | 
			
		||||
												.spinner_oXPr {
 | 
			
		||||
													animation-delay: 0.1s;
 | 
			
		||||
												}
 | 
			
		||||
												.spinner_ZTLf {
 | 
			
		||||
													animation-delay: 0.2s;
 | 
			
		||||
												}
 | 
			
		||||
												@keyframes spinner_8HQG {
 | 
			
		||||
													0%,
 | 
			
		||||
													57.14% {
 | 
			
		||||
														animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
 | 
			
		||||
														transform: translate(0);
 | 
			
		||||
								{#if messages.length - 1 === messageIdx && processing !== ''}
 | 
			
		||||
									<div class="flex my-2.5 ml-12 items-center w-fit space-x-2.5">
 | 
			
		||||
										<div class=" dark:text-blue-100">
 | 
			
		||||
											<svg
 | 
			
		||||
												class=" w-4 h-4 translate-y-[0.5px]"
 | 
			
		||||
												fill="currentColor"
 | 
			
		||||
												viewBox="0 0 24 24"
 | 
			
		||||
												xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
												><style>
 | 
			
		||||
													.spinner_qM83 {
 | 
			
		||||
														animation: spinner_8HQG 1.05s infinite;
 | 
			
		||||
													}
 | 
			
		||||
													28.57% {
 | 
			
		||||
														animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
 | 
			
		||||
														transform: translateY(-6px);
 | 
			
		||||
													.spinner_oXPr {
 | 
			
		||||
														animation-delay: 0.1s;
 | 
			
		||||
													}
 | 
			
		||||
													100% {
 | 
			
		||||
														transform: translate(0);
 | 
			
		||||
													.spinner_ZTLf {
 | 
			
		||||
														animation-delay: 0.2s;
 | 
			
		||||
													}
 | 
			
		||||
												}
 | 
			
		||||
											</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle
 | 
			
		||||
												class="spinner_qM83 spinner_oXPr"
 | 
			
		||||
												cx="12"
 | 
			
		||||
												cy="12"
 | 
			
		||||
												r="2.5"
 | 
			
		||||
											/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="2.5" /></svg
 | 
			
		||||
										>
 | 
			
		||||
													@keyframes spinner_8HQG {
 | 
			
		||||
														0%,
 | 
			
		||||
														57.14% {
 | 
			
		||||
															animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
 | 
			
		||||
															transform: translate(0);
 | 
			
		||||
														}
 | 
			
		||||
														28.57% {
 | 
			
		||||
															animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
 | 
			
		||||
															transform: translateY(-6px);
 | 
			
		||||
														}
 | 
			
		||||
														100% {
 | 
			
		||||
															transform: translate(0);
 | 
			
		||||
														}
 | 
			
		||||
													}
 | 
			
		||||
												</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle
 | 
			
		||||
													class="spinner_qM83 spinner_oXPr"
 | 
			
		||||
													cx="12"
 | 
			
		||||
													cy="12"
 | 
			
		||||
													r="2.5"
 | 
			
		||||
												/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="2.5" /></svg
 | 
			
		||||
											>
 | 
			
		||||
										</div>
 | 
			
		||||
										<div class=" text-sm font-medium">
 | 
			
		||||
											{processing}
 | 
			
		||||
										</div>
 | 
			
		||||
									</div>
 | 
			
		||||
									<div class=" text-sm font-medium">
 | 
			
		||||
										{processing}
 | 
			
		||||
									</div>
 | 
			
		||||
								</div>
 | 
			
		||||
								{/if}
 | 
			
		||||
							{:else}
 | 
			
		||||
								<ResponseMessage
 | 
			
		||||
									{message}
 | 
			
		||||
									modelfiles={selectedModelfiles}
 | 
			
		||||
									siblings={history.messages[message.parentId]?.childrenIds ?? []}
 | 
			
		||||
									isLastMessage={messageIdx + 1 === messages.length}
 | 
			
		||||
									{confirmEditResponseMessage}
 | 
			
		||||
									{showPreviousMessage}
 | 
			
		||||
									{showNextMessage}
 | 
			
		||||
									{rateMessage}
 | 
			
		||||
									{copyToClipboard}
 | 
			
		||||
									{continueGeneration}
 | 
			
		||||
									{regenerateResponse}
 | 
			
		||||
									on:save={async (e) => {
 | 
			
		||||
										console.log('save', e);
 | 
			
		||||
 | 
			
		||||
										const message = e.detail;
 | 
			
		||||
										history.messages[message.id] = message;
 | 
			
		||||
										await updateChatById(localStorage.token, chatId, {
 | 
			
		||||
											messages: messages,
 | 
			
		||||
											history: history
 | 
			
		||||
										});
 | 
			
		||||
									}}
 | 
			
		||||
								/>
 | 
			
		||||
							{/if}
 | 
			
		||||
						{:else}
 | 
			
		||||
							<ResponseMessage
 | 
			
		||||
								{message}
 | 
			
		||||
								modelfiles={selectedModelfiles}
 | 
			
		||||
								siblings={history.messages[message.parentId]?.childrenIds ?? []}
 | 
			
		||||
								isLastMessage={messageIdx + 1 === messages.length}
 | 
			
		||||
								{confirmEditResponseMessage}
 | 
			
		||||
								{showPreviousMessage}
 | 
			
		||||
								{showNextMessage}
 | 
			
		||||
								{rateMessage}
 | 
			
		||||
								{copyToClipboard}
 | 
			
		||||
								{continueGeneration}
 | 
			
		||||
								{regenerateResponse}
 | 
			
		||||
								on:save={async (e) => {
 | 
			
		||||
									console.log('save', e);
 | 
			
		||||
 | 
			
		||||
									const message = e.detail;
 | 
			
		||||
									history.messages[message.id] = message;
 | 
			
		||||
									await updateChatById(localStorage.token, chatId, {
 | 
			
		||||
										messages: messages,
 | 
			
		||||
										history: history
 | 
			
		||||
									});
 | 
			
		||||
								}}
 | 
			
		||||
							/>
 | 
			
		||||
						{/if}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				{/if}
 | 
			
		||||
			{/each}
 | 
			
		||||
 | 
			
		||||
			{#if bottomPadding}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
	import ProfileImage from './ProfileImage.svelte';
 | 
			
		||||
	import Skeleton from './Skeleton.svelte';
 | 
			
		||||
	import CodeBlock from './CodeBlock.svelte';
 | 
			
		||||
	import Image from '$lib/components/common/Image.svelte';
 | 
			
		||||
 | 
			
		||||
	export let modelfiles = [];
 | 
			
		||||
	export let message;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,6 @@
 | 
			
		|||
	let speakingIdx = null;
 | 
			
		||||
 | 
			
		||||
	let loadingSpeech = false;
 | 
			
		||||
 | 
			
		||||
	let generatingImage = false;
 | 
			
		||||
 | 
			
		||||
	$: tokens = marked.lexer(message.content);
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +323,7 @@
 | 
			
		|||
						{#each message.files as file}
 | 
			
		||||
							<div>
 | 
			
		||||
								{#if file.type === 'image'}
 | 
			
		||||
									<img src={file.url} alt="input" class=" max-h-96 rounded-lg" draggable="false" />
 | 
			
		||||
									<Image src={file.url} />
 | 
			
		||||
								{/if}
 | 
			
		||||
							</div>
 | 
			
		||||
						{/each}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,17 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import dayjs from 'dayjs';
 | 
			
		||||
 | 
			
		||||
	import { tick } from 'svelte';
 | 
			
		||||
	import { tick, createEventDispatcher } from 'svelte';
 | 
			
		||||
	import Name from './Name.svelte';
 | 
			
		||||
	import ProfileImage from './ProfileImage.svelte';
 | 
			
		||||
	import { modelfiles, settings } from '$lib/stores';
 | 
			
		||||
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
	export let user;
 | 
			
		||||
	export let message;
 | 
			
		||||
	export let siblings;
 | 
			
		||||
	export let isFirstMessage: boolean;
 | 
			
		||||
 | 
			
		||||
	export let confirmEditMessage: Function;
 | 
			
		||||
	export let showPreviousMessage: Function;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +45,10 @@
 | 
			
		|||
		edit = false;
 | 
			
		||||
		editedContent = '';
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const deleteMessageHandler = async () => {
 | 
			
		||||
		dispatch('delete', message.id);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div class=" flex w-full">
 | 
			
		||||
| 
						 | 
				
			
			@ -189,11 +196,11 @@
 | 
			
		|||
				<div class="w-full">
 | 
			
		||||
					<pre id="user-message">{message.content}</pre>
 | 
			
		||||
 | 
			
		||||
					<div class=" flex justify-start space-x-1">
 | 
			
		||||
					<div class=" flex justify-start space-x-1 text-gray-700 dark:text-gray-500">
 | 
			
		||||
						{#if siblings.length > 1}
 | 
			
		||||
							<div class="flex self-center">
 | 
			
		||||
								<button
 | 
			
		||||
									class="self-center"
 | 
			
		||||
									class="self-center dark:hover:text-white hover:text-black transition"
 | 
			
		||||
									on:click={() => {
 | 
			
		||||
										showPreviousMessage(message);
 | 
			
		||||
									}}
 | 
			
		||||
| 
						 | 
				
			
			@ -212,12 +219,12 @@
 | 
			
		|||
									</svg>
 | 
			
		||||
								</button>
 | 
			
		||||
 | 
			
		||||
								<div class="text-xs font-bold self-center">
 | 
			
		||||
								<div class="text-xs font-bold self-center dark:text-gray-100">
 | 
			
		||||
									{siblings.indexOf(message.id) + 1} / {siblings.length}
 | 
			
		||||
								</div>
 | 
			
		||||
 | 
			
		||||
								<button
 | 
			
		||||
									class="self-center"
 | 
			
		||||
									class="self-center dark:hover:text-white hover:text-black transition"
 | 
			
		||||
									on:click={() => {
 | 
			
		||||
										showNextMessage(message);
 | 
			
		||||
									}}
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +246,7 @@
 | 
			
		|||
						{/if}
 | 
			
		||||
 | 
			
		||||
						<button
 | 
			
		||||
							class="invisible group-hover:visible p-1 rounded dark:hover:text-white transition edit-user-message-button"
 | 
			
		||||
							class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition edit-user-message-button"
 | 
			
		||||
							on:click={() => {
 | 
			
		||||
								editMessageHandler();
 | 
			
		||||
							}}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +268,7 @@
 | 
			
		|||
						</button>
 | 
			
		||||
 | 
			
		||||
						<button
 | 
			
		||||
							class="invisible group-hover:visible p-1 rounded dark:hover:text-white transition"
 | 
			
		||||
							class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition"
 | 
			
		||||
							on:click={() => {
 | 
			
		||||
								copyToClipboard(message.content);
 | 
			
		||||
							}}
 | 
			
		||||
| 
						 | 
				
			
			@ -281,6 +288,30 @@
 | 
			
		|||
								/>
 | 
			
		||||
							</svg>
 | 
			
		||||
						</button>
 | 
			
		||||
 | 
			
		||||
						{#if !isFirstMessage}
 | 
			
		||||
							<button
 | 
			
		||||
								class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition"
 | 
			
		||||
								on:click={() => {
 | 
			
		||||
									deleteMessageHandler();
 | 
			
		||||
								}}
 | 
			
		||||
							>
 | 
			
		||||
								<svg
 | 
			
		||||
									xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
									fill="none"
 | 
			
		||||
									viewBox="0 0 24 24"
 | 
			
		||||
									stroke-width="1.5"
 | 
			
		||||
									stroke="currentColor"
 | 
			
		||||
									class="w-4 h-4"
 | 
			
		||||
								>
 | 
			
		||||
									<path
 | 
			
		||||
										stroke-linecap="round"
 | 
			
		||||
										stroke-linejoin="round"
 | 
			
		||||
										d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
 | 
			
		||||
									/>
 | 
			
		||||
								</svg>
 | 
			
		||||
							</button>
 | 
			
		||||
						{/if}
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			{/if}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
			</div>
 | 
			
		||||
			<div class="flex w-full">
 | 
			
		||||
				<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
 | 
			
		||||
					{WEB_UI_VERSION}
 | 
			
		||||
					v{WEB_UI_VERSION}
 | 
			
		||||
 | 
			
		||||
					<button
 | 
			
		||||
						class="mt-1 underline flex items-center space-x-1 text-xs text-gray-600 dark:text-gray-400"
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +57,13 @@
 | 
			
		|||
				/>
 | 
			
		||||
			</a>
 | 
			
		||||
 | 
			
		||||
			<a href="https://twitter.com/OpenWebUI" target="_blank">
 | 
			
		||||
				<img
 | 
			
		||||
					alt="X (formerly Twitter) Follow"
 | 
			
		||||
					src="https://img.shields.io/twitter/follow/OpenWebUI"
 | 
			
		||||
				/>
 | 
			
		||||
			</a>
 | 
			
		||||
 | 
			
		||||
			<a href="https://github.com/open-webui/open-webui" target="_blank">
 | 
			
		||||
				<img
 | 
			
		||||
					alt="Github Repo"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,9 +8,11 @@
 | 
			
		|||
		getDefaultDiffusionModel,
 | 
			
		||||
		getDiffusionModels,
 | 
			
		||||
		getImageGenerationEnabledStatus,
 | 
			
		||||
		getImageSize,
 | 
			
		||||
		toggleImageGenerationEnabledStatus,
 | 
			
		||||
		updateAUTOMATIC1111Url,
 | 
			
		||||
		updateDefaultDiffusionModel
 | 
			
		||||
		updateDefaultDiffusionModel,
 | 
			
		||||
		updateImageSize
 | 
			
		||||
	} from '$lib/apis/images';
 | 
			
		||||
	import { getBackendConfig } from '$lib/apis';
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +27,8 @@
 | 
			
		|||
	let selectedModel = '';
 | 
			
		||||
	let models = [];
 | 
			
		||||
 | 
			
		||||
	let imageSize = '';
 | 
			
		||||
 | 
			
		||||
	const getModels = async () => {
 | 
			
		||||
		models = await getDiffusionModels(localStorage.token).catch((error) => {
 | 
			
		||||
			toast.error(error);
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +57,6 @@
 | 
			
		|||
			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const toggleImageGeneration = async () => {
 | 
			
		||||
		if (AUTOMATIC1111_BASE_URL) {
 | 
			
		||||
			enableImageGeneration = await toggleImageGenerationEnabledStatus(localStorage.token).catch(
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +82,7 @@
 | 
			
		|||
			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token);
 | 
			
		||||
 | 
			
		||||
			if (enableImageGeneration && AUTOMATIC1111_BASE_URL) {
 | 
			
		||||
				imageSize = await getImageSize(localStorage.token);
 | 
			
		||||
				getModels();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -89,13 +93,17 @@
 | 
			
		|||
	class="flex flex-col h-full justify-between space-y-3 text-sm"
 | 
			
		||||
	on:submit|preventDefault={async () => {
 | 
			
		||||
		loading = true;
 | 
			
		||||
		const res = await updateDefaultDiffusionModel(localStorage.token, selectedModel);
 | 
			
		||||
		await updateDefaultDiffusionModel(localStorage.token, selectedModel);
 | 
			
		||||
		await updateImageSize(localStorage.token, imageSize).catch((error) => {
 | 
			
		||||
			toast.error(error);
 | 
			
		||||
			return null;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		dispatch('save');
 | 
			
		||||
		loading = false;
 | 
			
		||||
	}}
 | 
			
		||||
>
 | 
			
		||||
	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
 | 
			
		||||
	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-[21rem]">
 | 
			
		||||
		<div>
 | 
			
		||||
			<div class=" mb-1 text-sm font-medium">Image Settings</div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +177,7 @@
 | 
			
		|||
			<hr class=" dark:border-gray-700" />
 | 
			
		||||
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" mb-2.5 text-sm font-medium">Set default model</div>
 | 
			
		||||
				<div class=" mb-2.5 text-sm font-medium">Set Default Model</div>
 | 
			
		||||
				<div class="flex w-full">
 | 
			
		||||
					<div class="flex-1 mr-2">
 | 
			
		||||
						<select
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +197,19 @@
 | 
			
		|||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" mb-2.5 text-sm font-medium">Set Image Size</div>
 | 
			
		||||
				<div class="flex w-full">
 | 
			
		||||
					<div class="flex-1 mr-2">
 | 
			
		||||
						<input
 | 
			
		||||
							class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
 | 
			
		||||
							placeholder="Enter Image Size (e.g. 512x512)"
 | 
			
		||||
							bind:value={imageSize}
 | 
			
		||||
						/>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue