Add cool animations and placeholder pfps

This commit is contained in:
olcxja 2026-05-13 22:15:06 +02:00
commit e0c044a894
13 changed files with 624 additions and 204 deletions

View file

@ -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 = `
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
<rect width="100%" height="100%" fill="${color}" />
<text
x="50%"
y="50%"
fill="white"
font-family="Nunito"
font-size="${size * 0.45}"
text-anchor="middle"
dy=".35em">
${initials}
</text>
</svg>
`.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 =
`
<div style="display: flex;justify-content: center;align-items: center;height:100%;flex-direction: column;text-align: center;">
@ -528,7 +651,7 @@ addDmBtn.addEventListener("click", () => {
<br>
<div class="input-group">
<label for="addchat-username">Username</label>
<input type="text" id="addchat-username" placeholder="@username:serverhost" class="forminput">
<input type="text" id="addchat-username" placeholder="username:serverhost" class="forminput">
</div>
<div class="input-group">
<button class="submit-button" onclick="addDm()">
@ -536,10 +659,38 @@ addDmBtn.addEventListener("click", () => {
</button>
</div>
</div>
`
`;
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 =
`
<div style="display: flex;justify-content: center;align-items: center;height:100%;flex-direction: column;text-align: center;">
<svg xmlns="http://www.w3.org/2000/svg" width="3rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M500-482q29-32 44.5-73t15.5-85q0-44-15.5-85T500-798q60 8 100 53t40 105q0 60-40 105t-100 53Zm220 322v-120q0-36-16-68.5T662-406q51 18 94.5 46.5T800-280v120h-80Zm80-280v-80h-80v-80h80v-80h80v80h80v80h-80v80h-80Zm-593-87q-47-47-47-113t47-113q47-47 113-47t113 47q47 47 47 113t-47 113q-47 47-113 47t-113-47ZM0-160v-112q0-34 17.5-62.5T64-378q62-31 126-46.5T320-440q66 0 130 15.5T576-378q29 15 46.5 43.5T640-272v112H0Zm320-400q33 0 56.5-23.5T400-640q0-33-23.5-56.5T320-720q-33 0-56.5 23.5T240-640q0 33 23.5 56.5T320-560ZM80-240h480v-32q0-11-5.5-20T540-306q-54-27-109-40.5T320-360q-56 0-111 13.5T100-306q-9 5-14.5 14T80-272v32Zm240-400Zm0 400Z"/></svg>
<herotitle>Create Group</herotitle>
<p>Create a private, encrypted group</p>
<br>
<div class="input-group">
<label for="creategroup-name">Name</label>
<input type="text" id="creategroup-name" placeholder="My group" class="forminput">
</div>
<div class="input-group">
<button class="submit-button" onclick="createGroup()">
Create group
</button>
</div>
</div>
`;
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 =
`
<div style="display: flex;justify-content: center;align-items: center;height:100%;flex-direction: column;text-align: center;">
<svg xmlns="http://www.w3.org/2000/svg" width="3rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M80-120v-720h400v160h400v320h-80v-240H480v80h80v80h-80v80h80v80h-80v80h160v80H80Zm80-80h80v-80h-80v80Zm0-160h80v-80h-80v80Zm0-160h80v-80h-80v80Zm0-160h80v-80h-80v80Zm160 480h80v-80h-80v80Zm0-160h80v-80h-80v80Zm0-160h80v-80h-80v80Zm0-160h80v-80h-80v80ZM800-40v-80h-80v-80h80v-80h80v80h80v80h-80v80h-80ZM640-440v-80h80v80h-80Zm0 160v-80h80v80h-80Z"/></svg>
<herotitle>Create Space</herotitle>
<p>Create a space for your community</p>
<br>
<div class="input-group">
<label for="addgroup-name">Name</label>
<input type="text" id="createspace-name" placeholder="My space" class="forminput">
</div>
<div class="input-group">
<button class="submit-button" onclick="createGroup()">
Create space
</button>
</div>
</div>
`;
roomContentMain.style.transform = "";
roomContentMain.style.opacity = "";
}
function gotoHome() {
}