From 02f9460fd371cab6ed1fd8ae2291fcd4b346e075 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 7 Jun 2025 10:06:46 +1000 Subject: [PATCH] JSON-based message history --- client-web/index.js | 33 ++++++++++++-- server/src/main/kotlin/Main.kt | 81 ++++++++++++++++++++++++---------- 2 files changed, 87 insertions(+), 27 deletions(-) diff --git a/client-web/index.js b/client-web/index.js index 0c2de7a..ee49937 100644 --- a/client-web/index.js +++ b/client-web/index.js @@ -678,7 +678,7 @@ function handleRoomChange(message) { } // Handle file messages -function handleFileMessage(message) { +function handleFileMessage(message, isHistory = false) { // Only show file if it's for current room if (message.room && message.room !== currentRoom) { highlightRoom(message.room); @@ -690,6 +690,7 @@ function handleFileMessage(message) { const messageWrapper = document.createElement('div'); messageWrapper.className = 'message'; + if (isHistory) messageWrapper.classList.add('history-message'); // Create avatar const avatar = document.createElement('div'); @@ -711,7 +712,7 @@ function handleFileMessage(message) { const timestampSpan = document.createElement('span'); timestampSpan.className = 'message-timestamp'; - timestampSpan.textContent = new Date().toLocaleTimeString(); + timestampSpan.textContent = isHistory ? 'History' : new Date().toLocaleTimeString(); headerDiv.appendChild(authorSpan); headerDiv.appendChild(timestampSpan); @@ -1183,8 +1184,34 @@ function clearMessages() { async function loadRoomHistory(roomName) { try { const history = await getRoomHistory(roomName); + const jHistory = JSON.parse(history); + + if (history) { const messagebox = document.getElementById('messagebox'); + jHistory.forEach(function (message, index) { + // Handle file messages + if (message.type == "file") { + handleFileMessage(message, true); + return; + } + + // Handle call messages + else if (message.type == "call") { + handleCallMessage(message); + return; + } + // Handle regular messages + else if (message.type == "message") { + if (message.room && message.room !== currentRoom) { + // Highlight room with unread message + highlightRoom(message.room); + return; + } + addChatMessage(message.username, message.content, true); + } + }); + /* const lines = history.split('\n'); lines.forEach(line => { @@ -1205,7 +1232,7 @@ async function loadRoomHistory(roomName) { addSystemMessage(line, true); } } - }); + });*/ messagebox.scrollTop = messagebox.scrollHeight; } diff --git a/server/src/main/kotlin/Main.kt b/server/src/main/kotlin/Main.kt index 47c05da..bec095b 100644 --- a/server/src/main/kotlin/Main.kt +++ b/server/src/main/kotlin/Main.kt @@ -27,6 +27,16 @@ fun md5(input:String): String { return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0') } +fun log(input: String) { + val logFile = File("chookchat.log") + try { + logFile.appendText(input) + } catch (e: Exception) { + println("Something went wrong with logging to chookchat.log. Here's the error: " + e.toString()) + println("And here's what actually went wrong: " + input) + } +} + object config { var address = "" var port = "" @@ -67,7 +77,7 @@ object config { } } } catch (e: Exception) { - println("Something went wrong :/ Here's the error: $e") + log("Something went wrong :/ Here's the error: $e") } } } @@ -168,7 +178,7 @@ object WsSessionManager { deadSessions.add(ctx) } } catch (e: Exception) { - println("Error broadcasting to session: ${e.message}") + log("Error broadcasting to session: ${e.message}") deadSessions.add(ctx) } } @@ -200,7 +210,7 @@ object WsSessionManager { sessionIds.remove(sessionId) } } catch (e: Exception) { - println("Error removing session without broadcast: ${e.message}") + log("Error removing session without broadcast: ${e.message}") } } @@ -225,7 +235,7 @@ object WsSessionManager { deadSessions.add(ctx) } } catch (e: Exception) { - println("Error sending ping: ${e.message}") + log("Error sending ping: ${e.message}") deadSessions.add(ctx) } } @@ -239,7 +249,7 @@ object WsSessionManager { sessions[ctx] = sessionId sessionIds[sessionId] = ctx } catch (e: Exception) { - println("Error adding session: ${e.message}") + log("Error adding session: ${e.message}") } } @@ -267,7 +277,7 @@ object WsSessionManager { broadcastOnlineUsers() } } catch (e: Exception) { - println("Error removing session: ${e.message}") + log("Error removing session: ${e.message}") } } @@ -289,7 +299,7 @@ object WsSessionManager { deadSessions.add(ctx) } } catch (e: Exception) { - println("Error broadcasting to session: ${e.message}") + log("Error broadcasting to session: ${e.message}") deadSessions.add(ctx) } } @@ -426,7 +436,7 @@ fun extractMessageContent(inputData: String, ctx: WsContext): String { } fun handleSentMessage(inputData: String): String { - println("API request received: $inputData") + log("API request received: $inputData") var jsonInputData: JSONObject try { jsonInputData = JSONObject(inputData) @@ -549,9 +559,7 @@ fun handleSentMessage(inputData: String): String { } if (content != "") { - if (type != "message") { - return "Success" - } + if (type == "typing") return "Success" val room = WsSessionManager.getUserRoom(username) ?: "general" val roomDirectory = File("roomChats") @@ -560,10 +568,18 @@ fun handleSentMessage(inputData: String): String { } val roomChatHistory = File("roomChats/$room.txt") - roomChatHistory.appendText("$username: $content ${System.lineSeparator()}") - - val chatHistory = File("chatHistory") - chatHistory.appendText("$username: $content [Room: $room] ${System.lineSeparator()}") + if (!roomChatHistory.exists()) { + roomChatHistory.appendText("[" + JSONObject().apply { + put("type", "beginning") + put("username", "system") + put("content", "") + }) + } + roomChatHistory.appendText("," + JSONObject().apply { + put("type", type) + put("username", username) + put("content", content) + }) return "Success" } else { @@ -574,7 +590,7 @@ fun handleSentMessage(inputData: String): String { fun getRoomChatHistory(roomName: String): String { val roomChatFile = File("roomChats/$roomName.txt") if (roomChatFile.exists()) { - return roomChatFile.readText() + return roomChatFile.readText() + "]" } return "" } @@ -611,7 +627,7 @@ fun buildHTML(): String { return(editedhtml) } catch (e: Exception) { - println(e) + log(e.toString()) return("There was an error! If you're the server's admin, here are the details: $e") } return("dingus") @@ -646,7 +662,7 @@ fun buildJS(): String { } return(editedJS) } catch (e: Exception) { - println(e) + log(e.toString()) return("console.log(`There was an error! If you're the server's admin, here are the details: $e`)") } return("dingus") @@ -669,7 +685,6 @@ fun handleServerCommand(command: String): String { } fun createAccount(inputData: String): String { - println("Account creation request recieved: $inputData") var username = "" var token = "" var message = "" @@ -832,6 +847,24 @@ fun main(args: Array) { } else { WsSessionManager.broadcast(processedData2.toString()) } + val roomDirectory = File("roomChats") + if (!roomDirectory.exists()) { + roomDirectory.mkdir() + } + + val roomChatHistory = File("roomChats/$room.txt") + if (!roomChatHistory.exists()) { + roomChatHistory.appendText("[" + JSONObject().apply { + put("type", "beginning") + put("username", "system") + put("content", "") + }) + } + roomChatHistory.appendText("," + JSONObject().apply { + put("type", "file") + put("username", username) + put("content", "https://maxwellj.xyz/chookchat/uploads/$newFilename") + }) } .ws("/api/websocket") { ws -> ws.onConnect { ctx -> @@ -844,13 +877,13 @@ fun main(args: Array) { when (ctx.message()) { "pong" -> {} else -> { - println(ctx.message()) + log(ctx.message()) val successState = handleSentMessage(ctx.message()) if (successState != "Success") { try { ctx.send(successState) } catch (e: Exception) { - println("Error sending error message: ${e.message}") + log("Error sending error message: ${e.message}") } } else { val messageContent = extractMessageContent(ctx.message(), ctx) @@ -869,7 +902,7 @@ fun main(args: Array) { WsSessionManager.broadcastToRoom("general", messageContent) } } catch (e: Exception) { - println("Error in broadcasting message: ${e.message}") + log("Error in broadcasting message: ${e.message}") WsSessionManager.broadcastToRoom("general", messageContent) } } @@ -881,9 +914,9 @@ fun main(args: Array) { try { if (args[0] == "-i") { - println("Type a command for the server") + log("Type a command for the server") while (1 == 1) { - println(handleServerCommand(readln())) + log(handleServerCommand(readln())) } } else { println("Interactive mode disabled, add -i to enable")