diff options
| author | ilotterytea <iltsu@alright.party> | 2025-10-25 00:12:32 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-10-25 00:12:32 +0500 |
| commit | 21ea36b651f45863474059920d34716a44c09635 (patch) | |
| tree | 759517c83a033e8089dcc9bd3d34573aee823edf /scripts/chat.js | |
| parent | e77d6b63cbfc5a13a83d7a1badc56c7bf624895d (diff) | |
feat: parse irc message
Diffstat (limited to 'scripts/chat.js')
| -rw-r--r-- | scripts/chat.js | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/scripts/chat.js b/scripts/chat.js index d26a4ba..a845b06 100644 --- a/scripts/chat.js +++ b/scripts/chat.js @@ -1,19 +1,81 @@ -function addMessage(author, message) { +function parseIRCMessage(line) { + line = line.replace(/\r?\n$/, ''); + let tags = {}; + let prefix = null; + let nick = null; + let command = null; + const params = []; + + // tags + if (line[0] === '@') { + const end = line.indexOf(' '); + const rawTags = line.slice(1, end); + for (const tag of rawTags.split(';')) { + const [k, v = true] = tag.split('='); + tags[k] = v === true ? true : v; + } + line = line.slice(end + 1); + } + + // prefix + if (line[0] === ':') { + const end = line.indexOf(' '); + prefix = line.slice(1, end); + const bang = prefix.indexOf('!'); + if (bang !== -1) nick = prefix.slice(0, bang); + line = line.slice(end + 1); + } + + // command and params + const parts = line.split(' '); + command = parts.shift(); + for (let i = 0; i < parts.length; i++) { + if (parts[i][0] === ':') { + params.push(parts.slice(i).join(' ').slice(1)); + break; + } + if (parts[i].length) params.push(parts[i]); + } + + return { tags, prefix, nick, command, params }; +} + +function addMessage(message) { const messages = document.getElementById("messages"); - if (!messages) { + if (!messages || message.command != "PRIVMSG") { return; } + // msg base const elem = document.createElement("p"); elem.classList.add("message"); - elem.innerHTML = `<span class="author">${author}:</span> ${message}`; + // username + const usernameElem = document.createElement("span"); + elem.append(usernameElem); + if ("color" in message.tags) { + usernameElem.style.color = message.tags["color"]; + } + usernameElem.textContent = `${message.nick}:`; + + // message text + elem.innerHTML += ' ' + message.params[1]; messages.append(elem); window.scrollTo(0, document.body.scrollHeight); } +function addSystemMessage(message) { + addMessage({ + "params": ["#", message], + "nick": "System", + "prefix": "system", + "tags": {}, + "command": "PRIVMSG", + }); +} + function connectToChat(host, nick, password, room) { const socket = new WebSocket(host); @@ -22,7 +84,7 @@ function connectToChat(host, nick, password, room) { socket.send(`PASS ${password}`); socket.send("CAP REQ :twitch.tv/tags"); socket.send(`JOIN #${room}`); - addMessage("Chat", "Connected!"); + addSystemMessage("Connected to the chat!"); }); socket.addEventListener("message", (e) => { @@ -33,13 +95,13 @@ function connectToChat(host, nick, password, room) { if (l.length == 0) { continue; } - addMessage("Message", l); + addMessage(parseIRCMessage(l)); } }); socket.addEventListener("close", (e) => { - addMessage("Chat", `Disconnected: ${e.reason}`); - addMessage("Chat", "Reconnecting in 5 seconds..."); + addMessage("Chat", `Disconnected from the chat: ${e.reason}`); + addMessage("Chat", "Reconnecting to the chat in 5 seconds..."); setTimeout(() => connectToChat(host, nick, password, room), 5000); }); }
\ No newline at end of file |
