From 68ac0beedf0445bf5688da6a3243c314c0c1bbf5 Mon Sep 17 00:00:00 2001 From: olcxja Date: Sat, 4 Jul 2026 17:24:46 +0200 Subject: [PATCH] add message read/unread render & fix profile display --- .../src/main/assets/public/blah/en-cat.json | 6 +- .../src/main/assets/public/blah/en-us.json | 2 + android/app/src/main/assets/public/index.html | 8 +- android/app/src/main/assets/public/main.js | 143 ++++++++++++++++-- android/app/src/main/assets/public/screens.js | 2 +- android/app/src/main/assets/public/style.css | 3 + electron/assets/icon.png | Bin 14827 -> 14827 bytes icons/icon.png | Bin 14827 -> 14827 bytes webroot/blah/en-cat.json | 6 +- webroot/blah/en-us.json | 2 + webroot/index.html | 8 +- webroot/main.js | 143 ++++++++++++++++-- webroot/screens.js | 2 +- webroot/style.css | 3 + 14 files changed, 290 insertions(+), 38 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 bfd18b02..8051a7fb 100644 --- a/android/app/src/main/assets/public/blah/en-cat.json +++ b/android/app/src/main/assets/public/blah/en-cat.json @@ -147,8 +147,10 @@ "error:message.react.failed": "failed to add purr", "info.sending.message": "sending...", "placeholder.message.input": "meow...", - "larp.redacted": "this meow was hissed away.", - "placeholder.invitation.code": "invitation code meow", + "larp.redacted": "Meow meow was meowed.", + "message.already.deleted": "This meow has already been meowed.", + "rate.limit": "You are meowing too quickly. Please meow again later.", + "placeholder.invitation.code": "meow meow meow", "info.messages.loading.older": "Loading older meowsages...", "error:message.not.found": "Meowsage not found", "title.profile": "cat profile", 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 3aebb7f2..4d5c9155 100644 --- a/android/app/src/main/assets/public/blah/en-us.json +++ b/android/app/src/main/assets/public/blah/en-us.json @@ -145,6 +145,8 @@ "error:message.react.failed": "Failed to add reaction", "info.sending.message": "Sending...", "larp.redacted": "This message was deleted.", + "message.already.deleted": "This message has already been deleted.", + "rate.limit": "You are sending requests too quickly. Please try again later.", "placeholder.invitation.code": "invitation code", "info.messages.loading.older": "Loading older messages...", "error:message.not.found": "Message not found", diff --git a/android/app/src/main/assets/public/index.html b/android/app/src/main/assets/public/index.html index dd5bc391..a5daae41 100644 --- a/android/app/src/main/assets/public/index.html +++ b/android/app/src/main/assets/public/index.html @@ -157,9 +157,9 @@ } } - async function refreshDms(waittime = 0) { + async function refreshDms(waittime = 0, showLoading = true) { try { - showAction("action.dm.fetch", "dmrefresh"); + if (showLoading) showAction("action.dm.fetch", "dmrefresh"); await delay(waittime); if (window.cachedDms && typeof renderDms === 'function') { await renderDms(window.cachedDms); @@ -169,10 +169,10 @@ if (typeof renderDms === 'function') { await renderDms(res); } - clearAction("dmrefresh"); + if (showLoading) clearAction("dmrefresh"); } catch (e) { - clearAction("dmrefresh"); + if (showLoading) clearAction("dmrefresh"); showBlahNotification("error:dm.refresh.failed"); } } diff --git a/android/app/src/main/assets/public/main.js b/android/app/src/main/assets/public/main.js index ce9aae5c..8e5e81d0 100644 --- a/android/app/src/main/assets/public/main.js +++ b/android/app/src/main/assets/public/main.js @@ -1533,6 +1533,13 @@ async function openProfile(accountId) { try { if (!accountId) accountId = window.id; //var fallback + + if (accountId.endsWith(';' + host)) { + accountId = accountId.substring(0, accountId.length - host.length - 1); + } else if (accountId.endsWith(':' + host)) { + accountId = accountId.substring(0, accountId.length - host.length - 1); + } + let nameWithHost = await fetchAsync(`${url}/idtoname?id=${accountId}`); if (nameWithHost.startsWith("error:")) nameWithHost = accountId; //api fallback @@ -1632,7 +1639,7 @@ async function openProfile(accountId) {
${profileName}
-
${profileName}:${profileHost} (${accountId.split(':')[0]})
+
${profileName}:${profileHost} (${accountId.split(':')[0].split(';')[0]})
${bioHtml} ${actionBtnHtml} @@ -2098,11 +2105,14 @@ async function renderDms(res) { let pfp = await getAvatarUrl(targetId, targetUsername); let displayName = targetUsername.split(':')[0]; + let isRead = dmData.string3 === "true"; + let nameStyle = isRead ? "opacity: 0.8;" : "opacity: 1;"; + html += ` @@ -2188,6 +2198,8 @@ async function openDm(dmId, username, targetId) { try { showAction("action.dm.opening", "dmopen"); + markDmAsRead(dmId); + currentDmKey = await ensureDmRoomKey(dmId); if (!currentDmKey) { throw new Error("Missing DM room key"); @@ -2484,13 +2496,21 @@ async function renderMessages(messages, isPrepend = false) { container.innerHTML = html; + let targetScrollTop = 0; if (wasAtBottom) { - container.scrollTop = container.scrollHeight; + targetScrollTop = container.scrollHeight; } else if (isPrepend) { - container.scrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight); + targetScrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight); } else { - container.scrollTop = oldScrollTop; + targetScrollTop = oldScrollTop; } + + ignoreScroll = true; + container.scrollTop = targetScrollTop; + lastChatScroll = container.scrollHeight - targetScrollTop - container.clientHeight; + if (lastChatScroll < 0) lastChatScroll = 0; + + setTimeout(() => { ignoreScroll = false; }, 50); } var lastChatScroll = 0; @@ -2528,6 +2548,9 @@ function setupChatScrollListener() { if (!ignoreScroll) { isAdjusting = false; lastChatScroll = container.scrollHeight - container.scrollTop - container.clientHeight; + if (lastChatScroll <= 10) { + handleDmInteraction(); + } } if (container.scrollTop === 0 && !isLoadingOlderMessages && oldestLoadedMsgId !== null && oldestLoadedMsgId > 0) { @@ -2678,7 +2701,18 @@ function setupWebSocket() { appWebSocket.onmessage = (event) => { let data = event.data; if (data.startsWith("dm_message:")) { - let msgDmId = data.substring("dm_message:".length); + let parts = data.split(":"); + let msgDmId = parts[1]; + let msgType = parts[2] || "unread"; + + if (msgType === "unread") { + updateDmListUI(msgDmId, false, Date.now().toString()); + } else if (msgType === "read") { + updateDmListUI(msgDmId, true, Date.now().toString()); + } else if (msgType === "update") { + // do nothing to UI sorting/read state + } + if (currentDmId === msgDmId) { if (dmMessageLoadTimeout) clearTimeout(dmMessageLoadTimeout); dmMessageLoadTimeout = setTimeout(() => { @@ -2709,12 +2743,21 @@ function handleMessageContextMenu(e, msgId) { showFixedContextMenu({top: e.clientY, right: e.clientX, bottom: e.clientY, left: e.clientX}, messageContextMenu); let delBtn = fixedContextMenu.querySelector("#context-delete-btn"); - if (delBtn) { - if (loadedMessages[msgId] && loadedMessages[msgId].author !== id) { - delBtn.style.display = "none"; - } else { - delBtn.style.display = ""; + let reactBtn = fixedContextMenu.querySelector("#context-react-btn"); + let msg = loadedMessages[msgId]; + + if (msg && msg.type === "larp.redacted") { + if (delBtn) delBtn.style.display = "none"; + if (reactBtn) reactBtn.style.display = "none"; + } else { + if (delBtn) { + if (msg && msg.author !== id) { + delBtn.style.display = "none"; + } else { + delBtn.style.display = ""; + } } + if (reactBtn) reactBtn.style.display = ""; } } @@ -2895,6 +2938,11 @@ async function reactMessagePrompt(msgId, quickReaction = null) { showAction("action.message.reacting", "msgreact"); try { let currentMsg = loadedMessages[msgId]; + if (currentMsg && currentMsg.type === "larp.redacted") { + clearAction("msgreact"); + showNotification(processBlah("error.message.already.deleted"), "error"); + return; + } let existingReactions = []; if (currentMsg && currentMsg.reactions) { let rxStr = currentMsg.reactions; @@ -2922,7 +2970,9 @@ async function reactMessagePrompt(msgId, quickReaction = null) { let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey)); let encryptedReactions = await encryptAesGcmToBase64(JSON.stringify(existingReactions), dmKeyBytes); + let originalReactionsEncrypted = ""; if (currentMsg) { + originalReactionsEncrypted = currentMsg.reactions || ""; currentMsg.reactions = encryptedReactions; renderMessages(loadedMessages); } @@ -2935,6 +2985,10 @@ async function reactMessagePrompt(msgId, quickReaction = null) { let res = await fetchEncrypted("dm/message/react", JSON.stringify(msgPayload)); if (res && res.startsWith("error:")) { showBlahNotification(res); + if (currentMsg) { + currentMsg.reactions = originalReactionsEncrypted; + renderMessages(loadedMessages); + } } } catch (e) { showBlahNotification("error:message.react.failed"); @@ -3430,4 +3484,69 @@ if (container) { document.addEventListener('touchmove', onDrag, {passive: true}); document.addEventListener('mouseup', endDrag); document.addEventListener('touchend', endDrag); -} \ No newline at end of file +} + +function updateDmListUI(dmId, isRead, timestamp = null) { + try { + if (!window.cachedDms) return; + let parsedDms = JSON.parse(window.cachedDms); + if (!parsedDms.dms || !parsedDms.dms[dmId]) return; + + let changed = false; + if (parsedDms.dms[dmId].string3 !== (isRead ? "true" : "false")) { + parsedDms.dms[dmId].string3 = isRead ? "true" : "false"; + changed = true; + } + if (timestamp && parsedDms.dms[dmId].string2 !== timestamp) { + parsedDms.dms[dmId].string2 = timestamp; + changed = true; + } + + if (changed) { + window.cachedDms = JSON.stringify(parsedDms); + } + + let btn = document.getElementById(`dm-btn-${dmId}`); + let container = document.getElementById("dms-list"); + if (btn && container) { + let nameSpan = btn.querySelector('.room-name'); + if (nameSpan) { + nameSpan.style.opacity = isRead ? "0.8" : "1"; + } + if (timestamp) { + container.prepend(btn); + } + } else { + if (typeof refreshDms === 'function') refreshDms(0, false); + } + } catch (e) { + console.error(e); + if (typeof refreshDms === 'function') refreshDms(0, false); + } +} + +function markDmAsRead(dmId) { + fetchEncrypted("dm/read", JSON.stringify({string1: dmId})).catch(()=>{}); + updateDmListUI(dmId, true); +} + +function handleDmInteraction() { + if (!currentDmId) return; + let container = document.getElementById("chat-messages"); + if (!container) return; + + if (lastChatScroll <= 10) { + try { + if (window.cachedDms) { + let parsedDms = JSON.parse(window.cachedDms); + if (parsedDms.dms && parsedDms.dms[currentDmId] && parsedDms.dms[currentDmId].string3 !== "true") { + markDmAsRead(currentDmId); + } + } + } catch (e) {} + } +} + +document.addEventListener('click', handleDmInteraction); +document.addEventListener('keydown', handleDmInteraction); +document.addEventListener('touchstart', handleDmInteraction); \ 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 114c18d8..641fac88 100644 --- a/android/app/src/main/assets/public/screens.js +++ b/android/app/src/main/assets/public/screens.js @@ -245,7 +245,7 @@ var messageContextMenu = ` title.reply.message - diff --git a/android/app/src/main/assets/public/style.css b/android/app/src/main/assets/public/style.css index 5f6c3800..9de6967a 100644 --- a/android/app/src/main/assets/public/style.css +++ b/android/app/src/main/assets/public/style.css @@ -195,6 +195,7 @@ roomcontent { height: 100%; flex-grow: 1; + min-width: 0; border-right: var(--border-width) solid var(--light-border-color); } roomcontent2 { @@ -208,6 +209,7 @@ roomcontent2 { sidebar { display: flex; flex-direction: column; + flex-shrink: 0; height: 100%; width: calc(var(--icon-button-height) + (var(--button-margin) * 2) + var(--border-width)); @@ -217,6 +219,7 @@ sidebar.second { width: 17rem; min-width: 17rem; max-width: 17rem; + flex-shrink: 0; } .sidebar-section-header { display: flex; diff --git a/electron/assets/icon.png b/electron/assets/icon.png index 93a6c72a93c58f98326a8c189479b877169930cf..d332b59cc51c7d6472748947deaf6fd925861342 100644 GIT binary patch delta 84 zcmaD|{JMBT13SOCO3BoJl^fglS_qn285vs{n`s*uSQ!}Dxy?K;M1& delta 84 zcmaD|{JMBT13R}l&*inZ{%&mFYawW8Wol|=XrygmU}a#CvtjF>$)T1CsG_oOc^xLV RSt_H7di~IuKY5p>Apj-t96SI3 diff --git a/icons/icon.png b/icons/icon.png index 93a6c72a93c58f98326a8c189479b877169930cf..d332b59cc51c7d6472748947deaf6fd925861342 100644 GIT binary patch delta 84 zcmaD|{JMBT13SOCO3BoJl^fglS_qn285vs{n`s*uSQ!}Dxy?K;M1& delta 84 zcmaD|{JMBT13R}l&*inZ{%&mFYawW8Wol|=XrygmU}a#CvtjF>$)T1CsG_oOc^xLV RSt_H7di~IuKY5p>Apj-t96SI3 diff --git a/webroot/blah/en-cat.json b/webroot/blah/en-cat.json index bfd18b02..8051a7fb 100644 --- a/webroot/blah/en-cat.json +++ b/webroot/blah/en-cat.json @@ -147,8 +147,10 @@ "error:message.react.failed": "failed to add purr", "info.sending.message": "sending...", "placeholder.message.input": "meow...", - "larp.redacted": "this meow was hissed away.", - "placeholder.invitation.code": "invitation code meow", + "larp.redacted": "Meow meow was meowed.", + "message.already.deleted": "This meow has already been meowed.", + "rate.limit": "You are meowing too quickly. Please meow again later.", + "placeholder.invitation.code": "meow meow meow", "info.messages.loading.older": "Loading older meowsages...", "error:message.not.found": "Meowsage not found", "title.profile": "cat profile", diff --git a/webroot/blah/en-us.json b/webroot/blah/en-us.json index 3aebb7f2..4d5c9155 100644 --- a/webroot/blah/en-us.json +++ b/webroot/blah/en-us.json @@ -145,6 +145,8 @@ "error:message.react.failed": "Failed to add reaction", "info.sending.message": "Sending...", "larp.redacted": "This message was deleted.", + "message.already.deleted": "This message has already been deleted.", + "rate.limit": "You are sending requests too quickly. Please try again later.", "placeholder.invitation.code": "invitation code", "info.messages.loading.older": "Loading older messages...", "error:message.not.found": "Message not found", diff --git a/webroot/index.html b/webroot/index.html index dd5bc391..a5daae41 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -157,9 +157,9 @@ } } - async function refreshDms(waittime = 0) { + async function refreshDms(waittime = 0, showLoading = true) { try { - showAction("action.dm.fetch", "dmrefresh"); + if (showLoading) showAction("action.dm.fetch", "dmrefresh"); await delay(waittime); if (window.cachedDms && typeof renderDms === 'function') { await renderDms(window.cachedDms); @@ -169,10 +169,10 @@ if (typeof renderDms === 'function') { await renderDms(res); } - clearAction("dmrefresh"); + if (showLoading) clearAction("dmrefresh"); } catch (e) { - clearAction("dmrefresh"); + if (showLoading) clearAction("dmrefresh"); showBlahNotification("error:dm.refresh.failed"); } } diff --git a/webroot/main.js b/webroot/main.js index ce9aae5c..8e5e81d0 100644 --- a/webroot/main.js +++ b/webroot/main.js @@ -1533,6 +1533,13 @@ async function openProfile(accountId) { try { if (!accountId) accountId = window.id; //var fallback + + if (accountId.endsWith(';' + host)) { + accountId = accountId.substring(0, accountId.length - host.length - 1); + } else if (accountId.endsWith(':' + host)) { + accountId = accountId.substring(0, accountId.length - host.length - 1); + } + let nameWithHost = await fetchAsync(`${url}/idtoname?id=${accountId}`); if (nameWithHost.startsWith("error:")) nameWithHost = accountId; //api fallback @@ -1632,7 +1639,7 @@ async function openProfile(accountId) {
${profileName}
-
${profileName}:${profileHost} (${accountId.split(':')[0]})
+
${profileName}:${profileHost} (${accountId.split(':')[0].split(';')[0]})
${bioHtml} ${actionBtnHtml} @@ -2098,11 +2105,14 @@ async function renderDms(res) { let pfp = await getAvatarUrl(targetId, targetUsername); let displayName = targetUsername.split(':')[0]; + let isRead = dmData.string3 === "true"; + let nameStyle = isRead ? "opacity: 0.8;" : "opacity: 1;"; + html += ` @@ -2188,6 +2198,8 @@ async function openDm(dmId, username, targetId) { try { showAction("action.dm.opening", "dmopen"); + markDmAsRead(dmId); + currentDmKey = await ensureDmRoomKey(dmId); if (!currentDmKey) { throw new Error("Missing DM room key"); @@ -2484,13 +2496,21 @@ async function renderMessages(messages, isPrepend = false) { container.innerHTML = html; + let targetScrollTop = 0; if (wasAtBottom) { - container.scrollTop = container.scrollHeight; + targetScrollTop = container.scrollHeight; } else if (isPrepend) { - container.scrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight); + targetScrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight); } else { - container.scrollTop = oldScrollTop; + targetScrollTop = oldScrollTop; } + + ignoreScroll = true; + container.scrollTop = targetScrollTop; + lastChatScroll = container.scrollHeight - targetScrollTop - container.clientHeight; + if (lastChatScroll < 0) lastChatScroll = 0; + + setTimeout(() => { ignoreScroll = false; }, 50); } var lastChatScroll = 0; @@ -2528,6 +2548,9 @@ function setupChatScrollListener() { if (!ignoreScroll) { isAdjusting = false; lastChatScroll = container.scrollHeight - container.scrollTop - container.clientHeight; + if (lastChatScroll <= 10) { + handleDmInteraction(); + } } if (container.scrollTop === 0 && !isLoadingOlderMessages && oldestLoadedMsgId !== null && oldestLoadedMsgId > 0) { @@ -2678,7 +2701,18 @@ function setupWebSocket() { appWebSocket.onmessage = (event) => { let data = event.data; if (data.startsWith("dm_message:")) { - let msgDmId = data.substring("dm_message:".length); + let parts = data.split(":"); + let msgDmId = parts[1]; + let msgType = parts[2] || "unread"; + + if (msgType === "unread") { + updateDmListUI(msgDmId, false, Date.now().toString()); + } else if (msgType === "read") { + updateDmListUI(msgDmId, true, Date.now().toString()); + } else if (msgType === "update") { + // do nothing to UI sorting/read state + } + if (currentDmId === msgDmId) { if (dmMessageLoadTimeout) clearTimeout(dmMessageLoadTimeout); dmMessageLoadTimeout = setTimeout(() => { @@ -2709,12 +2743,21 @@ function handleMessageContextMenu(e, msgId) { showFixedContextMenu({top: e.clientY, right: e.clientX, bottom: e.clientY, left: e.clientX}, messageContextMenu); let delBtn = fixedContextMenu.querySelector("#context-delete-btn"); - if (delBtn) { - if (loadedMessages[msgId] && loadedMessages[msgId].author !== id) { - delBtn.style.display = "none"; - } else { - delBtn.style.display = ""; + let reactBtn = fixedContextMenu.querySelector("#context-react-btn"); + let msg = loadedMessages[msgId]; + + if (msg && msg.type === "larp.redacted") { + if (delBtn) delBtn.style.display = "none"; + if (reactBtn) reactBtn.style.display = "none"; + } else { + if (delBtn) { + if (msg && msg.author !== id) { + delBtn.style.display = "none"; + } else { + delBtn.style.display = ""; + } } + if (reactBtn) reactBtn.style.display = ""; } } @@ -2895,6 +2938,11 @@ async function reactMessagePrompt(msgId, quickReaction = null) { showAction("action.message.reacting", "msgreact"); try { let currentMsg = loadedMessages[msgId]; + if (currentMsg && currentMsg.type === "larp.redacted") { + clearAction("msgreact"); + showNotification(processBlah("error.message.already.deleted"), "error"); + return; + } let existingReactions = []; if (currentMsg && currentMsg.reactions) { let rxStr = currentMsg.reactions; @@ -2922,7 +2970,9 @@ async function reactMessagePrompt(msgId, quickReaction = null) { let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey)); let encryptedReactions = await encryptAesGcmToBase64(JSON.stringify(existingReactions), dmKeyBytes); + let originalReactionsEncrypted = ""; if (currentMsg) { + originalReactionsEncrypted = currentMsg.reactions || ""; currentMsg.reactions = encryptedReactions; renderMessages(loadedMessages); } @@ -2935,6 +2985,10 @@ async function reactMessagePrompt(msgId, quickReaction = null) { let res = await fetchEncrypted("dm/message/react", JSON.stringify(msgPayload)); if (res && res.startsWith("error:")) { showBlahNotification(res); + if (currentMsg) { + currentMsg.reactions = originalReactionsEncrypted; + renderMessages(loadedMessages); + } } } catch (e) { showBlahNotification("error:message.react.failed"); @@ -3430,4 +3484,69 @@ if (container) { document.addEventListener('touchmove', onDrag, {passive: true}); document.addEventListener('mouseup', endDrag); document.addEventListener('touchend', endDrag); -} \ No newline at end of file +} + +function updateDmListUI(dmId, isRead, timestamp = null) { + try { + if (!window.cachedDms) return; + let parsedDms = JSON.parse(window.cachedDms); + if (!parsedDms.dms || !parsedDms.dms[dmId]) return; + + let changed = false; + if (parsedDms.dms[dmId].string3 !== (isRead ? "true" : "false")) { + parsedDms.dms[dmId].string3 = isRead ? "true" : "false"; + changed = true; + } + if (timestamp && parsedDms.dms[dmId].string2 !== timestamp) { + parsedDms.dms[dmId].string2 = timestamp; + changed = true; + } + + if (changed) { + window.cachedDms = JSON.stringify(parsedDms); + } + + let btn = document.getElementById(`dm-btn-${dmId}`); + let container = document.getElementById("dms-list"); + if (btn && container) { + let nameSpan = btn.querySelector('.room-name'); + if (nameSpan) { + nameSpan.style.opacity = isRead ? "0.8" : "1"; + } + if (timestamp) { + container.prepend(btn); + } + } else { + if (typeof refreshDms === 'function') refreshDms(0, false); + } + } catch (e) { + console.error(e); + if (typeof refreshDms === 'function') refreshDms(0, false); + } +} + +function markDmAsRead(dmId) { + fetchEncrypted("dm/read", JSON.stringify({string1: dmId})).catch(()=>{}); + updateDmListUI(dmId, true); +} + +function handleDmInteraction() { + if (!currentDmId) return; + let container = document.getElementById("chat-messages"); + if (!container) return; + + if (lastChatScroll <= 10) { + try { + if (window.cachedDms) { + let parsedDms = JSON.parse(window.cachedDms); + if (parsedDms.dms && parsedDms.dms[currentDmId] && parsedDms.dms[currentDmId].string3 !== "true") { + markDmAsRead(currentDmId); + } + } + } catch (e) {} + } +} + +document.addEventListener('click', handleDmInteraction); +document.addEventListener('keydown', handleDmInteraction); +document.addEventListener('touchstart', handleDmInteraction); \ No newline at end of file diff --git a/webroot/screens.js b/webroot/screens.js index 114c18d8..641fac88 100644 --- a/webroot/screens.js +++ b/webroot/screens.js @@ -245,7 +245,7 @@ var messageContextMenu = ` title.reply.message - diff --git a/webroot/style.css b/webroot/style.css index 5f6c3800..9de6967a 100644 --- a/webroot/style.css +++ b/webroot/style.css @@ -195,6 +195,7 @@ roomcontent { height: 100%; flex-grow: 1; + min-width: 0; border-right: var(--border-width) solid var(--light-border-color); } roomcontent2 { @@ -208,6 +209,7 @@ roomcontent2 { sidebar { display: flex; flex-direction: column; + flex-shrink: 0; height: 100%; width: calc(var(--icon-button-height) + (var(--button-margin) * 2) + var(--border-width)); @@ -217,6 +219,7 @@ sidebar.second { width: 17rem; min-width: 17rem; max-width: 17rem; + flex-shrink: 0; } .sidebar-section-header { display: flex;