diff --git a/client/public/index.html b/client/public/index.html index 57f658a..7bb265f 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -31,8 +31,8 @@
COMS by Jacob Signorovitch. Help | - Code | - API + Code | + API
diff --git a/client/public/wsModule.js b/client/public/wsModule.js index b70460f..6666733 100644 --- a/client/public/wsModule.js +++ b/client/public/wsModule.js @@ -12,6 +12,7 @@ import { updateUser, getGroupedUsers, setMyId, + clearData, users, setFocused, setReplyTo, @@ -49,11 +50,25 @@ export function initWebSocket(username, chatEl, inputContainer, usersListEl) { case "welcome": { // Initial user list. const myId = packet.data.you; + clearData(); setMyId(myId); const users = packet.data.users || []; users.forEach(({ id, username }) => addUser(id, username)); const groups = getGroupedUsers(); usersListEl.innerHTML = "Online: " + groups.join(", "); + // Replay chat history. + const history = packet.data.history || []; + history.forEach((raw) => { + try { + const histPkt = JSON.parse(raw); + if (histPkt.type === "msg-event") { + const { id, username: u, content, ts, parent } = histPkt.data; + addMessage({ id, username: u, content, ts, parent }); + } + } catch (e) { + console.error("Invalid history entry", raw); + } + }); //addNotice(`Users online: ${groups.join(", ")}`); break; } diff --git a/server/src/chat.c b/server/src/chat.c index 369ed24..d341f29 100644 --- a/server/src/chat.c +++ b/server/src/chat.c @@ -12,6 +12,13 @@ static size_t next_msg_id = 1; +// History buffer for last 100 messages. +#define HISTORY_SIZE 100 +static char* history[HISTORY_SIZE]; +static size_t history_len[HISTORY_SIZE]; +static size_t history_pos = 0; +static size_t history_count = 0; + #define CHAT_BUF_SIZE SESSION_CHAT_BUF_SIZE /* @@ -92,6 +99,7 @@ int cb_chat( if (session_has_username(s)) { yyjson_mut_val* uobj = yyjson_mut_obj(wdoc); yyjson_mut_arr_add_val(wusers, uobj); + yyjson_mut_arr_add_val(wusers, uobj); yyjson_mut_obj_add_uint( wdoc, uobj, "id", session_get_id(s) ); @@ -100,6 +108,19 @@ int cb_chat( ); } } + // Include last 100 messages in the welcome history array. + yyjson_mut_val* whist = yyjson_mut_arr(wdoc); + yyjson_mut_obj_add_val(wdoc, wdata, "history", whist); + for (size_t i = 0; i < history_count; ++i) { + size_t idx = + (history_pos + HISTORY_SIZE - history_count + i) % + HISTORY_SIZE; + // Append raw JSON string into history array. + yyjson_mut_val* raw = yyjson_mut_strn( + wdoc, history[idx], history_len[idx] + ); + yyjson_mut_arr_add_val(whist, raw); + } size_t out_len; char* out = yyjson_mut_write(wdoc, 0, &out_len); @@ -291,6 +312,15 @@ int cb_chat( size_t out_len; char* out = yyjson_mut_write(mdoc, 0, &out_len); + /* Store this msg-event JSON in the circular history buffer */ + if (history_count == HISTORY_SIZE) { + free(history[history_pos]); + } else { + history_count++; + } + history[history_pos] = strdup(out); + history_len[history_pos] = out_len; + history_pos = (history_pos + 1) % HISTORY_SIZE; size_t copy_len = out_len < SESSION_CHAT_BUF_SIZE ? out_len : SESSION_CHAT_BUF_SIZE;