Mercurial Hosting > lang
annotate src/chat.html.luan @ 35:3117876debca
ai_first_message in textarea
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 05 Aug 2025 16:41:29 -0600 |
parents | 0fb3488a017d |
children | 2737eeedc1d5 |
rev | line source |
---|---|
0 | 1 local Luan = require "luan:Luan.luan" |
2 local error = Luan.error | |
31 | 3 local ipairs = Luan.ipairs or error() |
29 | 4 local Parsers = require "luan:Parsers.luan" |
5 local json_string = Parsers.json_string or error() | |
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
6 local Html = require "luan:Html.luan" |
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
7 local html_encode = Html.encode or error() |
0 | 8 local Io = require "luan:Io.luan" |
9 local Http = require "luan:http/Http.luan" | |
10 local Shared = require "site:/lib/Shared.luan" | |
11 local head = Shared.head or error() | |
12 local header = Shared.header or error() | |
4 | 13 local started = Shared.started or error() |
31 | 14 local voices = Shared.voices or error() |
4 | 15 local User = require "site:/lib/User.luan" |
24 | 16 local current_user = User.current_required or error() |
4 | 17 local Chat = require "site:/lib/Chat.luan" |
18 local get_chat_by_id = Chat.get_by_id or error() | |
32 | 19 local languages = require "site:/lib/languages.luan" |
0 | 20 |
21 | |
22 return function() | |
4 | 23 local user = current_user() |
24 | 24 if user == nil then return end |
18 | 25 local chat_id = Http.request.parameters.chat or error() |
26 local chat = get_chat_by_id(chat_id) or error() | |
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
27 local init_text = chat.init_text() |
0 | 28 Io.stdout = Http.response.text_writer() |
29 %> | |
30 <!doctype html> | |
31 <html lang="en"> | |
32 <head> | |
33 <% head() %> | |
4 | 34 <style> |
35 @import "/chat.css?s=<%=started%>"; | |
36 </style> | |
37 <script src="/chat.js?s=<%=started%>"></script> | |
0 | 38 </head> |
39 <body> | |
40 <% header() %> | |
4 | 41 <div content ai_container> |
42 <div top> | |
29 | 43 <h3 name></h3> |
4 | 44 <span pulldown> |
45 <img onclick="clickMenu(this)" src="/images/menu.svg"> | |
46 <div> | |
29 | 47 <span onclick="editChat()">Edit Chat</span> |
4 | 48 <span onclick="deleteChat()">Delete Chat</span> |
9 | 49 <span onclick="systemPrompt()">System Prompt</span> |
1 | 50 </div> |
4 | 51 </span> |
52 </div> | |
7 | 53 <div messages> |
54 <% chat.output_messages_html() %> | |
4 | 55 </div> |
56 <div ask> | |
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
57 <textarea autofocus oninput="fixTextarea(event.target)" onkeydown="textareaKey(event)"><%= html_encode(init_text) %></textarea> |
14 | 58 <div buttons> |
28 | 59 <audio controls preload=none></audio> |
14 | 60 <button record onclick="toggleRecording()">Record</button> |
61 <button onclick="askAi()" title="Send"><img src="/images/send.svg"></button> | |
62 </div> | |
1 | 63 </div> |
0 | 64 </div> |
6 | 65 <img waiting-ai-icon src="/images/spinner_green.gif"> |
29 | 66 <dialog edit> |
67 <h2>Edit Chat</h2> | |
68 <form onsubmit="saveChat(this)" action="javascript:"> | |
69 <input type=hidden name=chat value="<%=chat.id%>"> | |
4 | 70 <p> |
71 <label>Chat name</label><br> | |
34 | 72 <input type=text name=name required><br> |
4 | 73 <span error></span> |
74 </p> | |
32 | 75 <p><%= chat.language_name() %></p> |
76 <p> | |
77 <label>Region</label><br> | |
78 <select name=language_region> | |
79 <% for _, region in ipairs(languages[chat.language].regions) do %> | |
80 <option value="<%=region.code%>"><%=region.name%></option> | |
81 <% end %> | |
82 <select> | |
83 </p> | |
31 | 84 <p> |
85 <label>Voice</label><br> | |
86 <select name=voice> | |
87 <% for _, voice in ipairs(voices) do %> | |
88 <option value="<%=voice.code%>"><%=voice.name%></option> | |
89 <% end %> | |
90 <select> | |
91 </p> | |
34 | 92 <p> |
93 <label clickable><input type=checkbox name=show_text>Show text</label> | |
94 </p> | |
4 | 95 <div buttons> |
96 <button type=button onclick="closeModal(this)">Cancel</button> | |
29 | 97 <button type=submit>Save</button> |
4 | 98 </div> |
99 </form> | |
100 </dialog> | |
101 <dialog delete> | |
102 <h2>Delete Chat</h2> | |
103 <p>Are you sure that you want to delete this chat?</p> | |
104 <div buttons> | |
105 <button onclick="closeModal(this)">Cancel</button> | |
106 <button onclick="doDeleteChat(this)">Delete</button> | |
107 </div> | |
108 </dialog> | |
9 | 109 <dialog system_prompt> |
110 <h2>System Prompt</h2> | |
27 | 111 <pre> |
9 | 112 <% chat.output_system_prompt() %> |
27 | 113 </pre> |
114 <p><a href="view_course.html?course=<%=chat.course_id%>">View course</a></p> | |
9 | 115 <div buttons> |
116 <button onclick="closeModal(this)">Close</button> | |
117 </div> | |
118 </dialog> | |
27 | 119 <input name=initialized style="display:none"> |
6 | 120 <script> |
29 | 121 setChat(<%= json_string(chat.info()) %>); |
122 handleChatMarkdown(); | |
27 | 123 setTimeout(function(){ |
124 let initialized = document.querySelector('[name=initialized]'); | |
125 if( !initialized.value ) { | |
126 initialized.value = 'yes'; | |
127 //alert('init'); | |
128 scrollToEnd(); | |
129 } | |
130 },10); | |
6 | 131 </script> |
0 | 132 </body> |
133 </html> | |
134 <% | |
135 end |