forked from open-webui/open-webui
		
	Merge pull request #1025 from Carlos-err406/fix/dom-queries
rf: less dom queries using bind:this
This commit is contained in:
		
						commit
						2d59847fb9
					
				
					 15 changed files with 87 additions and 82 deletions
				
			
		|  | @ -19,7 +19,7 @@ | |||
| 
 | ||||
| 	export let suggestionPrompts = []; | ||||
| 	export let autoScroll = true; | ||||
| 
 | ||||
| 	let chatTextAreaElement:HTMLTextAreaElement | ||||
| 	let filesInputElement; | ||||
| 
 | ||||
| 	let promptsElement; | ||||
|  | @ -43,11 +43,9 @@ | |||
| 	let speechRecognition; | ||||
| 
 | ||||
| 	$: if (prompt) { | ||||
| 		const chatInput = document.getElementById('chat-textarea'); | ||||
| 
 | ||||
| 		if (chatInput) { | ||||
| 			chatInput.style.height = ''; | ||||
| 			chatInput.style.height = Math.min(chatInput.scrollHeight, 200) + 'px'; | ||||
| 		if (chatTextAreaElement) { | ||||
| 			chatTextAreaElement.style.height = ''; | ||||
| 			chatTextAreaElement.style.height = Math.min(chatTextAreaElement.scrollHeight, 200) + 'px'; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -86,9 +84,7 @@ | |||
| 			if (res) { | ||||
| 				prompt = res.text; | ||||
| 				await tick(); | ||||
| 
 | ||||
| 				const inputElement = document.getElementById('chat-textarea'); | ||||
| 				inputElement?.focus(); | ||||
| 				chatTextAreaElement?.focus(); | ||||
| 
 | ||||
| 				if (prompt !== '' && $settings?.speechAutoSend === true) { | ||||
| 					submitPrompt(prompt, user); | ||||
|  | @ -191,8 +187,7 @@ | |||
| 						prompt = `${prompt}${transcript}`; | ||||
| 
 | ||||
| 						await tick(); | ||||
| 						const inputElement = document.getElementById('chat-textarea'); | ||||
| 						inputElement?.focus(); | ||||
| 						chatTextAreaElement?.focus(); | ||||
| 
 | ||||
| 						// Restart the inactivity timeout | ||||
| 						timeoutId = setTimeout(() => { | ||||
|  | @ -294,8 +289,7 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	onMount(() => { | ||||
| 		const chatInput = document.getElementById('chat-textarea'); | ||||
| 		window.setTimeout(() => chatInput?.focus(), 0); | ||||
| 		window.setTimeout(() => chatTextAreaElement?.focus(), 0); | ||||
| 
 | ||||
| 		const dropZone = document.querySelector('body'); | ||||
| 
 | ||||
|  | @ -663,6 +657,7 @@ | |||
| 
 | ||||
| 						<textarea | ||||
| 							id="chat-textarea" | ||||
| 							bind:this={chatTextAreaElement} | ||||
| 							class=" dark:bg-gray-900 dark:text-gray-100 outline-none w-full py-3 px-3 {fileUploadEnabled | ||||
| 								? '' | ||||
| 								: ' pl-4'} rounded-xl resize-none h-[48px]" | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ | |||
| 
 | ||||
| 	let edit = false; | ||||
| 	let editedContent = ''; | ||||
| 
 | ||||
| 	let editTextAreaElement: HTMLTextAreaElement; | ||||
| 	let tooltipInstance = null; | ||||
| 
 | ||||
| 	let sentencesAudio = {}; | ||||
|  | @ -247,10 +247,9 @@ | |||
| 		editedContent = message.content; | ||||
| 
 | ||||
| 		await tick(); | ||||
| 		const editElement = document.getElementById(`message-edit-${message.id}`); | ||||
| 
 | ||||
| 		editElement.style.height = ''; | ||||
| 		editElement.style.height = `${editElement.scrollHeight}px`; | ||||
| 		editTextAreaElement.style.height = ''; | ||||
| 		editTextAreaElement.style.height = `${editTextAreaElement.scrollHeight}px`; | ||||
| 	}; | ||||
| 
 | ||||
| 	const editMessageConfirmHandler = async () => { | ||||
|  | @ -341,6 +340,7 @@ | |||
| 							<div class=" w-full"> | ||||
| 								<textarea | ||||
| 									id="message-edit-{message.id}" | ||||
| 									bind:this={editTextAreaElement} | ||||
| 									class=" bg-transparent outline-none w-full resize-none" | ||||
| 									bind:value={editedContent} | ||||
| 									on:input={(e) => { | ||||
|  |  | |||
|  | @ -20,18 +20,17 @@ | |||
| 
 | ||||
| 	let edit = false; | ||||
| 	let editedContent = ''; | ||||
| 
 | ||||
| 	let messageEditTextAreaElement: HTMLTextAreaElement; | ||||
| 	const editMessageHandler = async () => { | ||||
| 		edit = true; | ||||
| 		editedContent = message.content; | ||||
| 
 | ||||
| 		await tick(); | ||||
| 		const editElement = document.getElementById(`message-edit-${message.id}`); | ||||
| 
 | ||||
| 		editElement.style.height = ''; | ||||
| 		editElement.style.height = `${editElement.scrollHeight}px`; | ||||
| 		messageEditTextAreaElement.style.height = ''; | ||||
| 		messageEditTextAreaElement.style.height = `${messageEditTextAreaElement.scrollHeight}px`; | ||||
| 
 | ||||
| 		editElement?.focus(); | ||||
| 		messageEditTextAreaElement?.focus(); | ||||
| 	}; | ||||
| 
 | ||||
| 	const editMessageConfirmHandler = async () => { | ||||
|  | @ -165,10 +164,11 @@ | |||
| 				<div class=" w-full"> | ||||
| 					<textarea | ||||
| 						id="message-edit-{message.id}" | ||||
| 						bind:this={messageEditTextAreaElement} | ||||
| 						class=" bg-transparent outline-none w-full resize-none" | ||||
| 						bind:value={editedContent} | ||||
| 						on:input={(e) => { | ||||
| 							e.target.style.height = `${e.target.scrollHeight}px`; | ||||
| 							messageEditTextAreaElement.style.height = `${messageEditTextAreaElement.scrollHeight}px`; | ||||
| 						}} | ||||
| 					/> | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ | |||
| 	let name = ''; | ||||
| 	let showJWTToken = false; | ||||
| 	let JWTTokenCopied = false; | ||||
| 	let profileImageInputElement: HTMLInputElement; | ||||
| 
 | ||||
| 	const submitHandler = async () => { | ||||
| 		const updatedUser = await updateUserProfile(localStorage.token, name, profileImageUrl).catch( | ||||
|  | @ -40,11 +41,12 @@ | |||
| 	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80"> | ||||
| 		<input | ||||
| 			id="profile-image-input" | ||||
| 			bind:this={profileImageInputElement} | ||||
| 			type="file" | ||||
| 			hidden | ||||
| 			accept="image/*" | ||||
| 			on:change={(e) => { | ||||
| 				const files = e?.target?.files ?? []; | ||||
| 				const files = profileImageInputElement.files ?? []; | ||||
| 				let reader = new FileReader(); | ||||
| 				reader.onload = (event) => { | ||||
| 					let originalImageUrl = `${event.target.result}`; | ||||
|  | @ -86,7 +88,7 @@ | |||
| 						// Display the compressed image | ||||
| 						profileImageUrl = compressedSrc; | ||||
| 
 | ||||
| 						e.target.files = null; | ||||
| 						profileImageInputElement.files = null; | ||||
| 					}; | ||||
| 				}; | ||||
| 
 | ||||
|  | @ -107,9 +109,7 @@ | |||
| 					<button | ||||
| 						class="relative rounded-full dark:bg-gray-700" | ||||
| 						type="button" | ||||
| 						on:click={() => { | ||||
| 							document.getElementById('profile-image-input')?.click(); | ||||
| 						}} | ||||
| 						on:click={profileImageInputElement.click} | ||||
| 					> | ||||
| 						<img | ||||
| 							src={profileImageUrl !== '' ? profileImageUrl : '/user.png'} | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ | |||
| 	let saveChatHistory = true; | ||||
| 	let importFiles; | ||||
| 	let showDeleteConfirm = false; | ||||
| 	let chatImportInputElement: HTMLInputElement; | ||||
| 
 | ||||
| 	$: if (importFiles) { | ||||
| 		console.log(importFiles); | ||||
|  | @ -159,12 +160,17 @@ | |||
| 		<hr class=" dark:border-gray-700" /> | ||||
| 
 | ||||
| 		<div class="flex flex-col"> | ||||
| 			<input id="chat-import-input" bind:files={importFiles} type="file" accept=".json" hidden /> | ||||
| 			<input | ||||
| 				id="chat-import-input" | ||||
| 				bind:this={chatImportInputElement} | ||||
| 				bind:files={importFiles} | ||||
| 				type="file" | ||||
| 				accept=".json" | ||||
| 				hidden | ||||
| 			/> | ||||
| 			<button | ||||
| 				class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition" | ||||
| 				on:click={() => { | ||||
| 					document.getElementById('chat-import-input').click(); | ||||
| 				}} | ||||
| 				on:click={chatImportInputElement.click} | ||||
| 			> | ||||
| 				<div class=" self-center mr-3"> | ||||
| 					<svg | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| 
 | ||||
| 	let showLiteLLM = false; | ||||
| 	let showLiteLLMParams = false; | ||||
| 
 | ||||
| 	let modelUploadInputElement: HTMLInputElement; | ||||
| 	let liteLLMModelInfo = []; | ||||
| 
 | ||||
| 	let liteLLMModel = ''; | ||||
|  | @ -546,6 +546,7 @@ | |||
| 									<div class="flex-1 {modelInputFile && modelInputFile.length > 0 ? 'mr-2' : ''}"> | ||||
| 										<input | ||||
| 											id="model-upload-input" | ||||
| 											bind:this={modelUploadInputElement} | ||||
| 											type="file" | ||||
| 											bind:files={modelInputFile} | ||||
| 											on:change={() => { | ||||
|  | @ -559,9 +560,7 @@ | |||
| 										<button | ||||
| 											type="button" | ||||
| 											class="w-full rounded text-left py-2 px-4 dark:text-gray-300 dark:bg-gray-850" | ||||
| 											on:click={() => { | ||||
| 												document.getElementById('model-upload-input').click(); | ||||
| 											}} | ||||
| 											on:click={modelUploadInputElement.click} | ||||
| 										> | ||||
| 											{#if modelInputFile && modelInputFile.length > 0} | ||||
| 												{modelInputFile[0].name} | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
| 
 | ||||
| 	export let show = false; | ||||
| 	export let selectedDoc; | ||||
| 
 | ||||
| 	let uploadDocInputElement: HTMLInputElement; | ||||
| 	let inputFiles; | ||||
| 	let tags = []; | ||||
| 
 | ||||
|  | @ -69,7 +69,7 @@ | |||
| 			} | ||||
| 
 | ||||
| 			inputFiles = null; | ||||
| 			document.getElementById('upload-doc-input').value = ''; | ||||
| 			uploadDocInputElement.value = ''; | ||||
| 		} else { | ||||
| 			toast.error(`File not found.`); | ||||
| 		} | ||||
|  | @ -126,14 +126,19 @@ | |||
| 					}} | ||||
| 				> | ||||
| 					<div class="mb-3 w-full"> | ||||
| 						<input id="upload-doc-input" hidden bind:files={inputFiles} type="file" multiple /> | ||||
| 						<input | ||||
| 							id="upload-doc-input" | ||||
| 							bind:this={uploadDocInputElement} | ||||
| 							hidden | ||||
| 							bind:files={inputFiles} | ||||
| 							type="file" | ||||
| 							multiple | ||||
| 						/> | ||||
| 
 | ||||
| 						<button | ||||
| 							class="w-full text-sm font-medium py-3 bg-gray-850 hover:bg-gray-800 text-center rounded-xl" | ||||
| 							type="button" | ||||
| 							on:click={() => { | ||||
| 								document.getElementById('upload-doc-input')?.click(); | ||||
| 							}} | ||||
| 							on:click={uploadDocInputElement.click} | ||||
| 						> | ||||
| 							{#if inputFiles} | ||||
| 								{inputFiles.length > 0 ? `${inputFiles.length}` : ''} document(s) selected. | ||||
|  |  | |||
|  | @ -2,12 +2,11 @@ | |||
| 	import { onMount } from 'svelte'; | ||||
| 
 | ||||
| 	export let messages = []; | ||||
| 
 | ||||
| 	let textAreaElement: HTMLTextAreaElement; | ||||
| 	onMount(() => { | ||||
| 		messages.forEach((message, idx) => { | ||||
| 			let textareaElement = document.getElementById(`${message.role}-${idx}-textarea`); | ||||
| 			textareaElement.style.height = ''; | ||||
| 			textareaElement.style.height = textareaElement.scrollHeight + 'px'; | ||||
| 			textAreaElement.style.height = ''; | ||||
| 			textAreaElement.style.height = textAreaElement.scrollHeight + 'px'; | ||||
| 		}); | ||||
| 	}); | ||||
| </script> | ||||
|  | @ -27,16 +26,17 @@ | |||
| 			<div class="flex-1"> | ||||
| 				<textarea | ||||
| 					id="{message.role}-{idx}-textarea" | ||||
| 					bind:this={textAreaElement} | ||||
| 					class="w-full bg-transparent outline-none rounded-lg p-2 text-sm resize-none overflow-hidden" | ||||
| 					placeholder="Enter {message.role === 'user' ? 'a user' : 'an assistant'} message here" | ||||
| 					rows="1" | ||||
| 					on:input={(e) => { | ||||
| 						e.target.style.height = ''; | ||||
| 						e.target.style.height = e.target.scrollHeight + 'px'; | ||||
| 						textAreaElement.style.height = ''; | ||||
| 						textAreaElement.style.height = textAreaElement.scrollHeight + 'px'; | ||||
| 					}} | ||||
| 					on:focus={(e) => { | ||||
| 						e.target.style.height = ''; | ||||
| 						e.target.style.height = e.target.scrollHeight + 'px'; | ||||
| 						textAreaElement.style.height = ''; | ||||
| 						textAreaElement.style.height = textAreaElement.scrollHeight + 'px'; | ||||
| 
 | ||||
| 						// e.target.style.height = Math.min(e.target.scrollHeight, 200) + 'px'; | ||||
| 					}} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek