summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2021-11-14 12:06:37 +0100
committerTor Andersson <tor@ccxvii.net>2021-11-14 12:07:26 +0100
commit65e122492bd9cdd74b0a993a53875834071df53e (patch)
tree2eacc7f99882a89ff081359d6ee7d84998a06e98
parent8f3a28d965546f89cba27b23a3d7d545e889b4cb (diff)
downloadserver-65e122492bd9cdd74b0a993a53875834071df53e.tar.gz
Chat log.
-rw-r--r--public/common/client.js2
-rw-r--r--server.js17
-rw-r--r--views/chat.ejs79
-rw-r--r--views/profile.ejs2
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]);
});
diff --git a/server.js b/server.js
index e08a1df..343e46d 100644
--- a/server.js
+++ b/server.js
@@ -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()">&#x2190;</button>
+<button onclick="next()">&#x2192;</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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") %>;
+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>&#xbb;
+<a href="/chat">Chat log</a>
+<br>&#xbb;
<a href="/logout">Logout</a>
<% if (open_games.length > 0) { %>