diff options
| author | Michael Salaverry <barakplasma@gmail.com> | 2024-07-13 13:27:30 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-13 18:27:30 +0800 |
| commit | 571016096c1d403a0237d3fce322affe303c6ba1 (patch) | |
| tree | ac252abe18323fc3ee5811e23c1c7255564c196a /assets | |
| parent | 80d3edbd43e874bb30decf1c5d13834a9a896007 (diff) | |
| download | aichat-571016096c1d403a0237d3fce322affe303c6ba1.tar.gz | |
feat: webui supports text to speech for messages (#712)
Diffstat (limited to 'assets')
| -rw-r--r-- | assets/arena.html | 29 | ||||
| -rw-r--r-- | assets/playground.html | 29 |
2 files changed, 54 insertions, 4 deletions
diff --git a/assets/arena.html b/assets/arena.html index f0c93e5..1454448 100644 --- a/assets/arena.html +++ b/assets/arena.html @@ -174,7 +174,8 @@ } .copy-message-btn, - .regenerate-message-btn { + .regenerate-message-btn, + .tts-message-btn { top: 0.7rem; right: 0.7rem; cursor: pointer; @@ -183,7 +184,8 @@ } .copy-message-btn svg, - .regenerate-message-btn svg { + .regenerate-message-btn svg, + .tts-message-btn svg { width: 1rem; height: 1rem; } @@ -459,6 +461,16 @@ </svg> </div> </template> + <template + x-if="message.state == 'succeed' && !!window.speechSynthesis"> + <div class="tts-message-btn" @click="handleTTSMessage(message.content)" title="Text to speech"> + <svg fill="currentColor" viewBox="0 0 16 16"> + <path d="M11.536 14.01A8.47 8.47 0 0 0 14.026 8a8.47 8.47 0 0 0-2.49-6.01l-.708.707A7.48 7.48 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303z"/> + <path d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.48 5.48 0 0 1 11.025 8a5.48 5.48 0 0 1-1.61 3.89z"/> + <path d="M10.025 8a4.5 4.5 0 0 1-1.318 3.182L8 10.475A3.5 3.5 0 0 0 9.025 8c0-.966-.392-1.841-1.025-2.475l.707-.707A4.5 4.5 0 0 1 10.025 8M7 4a.5.5 0 0 0-.812-.39L3.825 5.5H1.5A.5.5 0 0 0 1 6v4a.5.5 0 0 0 .5.5h2.325l2.363 1.89A.5.5 0 0 0 7 12zM4.312 6.39 6 5.04v5.92L4.312 9.61A.5.5 0 0 0 4 9.5H2v-3h2a.5.5 0 0 0 .312-.11"/> + </svg> + </div> + </template> </div> </template> </div> @@ -658,6 +670,19 @@ this.ask(index); }, + /** + * @param {string} messageToUtter + */ + handleTTSMessage(messageToUtter) { + if (!!window.speechSynthesis) { + if (window.speechSynthesis.speaking || window.speechSynthesis.pending) { + window.speechSynthesis.cancel(); + } else { + let utterance = new SpeechSynthesisUtterance(messageToUtter); + window.speechSynthesis.speak(utterance); + } + } + }, handleCancelAsk() { for (const chat of this.chats) { diff --git a/assets/playground.html b/assets/playground.html index 72c1e3e..ec13133 100644 --- a/assets/playground.html +++ b/assets/playground.html @@ -251,7 +251,8 @@ } .copy-message-btn, - .regenerate-message-btn { + .regenerate-message-btn, + .tts-message-btn { top: 0.7rem; right: 0.7rem; cursor: pointer; @@ -260,7 +261,8 @@ } .copy-message-btn svg, - .regenerate-message-btn svg { + .regenerate-message-btn svg, + .tts-message-btn svg { width: 1rem; height: 1rem; } @@ -618,6 +620,16 @@ </svg> </div> </template> + <template + x-if="message.state == 'succeed' && !!window.speechSynthesis"> + <div class="tts-message-btn" @click="handleTTSMessage(message.content)" title="Text to speech"> + <svg fill="currentColor" viewBox="0 0 16 16"> + <path d="M11.536 14.01A8.47 8.47 0 0 0 14.026 8a8.47 8.47 0 0 0-2.49-6.01l-.708.707A7.48 7.48 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303z"/> + <path d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.48 5.48 0 0 1 11.025 8a5.48 5.48 0 0 1-1.61 3.89z"/> + <path d="M10.025 8a4.5 4.5 0 0 1-1.318 3.182L8 10.475A3.5 3.5 0 0 0 9.025 8c0-.966-.392-1.841-1.025-2.475l.707-.707A4.5 4.5 0 0 1 10.025 8M7 4a.5.5 0 0 0-.812-.39L3.825 5.5H1.5A.5.5 0 0 0 1 6v4a.5.5 0 0 0 .5.5h2.325l2.363 1.89A.5.5 0 0 0 7 12zM4.312 6.39 6 5.04v5.92L4.312 9.61A.5.5 0 0 0 4 9.5H2v-3h2a.5.5 0 0 0 .312-.11"/> + </svg> + </div> + </template> </div> </template> </div> @@ -816,6 +828,19 @@ this.ask(); }, + /** + * @param {string} messageToUtter + */ + handleTTSMessage(messageToUtter) { + if (!!window.speechSynthesis) { + if (window.speechSynthesis.speaking || window.speechSynthesis.pending) { + window.speechSynthesis.cancel(); + } else { + let utterance = new SpeechSynthesisUtterance(messageToUtter); + window.speechSynthesis.speak(utterance); + } + } + }, handleCancelAsk() { this.askAbortController?.abort(); |
