forked from open-webui/open-webui
		
	feat: tts automatic playback
This commit is contained in:
		
							parent
							
								
									ab3e0635bb
								
							
						
					
					
						commit
						5eff0e5f61
					
				
					 5 changed files with 93 additions and 46 deletions
				
			
		| 
						 | 
				
			
			@ -458,6 +458,7 @@
 | 
			
		|||
										</button>
 | 
			
		||||
 | 
			
		||||
										<button
 | 
			
		||||
											id="speak-button-{message.id}"
 | 
			
		||||
											class="{isLastMessage
 | 
			
		||||
												? 'visible'
 | 
			
		||||
												: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white transition"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,6 @@
 | 
			
		|||
 | 
			
		||||
	// Addons
 | 
			
		||||
	let titleAutoGenerate = true;
 | 
			
		||||
	let speechAutoSend = false;
 | 
			
		||||
	let responseAutoCopy = false;
 | 
			
		||||
	let titleAutoGenerateModel = '';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,12 +22,6 @@
 | 
			
		|||
		saveSettings({ showUsername: showUsername });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	const toggleSpeechAutoSend = async () => {
 | 
			
		||||
		speechAutoSend = !speechAutoSend;
 | 
			
		||||
		saveSettings({ speechAutoSend: speechAutoSend });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const toggleTitleAutoGenerate = async () => {
 | 
			
		||||
		titleAutoGenerate = !titleAutoGenerate;
 | 
			
		||||
		saveSettings({ titleAutoGenerate: titleAutoGenerate });
 | 
			
		||||
| 
						 | 
				
			
			@ -107,26 +100,6 @@
 | 
			
		|||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
					<div class=" self-center text-xs font-medium">Voice Input Auto-Send</div>
 | 
			
		||||
 | 
			
		||||
					<button
 | 
			
		||||
						class="p-1 px-3 text-xs flex rounded transition"
 | 
			
		||||
						on:click={() => {
 | 
			
		||||
							toggleSpeechAutoSend();
 | 
			
		||||
						}}
 | 
			
		||||
						type="button"
 | 
			
		||||
					>
 | 
			
		||||
						{#if speechAutoSend === true}
 | 
			
		||||
							<span class="ml-2 self-center">On</span>
 | 
			
		||||
						{:else}
 | 
			
		||||
							<span class="ml-2 self-center">Off</span>
 | 
			
		||||
						{/if}
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
					<div class=" self-center text-xs font-medium">Response AutoCopy to Clipboard</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -146,9 +119,12 @@
 | 
			
		|||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
					<div class=" self-center text-xs font-medium">Display the username instead of "You" in the Chat</div>
 | 
			
		||||
					<div class=" self-center text-xs font-medium">
 | 
			
		||||
						Display the username instead of "You" in the Chat
 | 
			
		||||
					</div>
 | 
			
		||||
 | 
			
		||||
					<button
 | 
			
		||||
						class="p-1 px-3 text-xs flex rounded transition"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,10 @@
 | 
			
		|||
	export let saveSettings: Function;
 | 
			
		||||
 | 
			
		||||
	// Voice
 | 
			
		||||
 | 
			
		||||
	let speechAutoSend = false;
 | 
			
		||||
	let responseAutoPlayback = false;
 | 
			
		||||
 | 
			
		||||
	let engines = ['', 'openai'];
 | 
			
		||||
	let engine = '';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +37,16 @@
 | 
			
		|||
		}, 100);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const toggleResponseAutoPlayback = async () => {
 | 
			
		||||
		responseAutoPlayback = !responseAutoPlayback;
 | 
			
		||||
		saveSettings({ responseAutoPlayback: responseAutoPlayback });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const toggleSpeechAutoSend = async () => {
 | 
			
		||||
		speechAutoSend = !speechAutoSend;
 | 
			
		||||
		saveSettings({ speechAutoSend: speechAutoSend });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	onMount(async () => {
 | 
			
		||||
		let settings = JSON.parse(localStorage.getItem('settings') ?? '{}');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,26 +74,66 @@
 | 
			
		|||
	}}
 | 
			
		||||
>
 | 
			
		||||
	<div class=" space-y-3">
 | 
			
		||||
		<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
			<div class=" self-center text-sm font-medium">Speech Engine</div>
 | 
			
		||||
			<div class="flex items-center relative">
 | 
			
		||||
				<select
 | 
			
		||||
					class="w-fit pr-8 rounded py-2 px-2 text-xs bg-transparent outline-none text-right"
 | 
			
		||||
					bind:value={engine}
 | 
			
		||||
					placeholder="Select a mode"
 | 
			
		||||
					on:change={(e) => {
 | 
			
		||||
						if (e.target.value === 'openai') {
 | 
			
		||||
							getOpenAIVoices();
 | 
			
		||||
							speaker = 'alloy';
 | 
			
		||||
						} else {
 | 
			
		||||
							getWebAPIVoices();
 | 
			
		||||
							speaker = '';
 | 
			
		||||
						}
 | 
			
		||||
		<div>
 | 
			
		||||
			<div class=" mb-1 text-sm font-medium">TTS Settings</div>
 | 
			
		||||
 | 
			
		||||
			<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
				<div class=" self-center text-xs font-medium">Speech Engine</div>
 | 
			
		||||
				<div class="flex items-center relative">
 | 
			
		||||
					<select
 | 
			
		||||
						class="w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
 | 
			
		||||
						bind:value={engine}
 | 
			
		||||
						placeholder="Select a mode"
 | 
			
		||||
						on:change={(e) => {
 | 
			
		||||
							if (e.target.value === 'openai') {
 | 
			
		||||
								getOpenAIVoices();
 | 
			
		||||
								speaker = 'alloy';
 | 
			
		||||
							} else {
 | 
			
		||||
								getWebAPIVoices();
 | 
			
		||||
								speaker = '';
 | 
			
		||||
							}
 | 
			
		||||
						}}
 | 
			
		||||
					>
 | 
			
		||||
						<option value="">Default (Web API)</option>
 | 
			
		||||
						<option value="openai">Open AI</option>
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
				<div class=" self-center text-xs font-medium">Voice Input Auto-Send</div>
 | 
			
		||||
 | 
			
		||||
				<button
 | 
			
		||||
					class="p-1 px-3 text-xs flex rounded transition"
 | 
			
		||||
					on:click={() => {
 | 
			
		||||
						toggleSpeechAutoSend();
 | 
			
		||||
					}}
 | 
			
		||||
					type="button"
 | 
			
		||||
				>
 | 
			
		||||
					<option value="">Default (Web API)</option>
 | 
			
		||||
					<option value="openai">Open AI</option>
 | 
			
		||||
				</select>
 | 
			
		||||
					{#if speechAutoSend === true}
 | 
			
		||||
						<span class="ml-2 self-center">On</span>
 | 
			
		||||
					{:else}
 | 
			
		||||
						<span class="ml-2 self-center">Off</span>
 | 
			
		||||
					{/if}
 | 
			
		||||
				</button>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
				<div class=" self-center text-xs font-medium">TTS Automatic Playback</div>
 | 
			
		||||
 | 
			
		||||
				<button
 | 
			
		||||
					class="p-1 px-3 text-xs flex rounded transition"
 | 
			
		||||
					on:click={() => {
 | 
			
		||||
						toggleResponseAutoPlayback();
 | 
			
		||||
					}}
 | 
			
		||||
					type="button"
 | 
			
		||||
				>
 | 
			
		||||
					{#if responseAutoPlayback === true}
 | 
			
		||||
						<span class="ml-2 self-center">On</span>
 | 
			
		||||
					{:else}
 | 
			
		||||
						<span class="ml-2 self-center">Off</span>
 | 
			
		||||
					{/if}
 | 
			
		||||
				</button>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue