Mercurial Hosting > lang
changeset 34:0fb3488a017d
show_text
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 04 Aug 2025 23:06:19 -0600 |
parents | 7d9462ea03e3 |
children | 3117876debca |
files | src/chat.css src/chat.html.luan src/chat.js src/lib/Chat.luan src/lib/ai/claude/Ai_chat.luan src/private/tools/chat.html.luan src/save_chat.js.luan src/site.css src/site.js |
diffstat | 9 files changed, 46 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/chat.css Mon Aug 04 15:56:23 2025 -0600 +++ b/src/chat.css Mon Aug 04 23:06:19 2025 -0600 @@ -37,10 +37,10 @@ width: 600px; max-width: 90%; } -dialog[edit] input { +dialog[edit] input[type=text] { width: 100%; } -div[buttons] audio { - max-height: 34px; +div[role=assistant]:not(:has([name=show_text]:checked)) div[message] { + filter: blur(5px); }
--- a/src/chat.html.luan Mon Aug 04 15:56:23 2025 -0600 +++ b/src/chat.html.luan Mon Aug 04 23:06:19 2025 -0600 @@ -67,7 +67,7 @@ <input type=hidden name=chat value="<%=chat.id%>"> <p> <label>Chat name</label><br> - <input name=name required><br> + <input type=text name=name required><br> <span error></span> </p> <p><%= chat.language_name() %></p> @@ -87,6 +87,9 @@ <% end %> <select> </p> + <p> + <label clickable><input type=checkbox name=show_text>Show text</label> + </p> <div buttons> <button type=button onclick="closeModal(this)">Cancel</button> <button type=submit>Save</button>
--- a/src/chat.js Mon Aug 04 15:56:23 2025 -0600 +++ b/src/chat.js Mon Aug 04 23:06:19 2025 -0600 @@ -24,6 +24,7 @@ dialog.querySelector('input[name=name]').value = chat.name; dialog.querySelector('select[name=language_region]').value = chat.language_region; dialog.querySelector('select[name=voice]').value = chat.voice; + dialog.querySelector('input[name=show_text]').checked = chat.show_text; dialog.showModal(); }
--- a/src/lib/Chat.luan Mon Aug 04 15:56:23 2025 -0600 +++ b/src/lib/Chat.luan Mon Aug 04 23:06:19 2025 -0600 @@ -31,6 +31,7 @@ language = doc.language language_region = doc.language_region voice = doc.voice + show_text = doc.show_text == "true" } end @@ -46,6 +47,7 @@ language = chat.language or error() language_region = chat.language_region or error() voice = chat.voice or error() + show_text = chat.show_text and "true" or "false" } end @@ -57,6 +59,7 @@ chat.updated = chat.updated or time_now() chat.language_region = chat.language_region or first_region(chat.language) chat.voice = chat.voice or voices[1].code + if chat.show_text==nil then chat.show_text = true end function chat.save() local doc = to_doc(chat) @@ -78,6 +81,7 @@ language_region = chat.language_region voice = chat.voice name = chat.name + show_text = chat.show_text } end @@ -105,7 +109,7 @@ end function chat.output_messages_html() - Ai_chat.output_messages_html(chat.ai_thread) + Ai_chat.output_messages_html(chat.show_text,chat.ai_thread) end function chat.ask(input) @@ -116,7 +120,7 @@ chat.ai_thread = ai_thread chat.save() end ) - return `Ai_chat.output_messages_html(ai_thread,old_thread)` + return `Ai_chat.output_messages_html(chat.show_text,ai_thread,old_thread)` end function chat.language_name()
--- a/src/lib/ai/claude/Ai_chat.luan Mon Aug 04 15:56:23 2025 -0600 +++ b/src/lib/ai/claude/Ai_chat.luan Mon Aug 04 23:06:19 2025 -0600 @@ -27,7 +27,7 @@ %><%=system_prompt%><% end -function Ai_chat.output_messages_html(thread,old_thread) +function Ai_chat.output_messages_html(show_text,thread,old_thread) if thread == nil then return end @@ -39,6 +39,7 @@ local old_messages = old_thread.messages or error n = #old_messages end + local checked = show_text and "checked" or "" for i, message in ipairs(messages) do if i <= n then continue @@ -56,7 +57,15 @@ text = html_encode(text) %> <h3><%=who%></h3> - <div markdown role="<%=role%>"><%=text%></div> + <div role="<%=role%>"> + <div message markdown><%=text%></div> +<% if role=="assistant" then %> + <div controls> + <audio controls preload=none></audio> + <label clickable><input type=checkbox name=show_text <%=checked%> >Show text</label> + </div> +<% end %> + </div> <% end local content = message.content or error()
--- a/src/private/tools/chat.html.luan Mon Aug 04 15:56:23 2025 -0600 +++ b/src/private/tools/chat.html.luan Mon Aug 04 23:06:19 2025 -0600 @@ -1,5 +1,7 @@ local Luan = require "luan:Luan.luan" local error = Luan.error +local Parsers = require "luan:Parsers.luan" +local json_string = Parsers.json_string or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" @@ -39,7 +41,7 @@ </div> <% if process_markdown then %> <script> - handleMarkdown(); + handleMarkdown(<%=json_string(chat.language_region)%>,<%=json_string(chat.voice)%>); </script> <% end %> </body>
--- a/src/save_chat.js.luan Mon Aug 04 15:56:23 2025 -0600 +++ b/src/save_chat.js.luan Mon Aug 04 23:06:19 2025 -0600 @@ -10,6 +10,8 @@ local current_user = User.current or error() local Db = require "site:/lib/Db.luan" local run_in_transaction = Db.run_in_transaction or error() +local Logging = require "luan:logging/Logging.luan" +local logger = Logging.logger "save_chat.js" return function() @@ -17,12 +19,14 @@ local name = Http.request.parameters.name or error() local language_region = Http.request.parameters.language_region or error() local voice = Http.request.parameters.voice or error() + local show_text = Http.request.parameters.show_text run_in_transaction( function() chat = get_chat_by_id(chat) or error() chat.user_id == current_user().id or error() chat.name = name chat.language_region = language_region chat.voice = voice + chat.show_text = show_text ~= nil chat.save() end ) Io.stdout = Http.response.text_writer()
--- a/src/site.css Mon Aug 04 15:56:23 2025 -0600 +++ b/src/site.css Mon Aug 04 23:06:19 2025 -0600 @@ -88,3 +88,12 @@ code { white-space: pre-wrap; } + +audio { + max-height: 34px; +} +div[role] div[controls] { + display: flex; + gap: 16px; + align-items: center; +}
--- a/src/site.js Mon Aug 04 15:56:23 2025 -0600 +++ b/src/site.js Mon Aug 04 23:06:19 2025 -0600 @@ -131,16 +131,17 @@ let text = div.textContent; text = text.replace(/\{([^|}]+)\|([^|}]+)\}/g, '<ruby>$1<rt>$2</rt></ruby>'); text = converter.render(text); - if( lang && div.getAttribute('role')==='assistant' ) { + div.innerHTML = text; + div.removeAttribute('markdown'); + let parent = div.parentNode; + if( parent.getAttribute('role')==='assistant' ) { mdDiv.innerHTML = text; let rts = mdDiv.querySelectorAll('rt'); for( let rt of rts ) { rt.remove(); } //console.log(mdDiv.textContent); - text += `\n<p><audio controls preload=none src="/tts.mp3?lang=${lang}&voice=${voice}&text=${encodeURIComponent(mdDiv.textContent)}"></audio></p>\n`; + parent.querySelector('audio').src = `/tts.mp3?lang=${lang}&voice=${voice}&text=${encodeURIComponent(mdDiv.textContent)}`; } - div.innerHTML = text; - div.removeAttribute('markdown'); } }