From e0c044a89424d0bce989f2713dfbc8a65d7fd1ef Mon Sep 17 00:00:00 2001 From: olcxja Date: Wed, 13 May 2026 22:15:06 +0200 Subject: [PATCH] Add cool animations and placeholder pfps --- .../src/main/assets/public/blah/en-us.json | 10 +- android/app/src/main/assets/public/index.html | 199 +++++++++------- .../src/main/assets/public/login/index.html | 1 - android/app/src/main/assets/public/main.js | 225 +++++++++++++++++- android/app/src/main/assets/public/style.css | 24 +- electron/assets/icon.png | Bin 14827 -> 14827 bytes icons/icon.png | Bin 14827 -> 14827 bytes webroot/blah/en-us.json | 10 +- webroot/index.html | 202 +++++++++------- webroot/login/index.html | 1 - webroot/main.js | 147 +++++++++++- webroot/pfpexamp.png | Bin 4698 -> 0 bytes webroot/style.css | 9 +- 13 files changed, 624 insertions(+), 204 deletions(-) delete mode 100644 webroot/pfpexamp.png 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 33f4e976..f6640451 100644 --- a/android/app/src/main/assets/public/blah/en-us.json +++ b/android/app/src/main/assets/public/blah/en-us.json @@ -36,5 +36,13 @@ "passwords.not.match": "Passwords do not match", "password.cant.empty": "Password cannot be empty", "username.cant.empty": "Username cannot be empty", - "bad.request": "Bad request" + "bad.request": "Bad request", + + "letters": "letters", + "numbers": "numbers", + "underscores": "underscores", + + "loading.connecting": "Connecting...", + "loading.loading": "Loading...", + "loading.done": "Ready!" } \ No newline at end of file diff --git a/android/app/src/main/assets/public/index.html b/android/app/src/main/assets/public/index.html index 41dc0412..a2f4078c 100644 --- a/android/app/src/main/assets/public/index.html +++ b/android/app/src/main/assets/public/index.html @@ -8,97 +8,119 @@ - - - - - - -
- - - - - -
-
- - - - Home - - - - - - - - - Splash - - +
- Welcome to Miarven -

First Larpix client. v1.0

+

-
-
- - + +
+ + + + + + + + + + + +
+
+ + + + + + + + + + +
+ + + + Home + + + + + + + + + Splash + + +
+ + Welcome to Miarven +

First Larpix client. v1.0

+
+
+
+ +
\ No newline at end of file diff --git a/android/app/src/main/assets/public/login/index.html b/android/app/src/main/assets/public/login/index.html index c844e976..aec3363c 100644 --- a/android/app/src/main/assets/public/login/index.html +++ b/android/app/src/main/assets/public/login/index.html @@ -478,6 +478,5 @@ } } - loginHostChanged(); \ No newline at end of file diff --git a/android/app/src/main/assets/public/main.js b/android/app/src/main/assets/public/main.js index f046bf40..c07412cc 100644 --- a/android/app/src/main/assets/public/main.js +++ b/android/app/src/main/assets/public/main.js @@ -24,7 +24,7 @@ var url = `${prot}//${window.location.hostname}/_larpix`; var params = new URLSearchParams(window.location.search); try { - + var loadingStatus = document.getElementById("loadingstatus"); var collapseDmsBtn = document.getElementById("collapse-dms"); var collapseGroupsBtn = document.getElementById("collapse-groups"); @@ -49,6 +49,21 @@ try { var roomContentBar = roomContent.children[0]; + var roomTopBar = document.getElementsByTagName("roomtopbar")[1]; + + var sidebarProfile = document.getElementById("sidebar-profile"); + var sidebarProfileButton = sidebarProfile.children.item(1); + var sidebarProfileIndicator = sidebarProfile.children.item(0); + + var sidebarPfp = sidebarProfileButton.children.item(0); + + + var sidebarInbox = document.getElementById("sidebar-inbox"); + var sidebarInboxButton = sidebarInbox.children.item(1); + var sidebarInboxIndicator = sidebarInbox.children.item(0); + + + } catch (e) { } @@ -439,6 +454,103 @@ async function hashSHA3_512(input) { return hashHex; } +//placeholder pfp +function getInitials(name) { + const cleanName = (name || "").trim(); + + //name empty + if (!cleanName) return ""; + + const parts = cleanName.split(/\s+/); + + //at least 2 words + if (parts.length >= 2) { + const firstInitial = parts[0][0]; + const secondInitial = parts[parts.length - 1][0]; //from last word + return (firstInitial + secondInitial).toUpperCase(); + } + + //only 1 word with 1 letter + const word = parts[0]; + if (word.length === 1) { + return word.toUpperCase(); + } + + //1 word at least 2 letters + return word.substring(0, 2).toUpperCase(); +} +function stringToColor(str) { + let hash = 0; + for (let i = 0; i < str.length; i++) { + hash = str.charCodeAt(i) + ((hash << 5) - hash); + } + const h = Math.abs(hash) % 360; + const s = 50; + const l = 65; + + return `hsl(${h}, ${s}%, ${l}%)`; +} +function createAvatarSvg(name, size = 512) { + const initials = getInitials(name); + const color = stringToColor(name); + + const svg = ` + + + + ${initials} + + + `.trim(); + return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`; +} + +async function getAvatarUrl(username) +{ + try { + let pfpUrl = `${url}/user/storage/public/getentry?u=${username}&e=larp.profile.pfp`; + if ((await fetchAsync(pfpUrl)) == "") + { + throw Error(); + } + return pfpUrl; + } + catch (e) { + return createAvatarSvg(username); + } +} + +function updateLoadingStatus(message) { + loadingStatus.innerHTML = processBlah(message); +} + +async function loadingFadeOut() { + let loadingScreen = document.querySelector("loading"); + let mainScreen = document.querySelector("main"); + + mainScreen.style.transform = "scale(0.85)"; + mainScreen.style.opacity = "0"; + + loadingScreen.style.transform = "scale(0.85)"; + loadingScreen.style.opacity = "0"; + await delay(200); + loadingScreen.style.display = "none"; + mainScreen.style.display = ""; + await delay(200); + mainScreen.style.transform = ""; + mainScreen.style.opacity = ""; + + +} + + var blah; async function initBlahs() { @@ -457,6 +569,10 @@ async function initBlahs() { function processBlah(blahmessage) { try { + if (!blahmessage.includes(":")) { + blahmessage = `:${blahmessage}`; + } + let split = blahmessage.split(":"); let values = []; try { @@ -468,10 +584,9 @@ function processBlah(blahmessage) { let valueslist = ""; for (let i = 0; i < values.length; i++) { - let value = values[i]; - valueslist+=`${values[i]}, `; - processBlah(value); - + let value = processBlah(values[i]); + valueslist+=`${value}, `; + message = message.replaceAll(`{${i}}`, value); } valueslist = valueslist.slice(0, -2); @@ -479,7 +594,6 @@ function processBlah(blahmessage) { message = message.replaceAll('{all}', valueslist); } - return message; } catch (e) @@ -505,6 +619,8 @@ async function mainJS() { if (localStorage.getItem('lang') != null) { lang = localStorage.getItem('lang'); } + + await start(); } username = localStorage.getItem('username'); password = localStorage.getItem('password'); @@ -518,7 +634,14 @@ collapseGroupsBtn.addEventListener("click", () => { collapseGroupsBtn.classList.toggle("collapsed"); }); -addDmBtn.addEventListener("click", () => { +addDmBtn.addEventListener("click", async () => { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + + roomTopBar.innerHTML = "Invite to dm"; + roomDetailsBar.style.display = "none"; + roomContentMain.innerHTML = `
@@ -528,7 +651,7 @@ addDmBtn.addEventListener("click", () => {
- +
- ` + `; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; }); -addGroupBtn.addEventListener("click", () => { - +addGroupBtn.addEventListener("click", async () => { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + + roomTopBar.innerHTML = "Create group"; + roomDetailsBar.style.display = "none"; + + roomContentMain.innerHTML = + ` +
+ + Create Group +

Create a private, encrypted group

+
+
+ + +
+
+ +
+
+ `; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; }); @@ -557,3 +708,55 @@ sidebarAddButton.addEventListener("mouseleave", () => { sidebarAddIndicator.classList.remove("hover"); }); +sidebarProfileButton.addEventListener("mouseenter", () => { + sidebarProfileIndicator.classList.add("hover"); +}); +sidebarProfileButton.addEventListener("mouseleave", () => { + sidebarProfileIndicator.classList.remove("hover"); +}); + +sidebarInboxButton.addEventListener("mouseenter", () => { + sidebarInboxIndicator.classList.add("hover"); +}); +sidebarInboxButton.addEventListener("mouseleave", () => { + sidebarInboxIndicator.classList.remove("hover"); +}); + + +function gotoSideProfilePopup() { + +} +function gotoInbox() { + +} +async function gotoCreateSpace() { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + + roomTopBar.innerHTML = "Create space"; + roomDetailsBar.style.display = "none"; + roomContentMain.innerHTML = + ` +
+ + Create Space +

Create a space for your community

+
+
+ + +
+
+ +
+
+ `; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; +} +function gotoHome() { + +} diff --git a/android/app/src/main/assets/public/style.css b/android/app/src/main/assets/public/style.css index 663eea28..03d3858c 100644 --- a/android/app/src/main/assets/public/style.css +++ b/android/app/src/main/assets/public/style.css @@ -40,9 +40,16 @@ html { body { padding-top: env(safe-area-inset-top); background-color: var(--main-bg-color); + overflow: hidden; +} +main, loading, body { display: flex; height: 100dvh; - overflow: hidden; +} +loading { + justify-content: center; + align-items: center; + width: 100%; } * { font-size: 1rem; @@ -68,6 +75,11 @@ button, input { align-items: center; justify-content: flex-start; border: var(--border-width) solid var(--light-border-color); + + backface-visibility: hidden; + transform: translateZ(0); + will-change: transform; + transform-origin: center center; } input { padding-left: calc(var(--button-margin) * 2); @@ -120,11 +132,16 @@ indicator.active { height: var(--icon-button-height); width: var(--icon-button-height); justify-content: center; + overflow: hidden; } .icon-button svg { width: var(--icon-button-size); height: var(--icon-button-size); } +.icon-button img { + width: calc(var(--icon-button-height) - (var(--border-width) * 2)); + height: calc(var(--icon-button-height) - (var(--border-width) * 2)); +} button:hover, input:hover { background-color: rgba(255, 255, 255, 0.1); } @@ -340,4 +357,9 @@ herotitle { .submit-button:hover { background-color: rgba(255, 255, 255, 0.5); +} + + +.bottom-element { + margin-top: auto; } \ No newline at end of file diff --git a/electron/assets/icon.png b/electron/assets/icon.png index eaeb16da04078b1c6989799c1c9c433cc32922f9..6132e9631a045a7ef113529fb531d429e3220aec 100644 GIT binary patch delta 87 zcmaD|{JMBT1G@;H&bP1q8XMd9SO^&zSQ(mFnV4uB7+4t?Y;TWmpB!o_k0yNV)^qF0 SZI()C!V}LQdop>Kr6B-H-yPWi delta 87 zcmaD|{JMBT13SAK;|KACdmG#LSO^)ITNzte85n9C7+4t??BDS;VRERYJeu&ir?Gb? Sw^=Ho3D5jc!#sJHr6B-C6dfo4 diff --git a/icons/icon.png b/icons/icon.png index eaeb16da04078b1c6989799c1c9c433cc32922f9..6132e9631a045a7ef113529fb531d429e3220aec 100644 GIT binary patch delta 87 zcmaD|{JMBT1G@;H&bP1q8XMd9SO^&zSQ(mFnV4uB7+4t?Y;TWmpB!o_k0yNV)^qF0 SZI()C!V}LQdop>Kr6B-H-yPWi delta 87 zcmaD|{JMBT13SAK;|KACdmG#LSO^)ITNzte85n9C7+4t??BDS;VRERYJeu&ir?Gb? Sw^=Ho3D5jc!#sJHr6B-C6dfo4 diff --git a/webroot/blah/en-us.json b/webroot/blah/en-us.json index 33f4e976..f6640451 100644 --- a/webroot/blah/en-us.json +++ b/webroot/blah/en-us.json @@ -36,5 +36,13 @@ "passwords.not.match": "Passwords do not match", "password.cant.empty": "Password cannot be empty", "username.cant.empty": "Username cannot be empty", - "bad.request": "Bad request" + "bad.request": "Bad request", + + "letters": "letters", + "numbers": "numbers", + "underscores": "underscores", + + "loading.connecting": "Connecting...", + "loading.loading": "Loading...", + "loading.done": "Ready!" } \ No newline at end of file diff --git a/webroot/index.html b/webroot/index.html index 4f7e103f..a2f4078c 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -8,104 +8,119 @@ - - - - - - -
- - - - - -
- - - - - -
- - - - Home - - - - - - - - - Splash - - +
- Welcome to Miarven -

First Larpix client. v1.0

+

-
-
- - + +
+ + + + + + + + + + + +
+
+ + + + + + + + + + +
+ + + + Home + + + + + + + + + Splash + + +
+ + Welcome to Miarven +

First Larpix client. v1.0

+
+
+
+ +
\ No newline at end of file diff --git a/webroot/login/index.html b/webroot/login/index.html index c844e976..aec3363c 100644 --- a/webroot/login/index.html +++ b/webroot/login/index.html @@ -478,6 +478,5 @@ } } - loginHostChanged(); \ No newline at end of file diff --git a/webroot/main.js b/webroot/main.js index c7572d02..c07412cc 100644 --- a/webroot/main.js +++ b/webroot/main.js @@ -24,7 +24,7 @@ var url = `${prot}//${window.location.hostname}/_larpix`; var params = new URLSearchParams(window.location.search); try { - + var loadingStatus = document.getElementById("loadingstatus"); var collapseDmsBtn = document.getElementById("collapse-dms"); var collapseGroupsBtn = document.getElementById("collapse-groups"); @@ -54,7 +54,10 @@ try { var sidebarProfile = document.getElementById("sidebar-profile"); var sidebarProfileButton = sidebarProfile.children.item(1); var sidebarProfileIndicator = sidebarProfile.children.item(0); - + + var sidebarPfp = sidebarProfileButton.children.item(0); + + var sidebarInbox = document.getElementById("sidebar-inbox"); var sidebarInboxButton = sidebarInbox.children.item(1); var sidebarInboxIndicator = sidebarInbox.children.item(0); @@ -451,6 +454,103 @@ async function hashSHA3_512(input) { return hashHex; } +//placeholder pfp +function getInitials(name) { + const cleanName = (name || "").trim(); + + //name empty + if (!cleanName) return ""; + + const parts = cleanName.split(/\s+/); + + //at least 2 words + if (parts.length >= 2) { + const firstInitial = parts[0][0]; + const secondInitial = parts[parts.length - 1][0]; //from last word + return (firstInitial + secondInitial).toUpperCase(); + } + + //only 1 word with 1 letter + const word = parts[0]; + if (word.length === 1) { + return word.toUpperCase(); + } + + //1 word at least 2 letters + return word.substring(0, 2).toUpperCase(); +} +function stringToColor(str) { + let hash = 0; + for (let i = 0; i < str.length; i++) { + hash = str.charCodeAt(i) + ((hash << 5) - hash); + } + const h = Math.abs(hash) % 360; + const s = 50; + const l = 65; + + return `hsl(${h}, ${s}%, ${l}%)`; +} +function createAvatarSvg(name, size = 512) { + const initials = getInitials(name); + const color = stringToColor(name); + + const svg = ` + + + + ${initials} + + + `.trim(); + return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`; +} + +async function getAvatarUrl(username) +{ + try { + let pfpUrl = `${url}/user/storage/public/getentry?u=${username}&e=larp.profile.pfp`; + if ((await fetchAsync(pfpUrl)) == "") + { + throw Error(); + } + return pfpUrl; + } + catch (e) { + return createAvatarSvg(username); + } +} + +function updateLoadingStatus(message) { + loadingStatus.innerHTML = processBlah(message); +} + +async function loadingFadeOut() { + let loadingScreen = document.querySelector("loading"); + let mainScreen = document.querySelector("main"); + + mainScreen.style.transform = "scale(0.85)"; + mainScreen.style.opacity = "0"; + + loadingScreen.style.transform = "scale(0.85)"; + loadingScreen.style.opacity = "0"; + await delay(200); + loadingScreen.style.display = "none"; + mainScreen.style.display = ""; + await delay(200); + mainScreen.style.transform = ""; + mainScreen.style.opacity = ""; + + +} + + var blah; async function initBlahs() { @@ -469,6 +569,10 @@ async function initBlahs() { function processBlah(blahmessage) { try { + if (!blahmessage.includes(":")) { + blahmessage = `:${blahmessage}`; + } + let split = blahmessage.split(":"); let values = []; try { @@ -480,10 +584,9 @@ function processBlah(blahmessage) { let valueslist = ""; for (let i = 0; i < values.length; i++) { - let value = values[i]; - valueslist+=`${values[i]}, `; - processBlah(value); - + let value = processBlah(values[i]); + valueslist+=`${value}, `; + message = message.replaceAll(`{${i}}`, value); } valueslist = valueslist.slice(0, -2); @@ -491,7 +594,6 @@ function processBlah(blahmessage) { message = message.replaceAll('{all}', valueslist); } - return message; } catch (e) @@ -517,6 +619,8 @@ async function mainJS() { if (localStorage.getItem('lang') != null) { lang = localStorage.getItem('lang'); } + + await start(); } username = localStorage.getItem('username'); password = localStorage.getItem('password'); @@ -530,9 +634,14 @@ collapseGroupsBtn.addEventListener("click", () => { collapseGroupsBtn.classList.toggle("collapsed"); }); -addDmBtn.addEventListener("click", () => { +addDmBtn.addEventListener("click", async () => { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + roomTopBar.innerHTML = "Invite to dm"; roomDetailsBar.style.display = "none"; + roomContentMain.innerHTML = `
@@ -551,10 +660,17 @@ addDmBtn.addEventListener("click", () => {
`; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; }); -addGroupBtn.addEventListener("click", () => { +addGroupBtn.addEventListener("click", async () => { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + roomTopBar.innerHTML = "Create group"; roomDetailsBar.style.display = "none"; + roomContentMain.innerHTML = `
@@ -573,6 +689,8 @@ addGroupBtn.addEventListener("click", () => {
`; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; }); @@ -608,7 +726,14 @@ sidebarInboxButton.addEventListener("mouseleave", () => { function gotoSideProfilePopup() { } -function gotoCreateSpace() { +function gotoInbox() { + +} +async function gotoCreateSpace() { + roomContentMain.style.transform = "scale(0.85)"; + roomContentMain.style.opacity = "0"; + await delay(200); + roomTopBar.innerHTML = "Create space"; roomDetailsBar.style.display = "none"; roomContentMain.innerHTML = @@ -629,6 +754,8 @@ function gotoCreateSpace() { `; + roomContentMain.style.transform = ""; + roomContentMain.style.opacity = ""; } function gotoHome() { diff --git a/webroot/pfpexamp.png b/webroot/pfpexamp.png deleted file mode 100644 index 416243bbb3641ff83ee7a8af7af77ebbe7db2ac5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4698 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 diff --git a/webroot/style.css b/webroot/style.css index 934879a8..03d3858c 100644 --- a/webroot/style.css +++ b/webroot/style.css @@ -40,9 +40,16 @@ html { body { padding-top: env(safe-area-inset-top); background-color: var(--main-bg-color); + overflow: hidden; +} +main, loading, body { display: flex; height: 100dvh; - overflow: hidden; +} +loading { + justify-content: center; + align-items: center; + width: 100%; } * { font-size: 1rem;