mirror of
https://github.com/open-webui/open-webui
synced 2024-11-07 17:19:53 +00:00
refac: voice call tap to interrupt
This commit is contained in:
parent
e183b0e5ff
commit
ad2ffc33d8
@ -31,6 +31,7 @@
|
|||||||
let loading = false;
|
let loading = false;
|
||||||
let confirmed = false;
|
let confirmed = false;
|
||||||
let interrupted = false;
|
let interrupted = false;
|
||||||
|
let assistantSpeaking = false;
|
||||||
|
|
||||||
let emoji = null;
|
let emoji = null;
|
||||||
|
|
||||||
@ -268,6 +269,14 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (assistantSpeaking) {
|
||||||
|
analyser.maxDecibels = 0;
|
||||||
|
analyser.minDecibels = -10;
|
||||||
|
} else {
|
||||||
|
analyser.minDecibels = MIN_DECIBELS;
|
||||||
|
analyser.maxDecibels = -30;
|
||||||
|
}
|
||||||
|
|
||||||
analyser.getByteTimeDomainData(timeDomainData);
|
analyser.getByteTimeDomainData(timeDomainData);
|
||||||
analyser.getByteFrequencyData(domainData);
|
analyser.getByteFrequencyData(domainData);
|
||||||
|
|
||||||
@ -379,6 +388,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const stopAllAudio = async () => {
|
const stopAllAudio = async () => {
|
||||||
|
assistantSpeaking = false;
|
||||||
interrupted = true;
|
interrupted = true;
|
||||||
|
|
||||||
if (chatStreaming) {
|
if (chatStreaming) {
|
||||||
@ -485,6 +495,7 @@
|
|||||||
}
|
}
|
||||||
} else if (finishedMessages[id] && messages[id] && messages[id].length === 0) {
|
} else if (finishedMessages[id] && messages[id] && messages[id].length === 0) {
|
||||||
// If the message is finished and there are no more messages to process, break the loop
|
// If the message is finished and there are no more messages to process, break the loop
|
||||||
|
assistantSpeaking = false;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// No messages to process, sleep for a bit
|
// No messages to process, sleep for a bit
|
||||||
@ -511,6 +522,7 @@
|
|||||||
}
|
}
|
||||||
audioAbortController = new AbortController();
|
audioAbortController = new AbortController();
|
||||||
|
|
||||||
|
assistantSpeaking = true;
|
||||||
// Start monitoring and playing audio for the message ID
|
// Start monitoring and playing audio for the message ID
|
||||||
monitorAndPlayAudio(id, audioAbortController.signal);
|
monitorAndPlayAudio(id, audioAbortController.signal);
|
||||||
}
|
}
|
||||||
@ -545,9 +557,9 @@
|
|||||||
const chatFinishHandler = async (e) => {
|
const chatFinishHandler = async (e) => {
|
||||||
const { id, content } = e.detail;
|
const { id, content } = e.detail;
|
||||||
// "content" here is the entire message from the assistant
|
// "content" here is the entire message from the assistant
|
||||||
|
finishedMessages[id] = true;
|
||||||
|
|
||||||
chatStreaming = false;
|
chatStreaming = false;
|
||||||
finishedMessages[id] = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
eventTarget.addEventListener('chat:start', chatStartHandler);
|
eventTarget.addEventListener('chat:start', chatStartHandler);
|
||||||
@ -577,7 +589,15 @@
|
|||||||
>
|
>
|
||||||
<div class="max-w-lg w-full h-screen max-h-[100dvh] flex flex-col justify-between p-3 md:p-6">
|
<div class="max-w-lg w-full h-screen max-h-[100dvh] flex flex-col justify-between p-3 md:p-6">
|
||||||
{#if camera}
|
{#if camera}
|
||||||
<div class="flex justify-center items-center w-full h-20 min-h-20">
|
<button
|
||||||
|
type="button"
|
||||||
|
class="flex justify-center items-center w-full h-20 min-h-20"
|
||||||
|
on:click={() => {
|
||||||
|
if (assistantSpeaking) {
|
||||||
|
stopAllAudio();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
{#if emoji}
|
{#if emoji}
|
||||||
<div
|
<div
|
||||||
class=" transition-all rounded-full"
|
class=" transition-all rounded-full"
|
||||||
@ -640,11 +660,19 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
<!-- navbar -->
|
<!-- navbar -->
|
||||||
</div>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex justify-center items-center flex-1 h-full w-full max-h-full">
|
<div class="flex justify-center items-center flex-1 h-full w-full max-h-full">
|
||||||
{#if !camera}
|
{#if !camera}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
if (assistantSpeaking) {
|
||||||
|
stopAllAudio();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
{#if emoji}
|
{#if emoji}
|
||||||
<div
|
<div
|
||||||
class=" transition-all rounded-full"
|
class=" transition-all rounded-full"
|
||||||
@ -706,6 +734,7 @@
|
|||||||
: 'size-44'} transition-all bg-black dark:bg-white rounded-full"
|
: 'size-44'} transition-all bg-black dark:bg-white rounded-full"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
class="relative flex video-container w-full max-h-full pt-2 pb-4 md:py-6 px-2 h-full"
|
class="relative flex video-container w-full max-h-full pt-2 pb-4 md:py-6 px-2 h-full"
|
||||||
@ -805,10 +834,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="button">
|
<button
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
if (assistantSpeaking) {
|
||||||
|
stopAllAudio();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div class=" line-clamp-1 text-sm font-medium">
|
<div class=" line-clamp-1 text-sm font-medium">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
{$i18n.t('Thinking...')}
|
{$i18n.t('Thinking...')}
|
||||||
|
{:else if assistantSpeaking}
|
||||||
|
{$i18n.t('Tap to interrupt')}
|
||||||
{:else}
|
{:else}
|
||||||
{$i18n.t('Listening...')}
|
{$i18n.t('Listening...')}
|
||||||
{/if}
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user