Просмотр исходного кода

add: Limit initial message count

gugdun 9 месяцев назад
Родитель
Сommit
3e113d5997
2 измененных файлов с 70 добавлено и 6 удалено
  1. 40 3
      src/routes/chat.js
  2. 30 3
      src/views/chat.ejs

+ 40 - 3
src/routes/chat.js

@@ -14,7 +14,8 @@ router.get("/chat/:chat_id", async (req, res) => {
         try {
             const user = await db.one("SELECT id FROM users WHERE username = $1", [ req.params.chat_id ]);
             const chat = await db.one("SELECT id FROM chats WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)", [ req.user.id, user?.id ]);
-            const messages = await db.any("SELECT username, attachment_id, text, timestamp FROM messages JOIN users ON users.id = user_id WHERE chat_id = $1 ORDER BY messages.timestamp DESC", [ chat?.id ]);
+            const messages = await db.any("SELECT username, attachment_id, text, timestamp FROM messages JOIN users ON users.id = user_id WHERE chat_id = $1 ORDER BY messages.timestamp DESC LIMIT 20", [ chat?.id ]);
+            const moreMessages = await db.any("SELECT 1 FROM messages WHERE chat_id = $1 AND timestamp < $2", [ chat?.id, messages[messages.length - 1]?.timestamp ]);
             res.render("layout", {
                 child: await ejs.renderFile(path.join(views, "chat.ejs"), {
                     username: req.user.username,
@@ -27,7 +28,9 @@ router.get("/chat/:chat_id", async (req, res) => {
                             text: message.text,
                             datetime: message.timestamp
                         }
-                    })
+                    }),
+                    hasMoreMessages: moreMessages.length > 0,
+                    firstTimestamp: messages[messages.length - 1]?.timestamp || new Date().toISOString()
                 })
             });
         } catch (err) {
@@ -36,7 +39,9 @@ router.get("/chat/:chat_id", async (req, res) => {
                 child: await ejs.renderFile(path.join(views, "chat.ejs"), {
                     title: req.params.chat_id,
                     empty: true,
-                    messages: []
+                    messages: [],
+                    hasMoreMessages: false,
+                    firstTimestamp: new Date().toISOString()
                 })
             });
         }
@@ -67,4 +72,36 @@ router.post("/chat/:chat_id", async (req, res) => {
     }
 });
 
+router.post("/chat/:chat_id/messages", async (req, res) => {
+    if (req.user) {
+        try {
+            const user = await db.one("SELECT id FROM users WHERE username = $1", [req.params.chat_id]);
+            const chat = await db.one("SELECT id FROM chats WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)", [ req.user.id, user?.id ]);
+            const firstTimestamp = req.body.timestamp;
+            const messages = await db.any("SELECT username, attachment_id, text, timestamp FROM messages JOIN users ON users.id = user_id WHERE chat_id = $1 AND timestamp < $2 ORDER BY messages.timestamp DESC LIMIT 20", [ chat?.id, firstTimestamp ]);
+            const moreMessages = await db.any("SELECT 1 FROM messages WHERE chat_id = $1 AND timestamp < $2", [ chat?.id, messages[messages.length - 1]?.timestamp ]);
+            res.json({
+                messages: messages.map((message) => {
+                    return {
+                        username: message.username,
+                        text: message.text,
+                        datetime: message.timestamp
+                    }
+                }),
+                hasMoreMessages: moreMessages.length > 0,
+                timestamp: messages[messages.length - 1]?.timestamp || firstTimestamp
+            });
+        } catch (err) {
+            console.log(err);
+            res.json({
+                messages: [],
+                hasMoreMessages: false,
+                timestamp: req.body.timestamp
+            });
+        }
+    } else {
+        res.redirect("/login");
+    }
+});
+
 module.exports = router;

+ 30 - 3
src/views/chat.ejs

@@ -16,6 +16,9 @@
                 <span class="message-datetime"><%- message.datetime %></span>
             </div>
         <% }); %>
+        <% if (hasMoreMessages) { %>
+            <button id="load-more" class="button">Load More</button>
+        <% } %>
     </div>
     <form onsubmit="return onMessageSubmit(event)" class="input-form">
         <input type="text" id="message-input" name="text" placeholder="Enter message..." class="text-input" required />
@@ -23,6 +26,7 @@
     </form>
 </div>
 <script>
+    var firstTimestamp = new Date("<%- firstTimestamp %>").toISOString();
     var lastTimestamp = new Date().toISOString()
     var messageList = document.getElementById("message-list")
     var messageInput = document.getElementById("message-input")
@@ -31,7 +35,7 @@
         var timestamp = timestamps[i]
         timestamp.innerText = new Date(timestamp.innerText).toLocaleString()
     }
-    function addMessage(message) {
+    function addMessage(message, before) {
         var container = document.createElement("div")
         var nameSpan = document.createElement("span")
         var textSpan = document.createElement("span")
@@ -46,8 +50,8 @@
         container.appendChild(nameSpan)
         container.appendChild(textSpan)
         container.appendChild(datetimeSpan)
-        messageList.insertBefore(container, messageList.firstChild)
         lastTimestamp = message.datetime
+        messageList.insertBefore(container, before)
     }
     function onMessageSubmit(event) {
         event.preventDefault()
@@ -73,7 +77,7 @@
             var response = JSON.parse(xhr.responseText)
             for (var i = 0; i < response["messages"].length; i++) {
                 var message = response["messages"][i]
-                addMessage(message)
+                addMessage(message, messageList.firstChild)
             }
             pollMessages()
         }
@@ -82,5 +86,28 @@
         }
         xhr.send(JSON.stringify(data))
     }
+    function loadMoreMessages() {
+        var data = { timestamp: firstTimestamp }
+        var xhr = new XMLHttpRequest()
+        xhr.open("POST", "/chat/<%- title %>/messages")
+        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8")
+        xhr.onload = function () {
+            var response = JSON.parse(xhr.responseText)
+            if (response.messages.length > 0) {
+                for (var i = 0; i < response["messages"].length; i++) {
+                    var message = response["messages"][i]
+                    addMessage(message, messageList.lastChild)
+                }
+                firstTimestamp = response.timestamp
+                if (!response.hasMoreMessages) {
+                    document.getElementById("load-more").style.display = "none"
+                }
+            } else {
+                document.getElementById("load-more").style.display = "none"
+            }
+        }
+        xhr.send(JSON.stringify(data))
+    }
+    document.getElementById("load-more")?.addEventListener("click", loadMoreMessages)
     pollMessages()
 </script>