diff options
author | Tor Andersson <tor@ccxvii.net> | 2021-11-14 12:06:37 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2021-11-14 12:07:26 +0100 |
commit | 65e122492bd9cdd74b0a993a53875834071df53e (patch) | |
tree | 2eacc7f99882a89ff081359d6ee7d84998a06e98 | |
parent | 8f3a28d965546f89cba27b23a3d7d545e889b4cb (diff) | |
download | server-65e122492bd9cdd74b0a993a53875834071df53e.tar.gz |
Chat log.
-rw-r--r-- | public/common/client.js | 2 | ||||
-rw-r--r-- | server.js | 17 | ||||
-rw-r--r-- | views/chat.ejs | 79 | ||||
-rw-r--r-- | views/profile.ejs | 2 |
4 files changed, 98 insertions, 2 deletions
diff --git a/public/common/client.js b/public/common/client.js index c516880..5df0413 100644 --- a/public/common/client.js +++ b/public/common/client.js @@ -251,7 +251,7 @@ function init_client(roles) { }); socket.on('chat', function (item) { - console.log("CHAT MESSAGE", JSON.stringify(item)); + console.log("CHAT", JSON.stringify(item)); update_chat(item[0], item[1], item[2], item[3]); }); @@ -542,6 +542,18 @@ app.get('/users', may_be_logged_in, function (req, res) { res.render('users.ejs', { user: req.user, userList: rows }); }); +app.get('/chat', must_be_logged_in, function (req, res) { + LOG(req, "GET /chat"); + let chat = SQL_SELECT_USER_CHAT_N.all(req.user.user_id, 1200); + res.render('chat.ejs', { user: req.user, chat: chat, page_size: 12 }); +}); + +app.get('/chat/all', must_be_logged_in, function (req, res) { + LOG(req, "GET /chat/all"); + let chat = SQL_SELECT_USER_CHAT.all(req.user.user_id); + res.render('chat.ejs', { user: req.user, chat: chat, page_size: 0 }); +}); + /* * MESSAGES */ @@ -861,6 +873,9 @@ load_rules(); const SQL_INSERT_GAME = SQL("INSERT INTO games (owner_id,title_id,scenario,options,private,random,description) VALUES (?,?,?,?,?,?,?)"); const SQL_DELETE_GAME = SQL("DELETE FROM games WHERE game_id=? AND owner_id=?"); +const SQL_SELECT_USER_CHAT = SQL("SELECT game_id,time,name,message FROM game_chat_view WHERE game_id IN ( SELECT DISTINCT game_id FROM players WHERE user_id=? ) ORDER BY chat_id DESC").raw(); +const SQL_SELECT_USER_CHAT_N = SQL("SELECT game_id,time,name,message FROM game_chat_view WHERE game_id IN ( SELECT DISTINCT game_id FROM players WHERE user_id=? ) ORDER BY chat_id DESC LIMIT ?").raw(); + const SQL_SELECT_GAME_CHAT = SQL("SELECT chat_id,time,name,message FROM game_chat_view WHERE game_id=? AND chat_id>?").raw(); const SQL_INSERT_GAME_CHAT = SQL("INSERT INTO game_chat (game_id,user_id,message) VALUES (?,?,?) RETURNING chat_id,time,'',message").raw(); @@ -1538,7 +1553,7 @@ function on_chat(socket, message) { try { let chat = SQL_INSERT_GAME_CHAT.get(socket.game_id, socket.user_id, message); chat[2] = socket.user_name; - SLOG(socket, "--> CHAT", chat); + SLOG(socket, "--> CHAT", JSON.stringify(chat)); for (let other of clients[socket.game_id]) if (other.role !== "Observer") other.emit('chat', chat); diff --git a/views/chat.ejs b/views/chat.ejs new file mode 100644 index 0000000..81697ee --- /dev/null +++ b/views/chat.ejs @@ -0,0 +1,79 @@ +<%- include('header', { title: "Chat Log" }) %> +<style> +table{width:min(60rem,100%);} +td:nth-child(1),td:nth-child(2){white-space:nowrap;width:0} +td:nth-child(3){white-space:nowrap;width:8rem} +#foot{display:inline-block;padding-top:8px;} +table{border:1px solid black} +td{border:none} +td a{text-decoration:none;color:black;} +tr{background-color:white;} +tr.me{background-color:aliceblue;} +</style> +<% if (page_size > 0) { %> +<p> +<button onclick="oldest()">Oldest</button> +<button onclick="back()">←</button> +<button onclick="next()">→</button> +<button onclick="newest()">Newest</button> +<span id="foot"></span> +<table><thead><tr><th>Game<th>Time<th>Who<th>Message</thead><tbody></tbody></table> +<p><a href="/chat/all">All messages</a> +<% } else { %> +<table><thead><tr><th>Game<th>Time<th>Who<th>Message</thead><tbody></tbody></table> +<% } %> +<script> +let chat_data = <%- JSON.stringify(chat).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">") %>; +let page_size = <%- page_size %>; +let me = <%- JSON.stringify(user.name) %>; +let table = document.querySelector("tbody"); +let foot = document.querySelector("#foot"); +let chat_lines = []; +function add(tr,text,link) { + let td = document.createElement("td"); + if (link) { + let a = document.createElement("a"); + a.href = link; + a.textContent = text; + td.appendChild(a); + } else { + td.textContent = text; + } + tr.appendChild(td); +} +function format_date(date) { + let t = date.toISOString(); + return t.substring(0,10) + " " + t.substring(11,19); +} +for (let [game_id,time,user,message] of chat_data) { + let tr = document.createElement("tr"); + if (user === me) tr.className = 'me'; + add(tr,game_id,'/join/'+game_id); + add(tr,format_date(new Date(time+'Z'))); + add(tr,user,'/user/'+user); + add(tr,message); + chat_lines.push(tr); +} +function next() { if (page > 0) --page; update(); } +function back() { if (page < page_count-1) ++page; update(); } +function newest() { page=0; update(); } +function oldest() { page=page_count-1; update(); } +let chat_size = chat_lines.length; +let page_count = Math.ceil(chat_size / page_size); +let page = 0; +function update() { + table.innerHTML = ''; + for (let i = 0; i < page_size; ++i) { + let k = page * page_size + ( page_size - i - 1); + if (k >= 0 && k < chat_size) + table.appendChild(chat_lines[k]); + foot.textContent = `${page_count-page} / ${page_count}`; + } +} +if (page_size > 0) { + newest(); +} else { + for (let i = chat_size-1; i >= 0; --i) + table.appendChild(chat_lines[i]); +} +</script> diff --git a/views/profile.ejs b/views/profile.ejs index 1dbc1f5..4d97486 100644 --- a/views/profile.ejs +++ b/views/profile.ejs @@ -22,6 +22,8 @@ Change <a href="/change_name">name</a>, or <a href="/change_about">profile text</a>. <br>» +<a href="/chat">Chat log</a> +<br>» <a href="/logout">Logout</a> <% if (open_games.length > 0) { %> |