changeset 46:42b741a1d5c6

add username
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 28 Feb 2025 19:25:12 -0700
parents e138343b2c76
children 8c6a2f602dbd
files src/account.html.luan src/chat.js src/get_chat.js.luan src/heartbeat.js.luan src/index.html.luan src/lib/Chat.luan src/lib/Shared.luan src/lib/User.luan src/save_username.js.luan
diffstat 9 files changed, 103 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.html.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/account.html.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -2,6 +2,8 @@
 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 html_encode = Html.encode or error()
 local Io = require "luan:Io.luan"
 local Http = require "luan:http/Http.luan"
 local Shared = require "site:/lib/Shared.luan"
@@ -25,10 +27,33 @@
 		<script>
 			'use strict';
 
+			let email = <%= json_string(user.email) %>;
+			let username = <%= json_string(user.name) or "" %>;
 			let notifyEmail = <%= json_string(user.notify_email or "") %>;
 			let multiNotify = <%= user.multi_notify %>;
 			let voice = <%= json_string(user.voice_url or "") %>;
 
+			function showUsername() {
+				let span = document.querySelector('span[username]');
+				span.textContent = username || email;
+			}
+
+			function editUsername() {
+				let dialog = document.querySelector('dialog[edit_username]');
+				let input = dialog.querySelector('input[name=username]');
+				input.value = username;
+				openModal(dialog);
+			}
+
+			function saveUsername() {
+				let dialog = document.querySelector('dialog[edit_username]');
+				let input = dialog.querySelector('input[name=username]');
+				username = input.value;
+				closeModal(input);
+				showUsername();
+				ajax(`save_username.js?username=${encodeURIComponent(username)}`);
+			}
+
 			function showNotify() {
 				let span = document.querySelector('span[notify]');
 				span.textContent = notifyEmail ? `Send notifications to ${notifyEmail}` : 'No notifications';
@@ -86,6 +111,7 @@
 			}
 
 			function init() {
+				showUsername();
 				showNotify();
 				showVoice();
 			}
@@ -100,6 +126,7 @@
 			h1 {
 				text-align: center;
 			}
+			input[name=username],
 			input[name=notify_email] {
 				width: 300px;
 				max-width: 100%;
@@ -119,11 +146,25 @@
 			<h1>Your Account</h1>
 			<p><a href="about.html">About Web Chat</a></p>
 			<p>Your URL: <%= base_url() %>/?with=<%=user.email%></p>
+			<p>Your username: <span username></span> <a href="javascript:editUsername()">Edit</a></p>
 			<p><span notify></span> <a href="javascript:editNotify()">Edit</a></p>
 			<p><span voice></span> <a href="javascript:editVoice()">Edit</a></p>
 			<p><a href="javascript:logout()">Logout</a></p>
 			<p><a href="javascript:deleteUser()">Delete account</a></p>
 		</div>
+		<dialog edit_username>
+			<h2>Edit Username</h2>
+			<form action="javascript:saveUsername()">
+				<p>
+					<label>Username</label><br> 
+					<input type=text name=username placeholder="<%=html_encode(user.email)%>"><br>
+				</p>
+				<div buttons>
+					<button type=button cancel onclick="closeModal(this)">Cancel</button>
+					<button type=submit go>Save</button>
+				</div>
+			</form>
+		</dialog>
 		<dialog edit_notify>
 			<h2>Edit Notification</h2>
 			<form action="javascript:saveNotify()">
--- a/src/chat.js	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/chat.js	Fri Feb 28 19:25:12 2025 -0700
@@ -16,7 +16,7 @@
 	userEventSource.onmessage = evalEvent;
 }
 
-function selectChat(div) {
+function selectChat(div,email) {
 	document.querySelector('div[content]').setAttribute('show','posts');
 	let chatId = div.getAttribute('chat');
 	if( chatId === currentChatId )
@@ -26,7 +26,6 @@
 	div.setAttribute('selected','');
 	ajax(`get_chat.js?chat=${chatId}`);
 	currentChatId = chatId;
-	let email = div.querySelector('[email]').textContent;
 	history.replaceState(null,null,`?with=${email}`);
 
 	if(eventSource)  eventSource.close();
--- a/src/get_chat.js.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/get_chat.js.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -7,13 +7,13 @@
 local Http = require "luan:http/Http.luan"
 local User = require "site:/lib/User.luan"
 local current_user = User.current or error()
+local get_user_by_id = User.get_by_id or error()
 local Chat = require "site:/lib/Chat.luan"
 local get_chat_by_id = Chat.get_by_id or error()
 local Post = require "site:/lib/Post.luan"
 local post_search = Post.search or error()
 local Shared = require "site:/lib/Shared.luan"
 local post_html = Shared.post_html or error()
-local chat_other_users_html = Shared.chat_other_users_html or error()
 local Logging = require "luan:logging/Logging.luan"
 local logger = Logging.logger "get_chat.js"
 
@@ -27,7 +27,15 @@
 	<div top>
 		<h3>
 			<img back onclick="back()" src="/images/arrow_back.svg">
-			<span><% chat_other_users_html(chat,user,true) %></span>
+			<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>
 		</h3>
 		<button onclick='deleteChat()'>Delete</button>
 	</div>
--- a/src/heartbeat.js.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/heartbeat.js.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -21,7 +21,7 @@
 	http_push_to_users( user_ids, js )
 
 	local last_update = Http.request.parameters.last_update or error()
-	last_update = to_number(last_update) or error()
+	last_update = to_number(last_update) or error(last_update)
 	local user_last_update = user.last_update()
 	local now = time_now()
 	if now - user_last_update < 10000 or last_update >= user_last_update then
--- a/src/index.html.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/index.html.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -7,6 +7,8 @@
 local concat = Table.concat or error()
 local is_empty = Table.is_empty or error()
 local size = Table.size or 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"
@@ -63,8 +65,8 @@
 end
 
 return function()
-	local with = Http.request.parameters.with
-	with = to_set(with)
+	local with_email = Http.request.parameters.with
+	local with = to_set(with_email)
 	local user = current_user()
 	if user == nil then
 		local url = "/login.html"
@@ -148,7 +150,7 @@
 	if selected ~= nil then
 %>
 			let div = document.querySelector('div[chat="<%=selected.id%>"]');
-			selectChat(div);
+			selectChat(div,<%=json_string(with_email)%>);
 <%
 	end
 %>
--- a/src/lib/Chat.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/lib/Chat.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -52,6 +52,15 @@
 		Http.push(url,message)
 	end
 
+	function chat.other_user_id(my_id)
+		for _, user_id in ipairs(chat.user_ids) do
+			if user_id ~= my_id then
+				return user_id
+			end
+		end
+		error()
+	end
+
 	return chat
 end
 
--- a/src/lib/Shared.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/lib/Shared.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -7,6 +7,8 @@
 local Time = require "luan:Time.luan"
 local Thread = require "luan:Thread.luan"
 local thread_run = Thread.run or error()
+local Parsers = require "luan:Parsers.luan"
+local json_string = Parsers.json_string or error()
 local Html = require "luan:Html.luan"
 local html_encode = Html.encode or error()
 local Http = require "luan:http/Http.luan"
@@ -128,7 +130,7 @@
 %>
 		<div post="<%=id%>" author="<%=author.id%>" fix>
 			<div who>
-				<span author><%=author.email%></span>
+				<span author><%=author.name_html()%></span>
 				<span right>
 					<span when><%=post.date%></span>
 					<span pulldown></span>
@@ -139,33 +141,16 @@
 <%
 end
 
-local function chat_other_users_html(chat,user,show_phone)
-	local my_id = user.id
-	local is_first = true
-	for _, user_id in ipairs(chat.user_ids) do
-		if user_id ~= my_id then
-			local other_user = get_user_by_id(user_id) or error()
-			if is_first then
-				is_first = false
-			else
-				%>, <%
-			end
-			%><span email><%= other_user.email %></span><span online="<%= other_user.id %>"></span><%
-			local voice_url = other_user.voice_url
-			if voice_url ~= nil and show_phone then
-				%> <a href="<%=voice_url%>" title="Call" target="voice"><img phone src="/images/call.svg"></a><%
-			end
-		end
-	end
-end
-Shared.chat_other_users_html = chat_other_users_html
-
 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 user_id = chat.other_user_id(user.id)
+		local other_user = get_user_by_id(user_id) or error()
 %>
-		<div chat="<%=chat.id%>" onclick="selectChat(this)"><% chat_other_users_html(chat,user,false) %></div>
+		<div chat="<%=chat.id%>" onclick='selectChat(this,<%=json_string(other_user.email)%>)'><%
+			%><%= other_user.name_html() %><span online="<%= other_user.id %>"></span><%
+		%></div>
 <%
 	end
 end
--- a/src/lib/User.luan	Fri Feb 28 14:37:11 2025 -0700
+++ b/src/lib/User.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -11,6 +11,8 @@
 local random = Math.random or error()
 local Table = require "luan:Table.luan"
 local concat = Table.concat or error()
+local Html = require "luan:Html.luan"
+local html_encode = Html.encode or error()
 local Lucene = require "luan:lucene/Lucene.luan"
 local lucene_quote = Lucene.quote or error()
 local Http = require "luan:http/Http.luan"
@@ -37,6 +39,7 @@
 		notify_email = doc.notify_email
 		multi_notify = doc.multi_notify=="true"
 		voice_url = doc.voice_url
+		name = doc.name
 	}
 end
 
@@ -50,6 +53,7 @@
 		notify_email = user.notify_email
 		multi_notify = user.multi_notify and "true" or nil
 		voice_url = user.voice_url
+		name = user.name
 	}
 end
 
@@ -107,6 +111,10 @@
 		return set_to_list(user_ids)
 	end
 
+	function user.name_html()
+		return html_encode(user.name or user.email)
+	end
+
 	return user
 end
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/save_username.js.luan	Fri Feb 28 19:25:12 2025 -0700
@@ -0,0 +1,20 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local Http = require "luan:http/Http.luan"
+local Db = require "site:/lib/Db.luan"
+local run_in_transaction = Db.run_in_transaction or error()
+local User = require "site:/lib/User.luan"
+local current_user = User.current or error()
+
+
+return function()
+	local username = Http.request.parameters.username or error()
+	if username == "" then
+		username = nil
+	end
+	run_in_transaction( function()
+		local user = current_user() or error()
+		user.name = username
+		user.save()
+	end )
+end