diff --git a/android/app/src/main/assets/public/index.html b/android/app/src/main/assets/public/index.html index 95451452..4bb6302c 100644 --- a/android/app/src/main/assets/public/index.html +++ b/android/app/src/main/assets/public/index.html @@ -109,6 +109,7 @@ //if fails continue loading encryption may be broken console.error(e); } + await delay(600); //because we need to wair for animations await refreshDms(); } else { showBlahNotification("error:auth.failed.redirect.to.login"); diff --git a/android/app/src/main/assets/public/main.js b/android/app/src/main/assets/public/main.js index d5eb05ad..309cfff4 100644 --- a/android/app/src/main/assets/public/main.js +++ b/android/app/src/main/assets/public/main.js @@ -1770,6 +1770,8 @@ async function openDm(dmId, username, targetId) { } } + await loadDmMessages(dmId); + setActiveRoombarItem(`dm-btn-${dmId}`); clearAction("dmopen"); } catch (e) { @@ -1777,4 +1779,89 @@ async function openDm(dmId, username, targetId) { console.error(e); showBlahNotification("error:dm.open.failed"); } +} + +async function loadDmMessages(dmId) { + try { + let payload = JSON.stringify({ string1: dmId, string2: "50", string3: "" }); + let res = await fetchEncrypted("dm/messages/get", payload); + + if (res && res.startsWith("error:")) { + showBlahNotification(res); + return; + } + + let messages = JSON.parse(res); + await renderMessages(messages); + } catch (e) { + console.error(e); + showBlahNotification("error:dm.messages.fetch.failed"); + } +} + +async function renderMessages(messages) { + let container = document.getElementById("chat-messages"); + if (!container) return; + + let entries = Object.entries(messages).sort((a,b) => parseInt(a[0]) - parseInt(b[0])); + + let html = ""; + let lastAuthor = null; + + for (let [msgId, msg] of entries) { + let content = msg.content; + + if (msg.key && msg.key !== "") { + try { + content = await decryptAesGcmFromBase64(content, currentDmKey); + } catch(e) { + content = `error:messages.decrypt.failed`; + } + } + content = content.replace(/\{blah\((.*?)\)\}/g, (match, p1) => { + return processBlah(p1); + }); + + // Also still process the whole thing in case it's just "dm.begin.notice" without {blah()} + content = processBlah(content); + + if (msg.type === "larp.info") { + html += `
${content}
`; + lastAuthor = null; + } else { + let showAvatar = lastAuthor !== msg.author; + lastAuthor = msg.author; + + let authorName = "Unknown"; + let pfp = "assets/default_avatar.png"; + if (msg.author !== "0") { + let fullUsername = await fetchAsync(`${url}/idtoname?id=${msg.author}`); + if (fullUsername && !fullUsername.startsWith("error:")) { + authorName = fullUsername.split(':')[0]; + pfp = await getAvatarUrl(msg.author, fullUsername); + } + } + + let date = new Date(parseInt(msg.timestamp)); + let timeStr = date.toLocaleString(); + + let extraClass = showAvatar ? "with-avatar" : ""; + + html += ` +
+ +
+ ${showAvatar ? `
+ ${authorName} + ${timeStr} +
` : ""} +
${content}
+
+
+ `; + } + } + + container.innerHTML = html; + container.scrollTop = container.scrollHeight; } \ No newline at end of file diff --git a/webroot/index.html b/webroot/index.html index 95451452..4bb6302c 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -109,6 +109,7 @@ //if fails continue loading encryption may be broken console.error(e); } + await delay(600); //because we need to wair for animations await refreshDms(); } else { showBlahNotification("error:auth.failed.redirect.to.login"); diff --git a/webroot/main.js b/webroot/main.js index d5eb05ad..309cfff4 100644 --- a/webroot/main.js +++ b/webroot/main.js @@ -1770,6 +1770,8 @@ async function openDm(dmId, username, targetId) { } } + await loadDmMessages(dmId); + setActiveRoombarItem(`dm-btn-${dmId}`); clearAction("dmopen"); } catch (e) { @@ -1777,4 +1779,89 @@ async function openDm(dmId, username, targetId) { console.error(e); showBlahNotification("error:dm.open.failed"); } +} + +async function loadDmMessages(dmId) { + try { + let payload = JSON.stringify({ string1: dmId, string2: "50", string3: "" }); + let res = await fetchEncrypted("dm/messages/get", payload); + + if (res && res.startsWith("error:")) { + showBlahNotification(res); + return; + } + + let messages = JSON.parse(res); + await renderMessages(messages); + } catch (e) { + console.error(e); + showBlahNotification("error:dm.messages.fetch.failed"); + } +} + +async function renderMessages(messages) { + let container = document.getElementById("chat-messages"); + if (!container) return; + + let entries = Object.entries(messages).sort((a,b) => parseInt(a[0]) - parseInt(b[0])); + + let html = ""; + let lastAuthor = null; + + for (let [msgId, msg] of entries) { + let content = msg.content; + + if (msg.key && msg.key !== "") { + try { + content = await decryptAesGcmFromBase64(content, currentDmKey); + } catch(e) { + content = `error:messages.decrypt.failed`; + } + } + content = content.replace(/\{blah\((.*?)\)\}/g, (match, p1) => { + return processBlah(p1); + }); + + // Also still process the whole thing in case it's just "dm.begin.notice" without {blah()} + content = processBlah(content); + + if (msg.type === "larp.info") { + html += `
${content}
`; + lastAuthor = null; + } else { + let showAvatar = lastAuthor !== msg.author; + lastAuthor = msg.author; + + let authorName = "Unknown"; + let pfp = "assets/default_avatar.png"; + if (msg.author !== "0") { + let fullUsername = await fetchAsync(`${url}/idtoname?id=${msg.author}`); + if (fullUsername && !fullUsername.startsWith("error:")) { + authorName = fullUsername.split(':')[0]; + pfp = await getAvatarUrl(msg.author, fullUsername); + } + } + + let date = new Date(parseInt(msg.timestamp)); + let timeStr = date.toLocaleString(); + + let extraClass = showAvatar ? "with-avatar" : ""; + + html += ` +
+ +
+ ${showAvatar ? `
+ ${authorName} + ${timeStr} +
` : ""} +
${content}
+
+
+ `; + } + } + + container.innerHTML = html; + container.scrollTop = container.scrollHeight; } \ No newline at end of file