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 581ba1b5..d9e7e382 100644 --- a/android/app/src/main/assets/public/blah/en-cat.json +++ b/android/app/src/main/assets/public/blah/en-cat.json @@ -119,6 +119,12 @@ "title.invitation.code": "invitation code", "title.back.to.register": "back to registration", "placeholder.username": "cat name", - "placeholder.invitation.code": "invitation code", - "placeholder.captcha.code": "captcha code" + "placeholder.captcha.code": "captcha code", + "placeholder.message.input": "meow...", + "desc.messages.encryption.active": "meows are end-to-end encrypted :3", + "desc.no.dms": "no direct meowchats :c", + "action.dm.opening": "opening meowchat...", + "dm.open.failed": "failed to open meowchat :c", + "dm.messages.fetch.failed": "failed to fetch meows :c", + "messages.decrypt.failed": "failed to decrypt meow :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 d5d1df94..b222b3b2 100644 --- a/android/app/src/main/assets/public/blah/en-us.json +++ b/android/app/src/main/assets/public/blah/en-us.json @@ -118,6 +118,12 @@ "title.invitation.code": "Invitation code", "title.back.to.register": "Back to registration", "placeholder.username": "username", - "placeholder.invitation.code": "invitation code", - "placeholder.captcha.code": "captcha code" + "placeholder.captcha.code": "captcha code", + "placeholder.message.input": "Message...", + "desc.messages.encryption.active": "Messages are end-to-end encrypted", + "desc.no.dms": "No direct messages", + "action.dm.opening": "Opening DM...", + "dm.open.failed": "Failed to open DM", + "dm.messages.fetch.failed": "Failed to fetch messages", + "messages.decrypt.failed": "Failed to decrypt message" } diff --git a/android/app/src/main/assets/public/index.html b/android/app/src/main/assets/public/index.html index 4bb6302c..2ee7428c 100644 --- a/android/app/src/main/assets/public/index.html +++ b/android/app/src/main/assets/public/index.html @@ -109,8 +109,6 @@ //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"); await delay(2000); @@ -126,14 +124,19 @@ } } - async function refreshDms() { + async function refreshDms(waittime = 0) { try { showAction("action.dm.fetch", "dmrefresh"); + await delay(waittime); + if (window.cachedDms && typeof renderDms === 'function') { + await renderDms(window.cachedDms); + } let res = await fetchEncrypted("user/dm/list"); - clearAction("dmrefresh"); + window.cachedDms = res; if (typeof renderDms === 'function') { await renderDms(res); } + clearAction("dmrefresh"); } catch (e) { clearAction("dmrefresh"); diff --git a/android/app/src/main/assets/public/main.js b/android/app/src/main/assets/public/main.js index 309cfff4..1020d879 100644 --- a/android/app/src/main/assets/public/main.js +++ b/android/app/src/main/assets/public/main.js @@ -1235,16 +1235,27 @@ function clickCollapseDms() { var collapseDmsBtn = document.getElementById("collapse-dms"); collapseDmsBtn.classList.toggle("collapsed"); - var dmsList = document.getElementById("dms-list"); - if (dmsList) { - dmsList.style.display = collapseDmsBtn.classList.contains("collapsed") ? "none" : ""; + var dmsWrapper = document.getElementById("dms-wrapper"); + if (dmsWrapper) { + if (collapseDmsBtn.classList.contains("collapsed")) { + dmsWrapper.classList.add("collapsed"); + } else { + dmsWrapper.classList.remove("collapsed"); + } } } function clickCollapseGroups() { var collapseGroupsBtn = document.getElementById("collapse-groups"); - collapseGroupsBtn.classList.toggle("collapsed"); + var groupsWrapper = document.getElementById("groups-wrapper"); + if (groupsWrapper) { + if (collapseGroupsBtn.classList.contains("collapsed")) { + groupsWrapper.classList.add("collapsed"); + } else { + groupsWrapper.classList.remove("collapsed"); + } + } } function clickAddGroup() { @@ -1361,9 +1372,11 @@ async function renderInvites(res, type) { if (invite.type === "dm") { let id = invite.id; + if (!id.includes(":")) { id += `:${host}`; } + let onlyId = id.split(":")[0]; let username = await fetchAsync(`${url}/idtoname?id=${id}`); if (!(username && username.trim() !== "")) return; count++; @@ -1374,7 +1387,7 @@ async function renderInvites(res, type) { let desc = ""; if (type === "received") { - desc = `:desc.invite.dm.received:${username};${id}`; + desc = `:desc.invite.dm.received:${username};${onlyId}`; actions = ` @@ -1384,7 +1397,7 @@ async function renderInvites(res, type) { `; } else { - desc = `:desc.invite.dm.sent:${username};${id}`; + desc = `:desc.invite.dm.sent:${username};${onlyId}`; actions = ` @@ -1419,10 +1432,16 @@ async function renderInvites(res, type) { } } +window.cachedInvites = { 'received': null, 'sent': null }; + async function loadInvites(tab) { try { showAction(`action.fetching.invites.${tab === 'received' ? 'recv' : 'sent'}`, `fetching.invites.${tab}`); + if (window.cachedInvites[tab]) { + await renderInvites(window.cachedInvites[tab], tab); + } let res = await fetchEncrypted(`user/invites/${tab}`); + window.cachedInvites[tab] = res; await renderInvites(res, tab); } catch (e) { showBlahNotification("error:something.wrong"); @@ -1474,7 +1493,6 @@ async function acceptInvite(targetId) { //TODO: Implement key generation clearAction("invite.action"); showBlahNotification(res || "success:invite.accepted"); await loadInvites('received'); - await refreshDms(); } catch (e) { clearAction("invite.action"); showBlahNotification("error:something.wrong"); @@ -1551,12 +1569,13 @@ function gotoJoinSpace() { switchRoomContent("title.join.space", joinSpaceScreen, false); } -function gotoHome() { +async function gotoHome() { if (roomsBarContainer) roomsBarContainer.style.display = ""; //show roombar setActiveSidebarIndicator(sidebarHomeIndicator); switchRoomContent("title.splash", splashScreen, false); switchRoomsBar("title.home", homeRoomBar); setActiveRoombarItem(null); + await refreshDms(210); } function setActiveSidebarIndicator(element, isTemporary = false) { @@ -1714,9 +1733,9 @@ async function renderDms(res) { html += ` - + ${displayName} - ${targetUsername} + ${targetUsername} (${targetId.split(';')[0]}) `; @@ -1758,7 +1777,7 @@ async function openDm(dmId, username, targetId) { currentDmId = dmId; let pfp = await getAvatarUrl(targetId, username); - let iconHtml = ``; + let iconHtml = ``; await switchRoomContent(username.split(':')[0], chatScreen, false, iconHtml); let msgContainer = document.getElementById("chat-messages"); diff --git a/android/app/src/main/assets/public/screens.js b/android/app/src/main/assets/public/screens.js index d8a65380..67111acb 100644 --- a/android/app/src/main/assets/public/screens.js +++ b/android/app/src/main/assets/public/screens.js @@ -161,7 +161,11 @@ var homeRoomBar = ` - + + + + + @@ -179,6 +183,11 @@ var homeRoomBar = ` + + + + + `; var inboxRoomBar = ` diff --git a/android/app/src/main/assets/public/style.css b/android/app/src/main/assets/public/style.css index f43a5d96..f6631631 100644 --- a/android/app/src/main/assets/public/style.css +++ b/android/app/src/main/assets/public/style.css @@ -524,6 +524,24 @@ space{ opacity: 0.5; } +.list-container.no-flex-grow { + flex-grow: 0; +} + +.collapsible-wrapper { + display: grid; + grid-template-rows: 1fr; + transition: grid-template-rows 0.25s cubic-bezier(0.25, 1, 0.5, 1); +} + +.collapsible-wrapper.collapsed { + grid-template-rows: 0fr; +} + +.collapsible-inner { + overflow: hidden; +} + .invite-entry { display: flex; align-items: center; @@ -574,14 +592,15 @@ space{ .room-entry { display: flex; align-items: center; - gap: 0.8rem; - padding: 0.5rem 0.8rem; + gap: 0.1rem; + padding: 1.5rem 0.6rem; width: 100%; border: none; background: transparent; border-radius: 0.8rem; flex-shrink: 0; cursor: pointer; + margin: 0; } .room-pfp { width: 2.2rem; diff --git a/webroot/blah/en-cat.json b/webroot/blah/en-cat.json index 581ba1b5..d9e7e382 100644 --- a/webroot/blah/en-cat.json +++ b/webroot/blah/en-cat.json @@ -119,6 +119,12 @@ "title.invitation.code": "invitation code", "title.back.to.register": "back to registration", "placeholder.username": "cat name", - "placeholder.invitation.code": "invitation code", - "placeholder.captcha.code": "captcha code" + "placeholder.captcha.code": "captcha code", + "placeholder.message.input": "meow...", + "desc.messages.encryption.active": "meows are end-to-end encrypted :3", + "desc.no.dms": "no direct meowchats :c", + "action.dm.opening": "opening meowchat...", + "dm.open.failed": "failed to open meowchat :c", + "dm.messages.fetch.failed": "failed to fetch meows :c", + "messages.decrypt.failed": "failed to decrypt meow :c" } diff --git a/webroot/blah/en-us.json b/webroot/blah/en-us.json index d5d1df94..b222b3b2 100644 --- a/webroot/blah/en-us.json +++ b/webroot/blah/en-us.json @@ -118,6 +118,12 @@ "title.invitation.code": "Invitation code", "title.back.to.register": "Back to registration", "placeholder.username": "username", - "placeholder.invitation.code": "invitation code", - "placeholder.captcha.code": "captcha code" + "placeholder.captcha.code": "captcha code", + "placeholder.message.input": "Message...", + "desc.messages.encryption.active": "Messages are end-to-end encrypted", + "desc.no.dms": "No direct messages", + "action.dm.opening": "Opening DM...", + "dm.open.failed": "Failed to open DM", + "dm.messages.fetch.failed": "Failed to fetch messages", + "messages.decrypt.failed": "Failed to decrypt message" } diff --git a/webroot/index.html b/webroot/index.html index 4bb6302c..2ee7428c 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -109,8 +109,6 @@ //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"); await delay(2000); @@ -126,14 +124,19 @@ } } - async function refreshDms() { + async function refreshDms(waittime = 0) { try { showAction("action.dm.fetch", "dmrefresh"); + await delay(waittime); + if (window.cachedDms && typeof renderDms === 'function') { + await renderDms(window.cachedDms); + } let res = await fetchEncrypted("user/dm/list"); - clearAction("dmrefresh"); + window.cachedDms = res; if (typeof renderDms === 'function') { await renderDms(res); } + clearAction("dmrefresh"); } catch (e) { clearAction("dmrefresh"); diff --git a/webroot/main.js b/webroot/main.js index 309cfff4..1020d879 100644 --- a/webroot/main.js +++ b/webroot/main.js @@ -1235,16 +1235,27 @@ function clickCollapseDms() { var collapseDmsBtn = document.getElementById("collapse-dms"); collapseDmsBtn.classList.toggle("collapsed"); - var dmsList = document.getElementById("dms-list"); - if (dmsList) { - dmsList.style.display = collapseDmsBtn.classList.contains("collapsed") ? "none" : ""; + var dmsWrapper = document.getElementById("dms-wrapper"); + if (dmsWrapper) { + if (collapseDmsBtn.classList.contains("collapsed")) { + dmsWrapper.classList.add("collapsed"); + } else { + dmsWrapper.classList.remove("collapsed"); + } } } function clickCollapseGroups() { var collapseGroupsBtn = document.getElementById("collapse-groups"); - collapseGroupsBtn.classList.toggle("collapsed"); + var groupsWrapper = document.getElementById("groups-wrapper"); + if (groupsWrapper) { + if (collapseGroupsBtn.classList.contains("collapsed")) { + groupsWrapper.classList.add("collapsed"); + } else { + groupsWrapper.classList.remove("collapsed"); + } + } } function clickAddGroup() { @@ -1361,9 +1372,11 @@ async function renderInvites(res, type) { if (invite.type === "dm") { let id = invite.id; + if (!id.includes(":")) { id += `:${host}`; } + let onlyId = id.split(":")[0]; let username = await fetchAsync(`${url}/idtoname?id=${id}`); if (!(username && username.trim() !== "")) return; count++; @@ -1374,7 +1387,7 @@ async function renderInvites(res, type) { let desc = ""; if (type === "received") { - desc = `:desc.invite.dm.received:${username};${id}`; + desc = `:desc.invite.dm.received:${username};${onlyId}`; actions = ` @@ -1384,7 +1397,7 @@ async function renderInvites(res, type) { `; } else { - desc = `:desc.invite.dm.sent:${username};${id}`; + desc = `:desc.invite.dm.sent:${username};${onlyId}`; actions = ` @@ -1419,10 +1432,16 @@ async function renderInvites(res, type) { } } +window.cachedInvites = { 'received': null, 'sent': null }; + async function loadInvites(tab) { try { showAction(`action.fetching.invites.${tab === 'received' ? 'recv' : 'sent'}`, `fetching.invites.${tab}`); + if (window.cachedInvites[tab]) { + await renderInvites(window.cachedInvites[tab], tab); + } let res = await fetchEncrypted(`user/invites/${tab}`); + window.cachedInvites[tab] = res; await renderInvites(res, tab); } catch (e) { showBlahNotification("error:something.wrong"); @@ -1474,7 +1493,6 @@ async function acceptInvite(targetId) { //TODO: Implement key generation clearAction("invite.action"); showBlahNotification(res || "success:invite.accepted"); await loadInvites('received'); - await refreshDms(); } catch (e) { clearAction("invite.action"); showBlahNotification("error:something.wrong"); @@ -1551,12 +1569,13 @@ function gotoJoinSpace() { switchRoomContent("title.join.space", joinSpaceScreen, false); } -function gotoHome() { +async function gotoHome() { if (roomsBarContainer) roomsBarContainer.style.display = ""; //show roombar setActiveSidebarIndicator(sidebarHomeIndicator); switchRoomContent("title.splash", splashScreen, false); switchRoomsBar("title.home", homeRoomBar); setActiveRoombarItem(null); + await refreshDms(210); } function setActiveSidebarIndicator(element, isTemporary = false) { @@ -1714,9 +1733,9 @@ async function renderDms(res) { html += ` - + ${displayName} - ${targetUsername} + ${targetUsername} (${targetId.split(';')[0]}) `; @@ -1758,7 +1777,7 @@ async function openDm(dmId, username, targetId) { currentDmId = dmId; let pfp = await getAvatarUrl(targetId, username); - let iconHtml = ``; + let iconHtml = ``; await switchRoomContent(username.split(':')[0], chatScreen, false, iconHtml); let msgContainer = document.getElementById("chat-messages"); diff --git a/webroot/screens.js b/webroot/screens.js index d8a65380..67111acb 100644 --- a/webroot/screens.js +++ b/webroot/screens.js @@ -161,7 +161,11 @@ var homeRoomBar = ` - + + + + + @@ -179,6 +183,11 @@ var homeRoomBar = ` + + + + + `; var inboxRoomBar = ` diff --git a/webroot/style.css b/webroot/style.css index f43a5d96..f6631631 100644 --- a/webroot/style.css +++ b/webroot/style.css @@ -524,6 +524,24 @@ space{ opacity: 0.5; } +.list-container.no-flex-grow { + flex-grow: 0; +} + +.collapsible-wrapper { + display: grid; + grid-template-rows: 1fr; + transition: grid-template-rows 0.25s cubic-bezier(0.25, 1, 0.5, 1); +} + +.collapsible-wrapper.collapsed { + grid-template-rows: 0fr; +} + +.collapsible-inner { + overflow: hidden; +} + .invite-entry { display: flex; align-items: center; @@ -574,14 +592,15 @@ space{ .room-entry { display: flex; align-items: center; - gap: 0.8rem; - padding: 0.5rem 0.8rem; + gap: 0.1rem; + padding: 1.5rem 0.6rem; width: 100%; border: none; background: transparent; border-radius: 0.8rem; flex-shrink: 0; cursor: pointer; + margin: 0; } .room-pfp { width: 2.2rem;