diff options
Diffstat (limited to '')
-rw-r--r-- | g4f/gui/client/static/js/chat.v1.js | 143 |
1 files changed, 86 insertions, 57 deletions
diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index 628d0682..68800bdd 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -10,13 +10,14 @@ const sendButton = document.getElementById("send-button"); const imageInput = document.getElementById("image"); const cameraInput = document.getElementById("camera"); const fileInput = document.getElementById("file"); -const microLabel = document.querySelector(".micro-label") -const inputCount = document.getElementById("input-count") +const microLabel = document.querySelector(".micro-label"); +const inputCount = document.getElementById("input-count"); const providerSelect = document.getElementById("provider"); const modelSelect = document.getElementById("model"); const modelProvider = document.getElementById("model2"); -const systemPrompt = document.getElementById("systemPrompt") -const settings = document.querySelector(".settings") +const systemPrompt = document.getElementById("systemPrompt"); +const settings = document.querySelector(".settings"); +const album = document.querySelector(".images"); let prompt_lock = false; @@ -49,6 +50,12 @@ const markdown_render = (content) => { .replaceAll('<code>', '<code class="language-plaintext">') } +function filter_message(text) { + return text.replaceAll( + /<!-- generated images start -->[\s\S]+<!-- generated images end -->/gm, "" + ) +} + hljs.addPlugin(new CopyButtonPlugin()); let typesetPromise = Promise.resolve(); const highlight = (container) => { @@ -64,7 +71,6 @@ const highlight = (container) => { ); } -let stopped = false; const register_message_buttons = async () => { document.querySelectorAll(".message .fa-xmark").forEach(async (el) => { if (!("click" in el.dataset)) { @@ -95,69 +101,76 @@ const register_message_buttons = async () => { if (!("click" in el.dataset)) { el.dataset.click = "true"; el.addEventListener("click", async () => { - if ("active" in el.classList || window.doSpeech) { - el.classList.add("blink") - stopped = true; - return; + let playlist = []; + function play_next() { + const next = playlist.shift(); + if (next) + next.play(); } - if (stopped) { + if (el.dataset.stopped) { el.classList.remove("blink") - stopped = false; + delete el.dataset.stopped; + return; + } + if (el.dataset.running) { + el.dataset.stopped = true; + el.classList.add("blink") + playlist = []; return; } + el.dataset.running = true; el.classList.add("blink") el.classList.add("active") - const message_el = el.parentElement.parentElement.parentElement; const content_el = el.parentElement.parentElement; + const message_el = content_el.parentElement; let speechText = await get_message(window.conversation_id, message_el.dataset.index); + speechText = speechText.replaceAll(/([^0-9])\./gm, "$1.;"); + speechText = speechText.replaceAll("?", "?;"); speechText = speechText.replaceAll(/\[(.+)\]\(.+\)/gm, "($1)"); - speechText = speechText.replaceAll("`", "").replaceAll("#", "") - speechText = speechText.replaceAll( - /<!-- generated images start -->[\s\S]+<!-- generated images end -->/gm, - "" - ) - - const lines = speechText.trim().split(/\n|\.|;/); - let ended = true; + speechText = speechText.replaceAll(/```[a-z]+/gm, ""); + speechText = filter_message(speechText.replaceAll("`", "").replaceAll("#", "")) + const lines = speechText.trim().split(/\n|;/).filter(v => v.trim()); + window.onSpeechResponse = (url) => { - el.classList.remove("blink") + if (!el.dataset.stopped) { + el.classList.remove("blink") + } if (url) { var sound = document.createElement('audio'); sound.controls = 'controls'; sound.src = url; sound.type = 'audio/wav'; sound.onended = function() { - ended = true; + el.dataset.do_play = true; + setTimeout(play_next, 1000); }; sound.onplay = function() { - ended = false; + delete el.dataset.do_play; }; var container = document.createElement('div'); container.classList.add("audio"); container.appendChild(sound); content_el.appendChild(container); - if (ended && !stopped) { - sound.play(); + if (!el.dataset.stopped) { + playlist.push(sound); + if (el.dataset.do_play) { + play_next(); + } } } - if (lines.length < 1 || stopped) { + let line = lines.length > 0 ? lines.shift() : null; + if (line && !el.dataset.stopped) { + handleGenerateSpeech(line); + } else { el.classList.remove("active"); - return; - } - while (lines.length > 0) { - let line = lines.shift(); - var reg = new RegExp('^[0-9]$'); - if (line && !reg.test(line)) { - return handleGenerateSpeech(line); - } - } - if (!line) { - el.classList.remove("active") + el.classList.remove("blink"); + delete el.dataset.running; } } + el.dataset.do_play = true; let line = lines.shift(); - return handleGenerateSpeech(line); + handleGenerateSpeech(line); }); } }); @@ -399,7 +412,7 @@ const ask_gpt = async () => { provider = "Bing"; let api_key = null; if (provider) - api_key = document.getElementById(`${provider}-api_key`)?.value; + api_key = document.getElementById(`${provider}-api_key`)?.value || null; await api("conversation", { id: window.token, conversation_id: window.conversation_id, @@ -717,7 +730,7 @@ const load_conversations = async () => { </div> `; }); - box_conversations.innerHTML = html; + box_conversations.innerHTML += html; }; document.getElementById("cancelButton").addEventListener("click", async () => { @@ -790,6 +803,17 @@ function open_settings() { } } +function open_album() { + if (album.classList.contains("hidden")) { + sidebar.classList.remove("shown"); + settings.classList.add("hidden"); + album.classList.remove("hidden"); + history.pushState({}, null, "/images/"); + } else { + album.classList.add("hidden"); + } +} + const register_settings_storage = async () => { optionElements.forEach((element) => { if (element.type == "textarea") { @@ -1232,12 +1256,12 @@ if (SpeechRecognition) { } let startValue; - let lastValue; let timeoutHandle; + let lastDebounceTranscript; recognition.onstart = function() { microLabel.classList.add("recognition"); startValue = messageInput.value; - lastValue = ""; + lastDebounceTranscript = ""; timeoutHandle = window.setTimeout(may_stop, 8000); }; recognition.onend = function() { @@ -1248,22 +1272,27 @@ if (SpeechRecognition) { return; } window.clearTimeout(timeoutHandle); - let newText; - Array.from(event.results).forEach((result) => { - newText = result[0].transcript; - if (newText && newText != lastValue) { - messageInput.value = `${startValue ? startValue+"\n" : ""}${newText.trim()}`; - if (result.isFinal) { - lastValue = newText; - startValue = messageInput.value; - messageInput.focus(); - } - messageInput.style.height = messageInput.scrollHeight + "px"; - messageInput.scrollTop = messageInput.scrollHeight; + + let result = event.results[event.resultIndex]; + let isFinal = result.isFinal && (result[0].confidence > 0); + let transcript = result[0].transcript; + if (isFinal) { + if(transcript == lastDebounceTranscript) { + return; } - }); - window.clearTimeout(timeoutHandle); - timeoutHandle = window.setTimeout(may_stop, newText ? 8000 : 5000); + lastDebounceTranscript = transcript; + } + if (transcript) { + messageInput.value = `${startValue ? startValue+"\n" : ""}${transcript.trim()}`; + if (isFinal) { + startValue = messageInput.value; + messageInput.focus(); + } + messageInput.style.height = messageInput.scrollHeight + "px"; + messageInput.scrollTop = messageInput.scrollHeight; + } + + timeoutHandle = window.setTimeout(may_stop, transcript ? 8000 : 5000); }; microLabel.addEventListener("click", () => { |