From 92edb123f3685fc935e238dcfb8358e562951faf Mon Sep 17 00:00:00 2001 From: olcxja Date: Tue, 2 Jun 2026 12:53:41 +0200 Subject: [PATCH] working messages!!@!@ --- .../src/main/assets/public/blah/en-cat.json | 2 +- .../src/main/assets/public/blah/en-us.json | 2 +- android/app/src/main/assets/public/main.js | 90 ++++++++++++++++++- android/app/src/main/assets/public/screens.js | 3 +- android/app/src/main/assets/public/style.css | 10 +-- webroot/main.js | 88 +++++++++++++++++- webroot/screens.js | 2 +- webroot/style.css | 10 +-- 8 files changed, 189 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/assets/public/blah/en-cat.json b/android/app/src/main/assets/public/blah/en-cat.json index a41d1b4f..75fcf968 100644 --- a/android/app/src/main/assets/public/blah/en-cat.json +++ b/android/app/src/main/assets/public/blah/en-cat.json @@ -121,7 +121,7 @@ "placeholder.username": "cat name", "placeholder.captcha.code": "captcha code", "placeholder.message.input": "meow...", - "desc.messages.encryption.active": "meows are end-to-end encrypted :3", + "desc.messages.loading": "loading meows...", "desc.no.dms": "no direct meowchats :c", "action.dm.opening": "opening meowchat...", "dm.open.failed": "failed to open meowchat :c", diff --git a/android/app/src/main/assets/public/blah/en-us.json b/android/app/src/main/assets/public/blah/en-us.json index 31c45501..104354bb 100644 --- a/android/app/src/main/assets/public/blah/en-us.json +++ b/android/app/src/main/assets/public/blah/en-us.json @@ -120,7 +120,7 @@ "placeholder.username": "username", "placeholder.captcha.code": "captcha code", "placeholder.message.input": "Message...", - "desc.messages.encryption.active": "Messages are end-to-end encrypted", + "desc.messages.loading": "Fetching messages...", "desc.no.dms": "No direct messages", "action.dm.opening": "Opening DM...", "dm.open.failed": "Failed to open DM", diff --git a/android/app/src/main/assets/public/main.js b/android/app/src/main/assets/public/main.js index 084d54cb..868fe841 100644 --- a/android/app/src/main/assets/public/main.js +++ b/android/app/src/main/assets/public/main.js @@ -1645,6 +1645,7 @@ async function gotoHome() { switchRoomContent("title.splash", splashScreen, false); switchRoomsBar("title.home", homeRoomBar); setActiveRoombarItem(null); + setupWebSocket(); await refreshDms(210); } @@ -1852,7 +1853,7 @@ async function openDm(dmId, username, targetId) { let msgContainer = document.getElementById("chat-messages"); if (msgContainer) { - msgContainer.innerHTML = `
desc.messages.encryption.active
`; + msgContainer.innerHTML = `
desc.messages.loading
`; let blahTags = msgContainer.getElementsByTagName("blah"); for (let i = 0; i < blahTags.length; i++) { blahTags[i].innerHTML = processBlah(blahTags[i].innerHTML); @@ -1861,6 +1862,15 @@ async function openDm(dmId, username, targetId) { await loadDmMessages(dmId); + if (dmMessagePollInterval) clearInterval(dmMessagePollInterval); + dmMessagePollInterval = setInterval(() => { + if (currentDmId === dmId) { + loadDmMessages(dmId); + } else { + clearInterval(dmMessagePollInterval); + } + }, 15000); + setActiveRoombarItem(`dm-btn-${dmId}`); clearAction("dmopen"); } catch (e) { @@ -1906,7 +1916,8 @@ async function renderMessages(messages) { if (msg.key && msg.key !== "") { try { - content = await decryptAesGcmFromBase64(content, currentDmKey); + let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey)); + content = await decryptAesGcmFromBase64(content, dmKeyBytes); } catch(e) { content = `error:messages.decrypt.failed`; } @@ -1957,4 +1968,79 @@ async function renderMessages(messages) { container.innerHTML = html; container.scrollTop = container.scrollHeight; +} + +async function sendMessage() { + if (!currentDmId || !currentDmKey) return; + + let input = document.getElementById("chat-input"); + let content = input.value.trim(); + if (!content) return; + + try { + let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey)); + let encryptedContent = await encryptAesGcmToBase64(content, dmKeyBytes); + + let msgPayload = { + string1: currentDmId, + string2: encryptedContent, + string3: "" + }; + + input.value = ""; + + let res = await fetchEncrypted("dm/message/send", JSON.stringify(msgPayload)); + if (res && res.startsWith("error:")) { + showBlahNotification(res); + } else { + await loadDmMessages(currentDmId); + } + } catch (e) { + console.error(e); + showBlahNotification("error:message.send.failed"); + } +} + +function handleChatInputKey(event) { + if (event.key === "Enter" && !event.shiftKey) { + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + if (!isMobile) { + event.preventDefault(); + sendMessage(); + } + } +} + +let dmMessagePollInterval = null; +let appWebSocket = null; + +function setupWebSocket() { + if (appWebSocket && appWebSocket.readyState === WebSocket.OPEN) return; + + let wsUrl = url.replace(/^http/, "ws") + "/ws"; + appWebSocket = new WebSocket(wsUrl); + + appWebSocket.onopen = async () => { + try { + let nonce = await getNonce(id, passwordHash); + let secretEnc = await encryptWithNonce(passwordHash, passwordHash, nonce); + appWebSocket.send(JSON.stringify({ string1: id, string2: secretEnc })); + } catch (e) { + console.error("WS auth failed", e); + } + }; + + appWebSocket.onmessage = (event) => { + let data = event.data; + if (data.startsWith("dm_message:")) { + let msgDmId = data.substring("dm_message:".length); + if (currentDmId === msgDmId) { + loadDmMessages(msgDmId); + } + } + }; + + appWebSocket.onclose = () => { + setTimeout(setupWebSocket, 5000); + }; } \ No newline at end of file diff --git a/android/app/src/main/assets/public/screens.js b/android/app/src/main/assets/public/screens.js index 2dc7189f..bdd58c06 100644 --- a/android/app/src/main/assets/public/screens.js +++ b/android/app/src/main/assets/public/screens.js @@ -132,10 +132,9 @@ var invitesEntry = ` var chatScreen = `
-
- +