Mercurial Hosting > chat
changeset 83:a47036fd0158
group chat
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 11 Mar 2025 13:56:59 -0600 |
parents | 0bc5e0d098f7 |
children | 83fb90276334 |
files | src/account.html.luan src/add_to_chat.js.luan src/chat.css src/chat.js src/chat.luan src/do_login.html.luan src/get_chat.js.luan src/index.html.luan src/invite.js.luan src/lib/Chat.luan src/lib/Shared.luan src/login.js.luan |
diffstat | 12 files changed, 155 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/account.html.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/account.html.luan Tue Mar 11 13:56:59 2025 -0600 @@ -47,9 +47,8 @@ function saveUsername() { let dialog = document.querySelector('dialog[edit_username]'); - let input = dialog.querySelector('input[name=username]'); - username = input.value; - closeModal(input); + closeModal(dialog); + username = dialog.querySelector('input[name=username]').value; showUsername(); ajax(`save_username.js?username=${encodeURIComponent(username)}`); } @@ -70,11 +69,10 @@ function saveNotify() { let dialog = document.querySelector('dialog[edit_notify]'); - let input = dialog.querySelector('input[name=notify_email]'); - notifyEmail = input.value; + closeModal(dialog); + notifyEmail = dialog.querySelector('input[name=notify_email]').value; let radio = dialog.querySelector('input[type=radio]:checked'); multiNotify = radio.value === 'true'; - closeModal(input); showNotify(); ajax(`save_notify.js?email=${encodeURIComponent(notifyEmail)}&multi=${multiNotify}`); } @@ -93,9 +91,8 @@ function saveVoice() { let dialog = document.querySelector('dialog[edit_voice]'); - let input = dialog.querySelector('input[name=voice]'); - voice = input.value; - closeModal(input); + closeModal(dialog); + voice = dialog.querySelector('input[name=voice]').value; showVoice(); ajax(`save_voice.js?url=${encodeURIComponent(voice)}`); } @@ -219,7 +216,7 @@ </dialog> <dialog url> <h2>Your chat URL</h2> - <p><%= base_url() %>/chat?with=<%=user.email%></p> + <p><%= base_url() %>/chat?with=<%=html_encode(user.email)%></p> <p>Use this URL to link to your chat so that other people can chat with you by clicking on the link.</p> <div buttons> <button onclick="closeModal(this)">Close</button>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/add_to_chat.js.luan Tue Mar 11 13:56:59 2025 -0600 @@ -0,0 +1,44 @@ +local Luan = require "luan:Luan.luan" +local error = Luan.error +local pairs = Luan.pairs or error() +local Table = require "luan:Table.luan" +local concat = Table.concat or error() +local Html = require "luan:Html.luan" +local url_encode = Html.url_encode or error() +local Io = require "luan:Io.luan" +local Http = require "luan:http/Http.luan" +local User = require "site:/lib/User.luan" +local get_user_by_email = User.get_by_email or error() +local get_user_by_id = User.get_by_id or error() +local current_user = User.current or error() +local Chat = require "site:/lib/Chat.luan" +local get_chat_by_id = Chat.get_by_id or error() +local Utils = require "site:/lib/Utils.luan" +local list_to_set = Utils.list_to_set or error() + + +return function() + local email = Http.request.parameters.email or error() + local add_user = get_user_by_email(email) + Io.stdout = Http.response.text_writer() + if add_user == nil then +%> + addToChatError('email not found'); +<% + return + end + local user = current_user() or error() + local chat = Http.request.parameters.chat or error() + chat = get_chat_by_id(chat) or error() + local set = list_to_set(chat.user_ids) + set[user.id] or error() + set[add_user.id] = true + local t = {} + for id in pairs(set) do + local user = get_user_by_id(id) + t[#t+1] = "with="..url_encode(user.email) + end +%> + location = 'chat?<%= concat(t,"&") %>'; +<% +end
--- a/src/chat.css Mon Mar 10 22:42:46 2025 -0600 +++ b/src/chat.css Tue Mar 11 13:56:59 2025 -0600 @@ -227,6 +227,14 @@ height: 1em; } +dialog[add] input[name=email] { + width: 300px; +} + +[error] { + color: red; +} + @media (min-width: 700px) { div[chat_content] { margin-left: calc(3% - 8px);
--- a/src/chat.js Mon Mar 10 22:42:46 2025 -0600 +++ b/src/chat.js Tue Mar 11 13:56:59 2025 -0600 @@ -304,7 +304,7 @@ function gotoInvite(el) { let email = document.querySelector('dialog[invite] span[email]').textContent; closeModal(el); - location = `chat?with=${email}`; + location = `chat?with=${encodeURIComponent(email)}`; ajax(`save_post.js?post=${currentPostId}`,`content=${encodeURIComponent(text)}`); } @@ -443,3 +443,20 @@ div.setAttribute('hidden',''); div.setAttribute('reply',''); } + +function openAddToChat() { + let dialog = document.querySelector('dialog[add]'); + dialog.querySelector('input[name=email]').value = ''; + openModal(dialog); +} + +function addToChat() { + let dialog = document.querySelector('dialog[add]'); + let email = dialog.querySelector('input[name=email]').value; + ajax(`add_to_chat.js?chat=${currentChatId}&email=${encodeURIComponent(email)}`); +} + +function addToChatError(msg) { + let dialog = document.querySelector('dialog[add]'); + dialog.querySelector('span[error]').textContent = msg; +}
--- a/src/chat.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/chat.luan Tue Mar 11 13:56:59 2025 -0600 @@ -4,6 +4,8 @@ local Table = require "luan:Table.luan" local concat = Table.concat or error() local is_empty = Table.is_empty or error() +local Html = require "luan:Html.luan" +local url_encode = Html.url_encode or error() local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" local http_push_to_users = Shared.http_push_to_users or error() @@ -27,7 +29,7 @@ if not is_empty(with) then local t = {} for email in pairs(with) do - t[#t+1] = "with="..email + t[#t+1] = "with="..url_encode(email) end url = url.."?"..concat(t,"&") end
--- a/src/do_login.html.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/do_login.html.luan Tue Mar 11 13:56:59 2025 -0600 @@ -3,6 +3,8 @@ local ipairs = Luan.ipairs or error() local Table = require "luan:Table.luan" local concat = Table.concat or error() +local Html = require "luan:Html.luan" +local url_encode = Html.url_encode or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" @@ -41,7 +43,7 @@ with = to_list(with) local t = {} for _, email in ipairs(with) do - t[#t+1] = "with="..email + t[#t+1] = "with="..url_encode(email) end location = "/chat?"..concat(t,"&") end
--- a/src/get_chat.js.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/get_chat.js.luan Tue Mar 11 13:56:59 2025 -0600 @@ -18,6 +18,7 @@ local post_search = Post.search or error() local Shared = require "site:/lib/Shared.luan" local post_html = Shared.post_html or error() +local group_name = Shared.group_name or error() local Logging = require "luan:logging/Logging.luan" local logger = Logging.logger "get_chat.js" @@ -29,20 +30,33 @@ <div top> <h3> <img back onclick="back()" src="/images/arrow_back.svg"> - <span><% - local user_id = chat.other_user_id(user.id) - local other_user = get_user_by_id(user_id) or error(user_id) - %><%= other_user.name_html() %><span online="<%= other_user.id %>"></span><% - local voice_url = other_user.voice_url - if voice_url ~= nil then - %> <a href="<%=voice_url%>" title="Call" target="voice"><img phone src="/images/call.svg"></a><% - end - %></span> + <span> +<% + local user_ids = chat.other_user_ids(user.id) + if #user_ids > 1 then +%> + <%= group_name(user_ids) %> +<% + else + local other_user = get_user_by_id(user_ids[1]) or error() +%> + <%= other_user.name_html() %><span online="<%= other_user.id %>"></span> +<% + local voice_url = other_user.voice_url + if voice_url ~= nil then +%> + <a href="<%=voice_url%>" title="Call" target="voice"><img phone src="/images/call.svg"></a> +<% + end + end +%> + </span> </h3> <span pulldown> <img onclick="clickMenu(this)" src="/images/menu.svg"> <div> <span onclick="openPeople()">People in Chat</span> + <span onclick="openAddToChat()">Add Someone to Chat</span> <span onclick="deleteChat()">Delete Chat</span> </div> </span>
--- a/src/index.html.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/index.html.luan Tue Mar 11 13:56:59 2025 -0600 @@ -111,6 +111,20 @@ <button onclick="closeModal(this)">Close</button> </div> </dialog> + <dialog add> + <h2>Add Someone to Chat</h2> + <form action="javascript:addToChat()"> + <p> + <label>Person's email</label><br> + <input type=email name=email required><br> + <span error></span> + </p> + <div buttons> + <button onclick="closeModal(this)">Cancel</button> + <button type=submit>Add</button> + </div> + </form> + </dialog> <input type="file" required onchange="loadedFile(this)"> <script> 'use strict';
--- a/src/invite.js.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/invite.js.luan Tue Mar 11 13:56:59 2025 -0600 @@ -2,8 +2,10 @@ local error = Luan.error local Parsers = require "luan:Parsers.luan" local json_string = Parsers.json_string or error() +local Html = require "luan:Html.luan" +local url_encode = Html.url_encode or error() +local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" -local Io = require "luan:Io.luan" local User = require "site:/lib/User.luan" local get_user_by_email = User.get_by_email or error() local get_or_create_user_by_email = User.get_or_create_by_email or error() @@ -20,13 +22,13 @@ Io.stdout = Http.response.text_writer() if get_user_by_email(email) ~= nil then %> - location = 'chat?with=<%=email%>'; + location = 'chat?with=<%=url_encode(email)%>'; <% return end local invitee = get_or_create_user_by_email(email) local password = invitee.password - local url = base_url().."/do_login.html?user="..invitee.id.."&password="..password.."&with="..user.email + local url = base_url().."/do_login.html?user="..invitee.id.."&password="..password.."&with="..url_encode(user.email) local who = user.name or user.email send_mail { To = email
--- a/src/lib/Chat.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/lib/Chat.luan Tue Mar 11 13:56:59 2025 -0600 @@ -65,13 +65,14 @@ Http.push(url,message) end - function chat.other_user_id(my_id) + function chat.other_user_ids(my_id) + local t = {nil} for _, user_id in ipairs(chat.user_ids) do if user_id ~= my_id then - return user_id + t[#t+1] = user_id end end - error() + return t end local function get_chatuser_key(user)
--- a/src/lib/Shared.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/lib/Shared.luan Tue Mar 11 13:56:59 2025 -0600 @@ -2,6 +2,8 @@ local error = Luan.error local ipairs = Luan.ipairs or error() local parse = Luan.parse or error() +local Table = require "luan:Table.luan" +local concat = Table.concat or error() local Time = require "luan:Time.luan" local Thread = require "luan:Thread.luan" local thread_run = Thread.run or error() @@ -145,18 +147,37 @@ <% end +local function group_name(user_ids) + local t = {nil} + for _, user_id in ipairs(user_ids) do + t[#t+1] = get_user_by_id(user_id).name_html() + end + return concat(t,", ") +end +Shared.group_name = group_name + function Shared.chats_html() local user = current_user() or error() local chats = chat_search( "chat_user_ids:"..user.id, "chat_updated desc" ) for _, chat in ipairs(chats) do local chat_id = chat.id - local user_id = chat.other_user_id(user.id) - local other_user = get_user_by_id(user_id) or error() local unread = chat.unread(user) %> <div chat="<%=chat_id%>" onclick="selectChat('<%=chat_id%>')"> +<% + local user_ids = chat.other_user_ids(user.id) + if #user_ids > 1 then +%> + <%= group_name(user_ids) %> +<% + else + local other_user = get_user_by_id(user_ids[1]) or error() +%> <%= other_user.name_html() %> <span online="<%= other_user.id %>"></span> +<% + end +%> <span unread="<%=unread%>"><%=unread%></span> </div> <%
--- a/src/login.js.luan Mon Mar 10 22:42:46 2025 -0600 +++ b/src/login.js.luan Tue Mar 11 13:56:59 2025 -0600 @@ -1,6 +1,8 @@ local Luan = require "luan:Luan.luan" local error = Luan.error local ipairs = Luan.ipairs or error() +local Html = require "luan:Html.luan" +local url_encode = Html.url_encode or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" @@ -19,7 +21,7 @@ local with = Http.request.parameters.with with = to_list(with) for _, email in ipairs(with) do - url = url.."&with="..email + url = url.."&with="..url_encode(email) end send_mail_async { To = email