add css kv var, move away from ssr ( multiple queries ), remove colors kv var, add option to disable logging per route

This commit is contained in:
creations 2025-04-25 21:20:08 -04:00
parent bd680ab607
commit 3b6c68c25d
Signed by: creations
GPG key ID: 8F553AA4320FC711
18 changed files with 571 additions and 667 deletions

View file

@ -353,13 +353,45 @@ if (badgeURL && badgeURL !== "null" && userId) {
});
}
function updatePresence(data) {
const avatarWrapper = document.querySelector(".avatar-wrapper");
const statusIndicator = avatarWrapper?.querySelector(".status-indicator");
const mobileIcon = avatarWrapper?.querySelector(".platform-icon.mobile-only");
async function updatePresence(data) {
const cssLink = data.kv?.css;
const userInfo = document.querySelector(".user-info");
const customStatus = userInfo?.querySelector(".custom-status");
if (cssLink) {
try {
const res = await fetch(`/api/css?url=${encodeURIComponent(cssLink)}`);
if (!res.ok) throw new Error("Failed to fetch CSS");
const cssText = await res.text();
const style = document.createElement("style");
style.textContent = cssText;
document.head.appendChild(style);
} catch (err) {
console.error("Failed to load CSS", err);
}
}
const avatarWrapper = document.querySelector(".avatar-wrapper");
const avatarImg = document.querySelector(".avatar-wrapper .avatar");
const usernameEl = document.querySelector(".username");
if (avatarImg && data.discord_user?.avatar) {
const newAvatarUrl = `https://cdn.discordapp.com/avatars/${data.discord_user.id}/${data.discord_user.avatar}`;
avatarImg.src = newAvatarUrl;
avatarImg.classList.remove("hidden");
const siteIcon = document.getElementById("site-icon");
if (siteIcon) {
siteIcon.href = newAvatarUrl;
}
}
if (usernameEl) {
const username =
data.discord_user.global_name || data.discord_user.username;
usernameEl.textContent = username;
document.title = username;
}
const platform = {
mobile: data.active_on_discord_mobile,
@ -374,37 +406,51 @@ function updatePresence(data) {
status = data.discord_status;
}
if (statusIndicator) {
statusIndicator.className = `status-indicator ${status}`;
}
let updatedStatusIndicator = avatarWrapper.querySelector(".status-indicator");
const updatedMobileIcon = avatarWrapper.querySelector(
".platform-icon.mobile-only",
);
if (platform.mobile && !mobileIcon) {
if (platform.mobile && !updatedMobileIcon) {
avatarWrapper.innerHTML += `
<svg class="platform-icon mobile-only ${status}" viewBox="0 0 1000 1500" fill="#43a25a" aria-label="Mobile" width="17" height="17">
<path d="M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z"/>
</svg>
`;
} else if (!platform.mobile && mobileIcon) {
mobileIcon.remove();
} else if (!platform.mobile && updatedMobileIcon) {
updatedMobileIcon.remove();
avatarWrapper.innerHTML += `<div class="status-indicator ${status}"></div>`;
}
const custom = data.activities?.find((a) => a.type === 4);
if (customStatus && custom) {
let emojiHTML = "";
const emoji = custom.emoji;
if (emoji?.id) {
const emojiUrl = `https://cdn.discordapp.com/emojis/${emoji.id}.${emoji.animated ? "gif" : "png"}`;
emojiHTML = `<img src="${emojiUrl}" alt="${emoji.name}" class="custom-emoji">`;
} else if (emoji?.name) {
emojiHTML = `${emoji.name} `;
}
customStatus.innerHTML = `
${emojiHTML}
${custom.state ? `<span class="custom-status-text">${custom.state}</span>` : ""}
`;
updatedStatusIndicator = avatarWrapper.querySelector(".status-indicator");
if (updatedStatusIndicator) {
updatedStatusIndicator.className = `status-indicator ${status}`;
}
const readmeSection = document.querySelector(".readme");
if (readmeSection && data.kv?.readme) {
const url = data.kv.readme;
try {
const res = await fetch(`/api/readme?url=${encodeURIComponent(url)}`);
if (!res.ok) throw new Error("Failed to fetch readme");
const text = await res.text();
readmeSection.innerHTML = `<div class="markdown-body">${text}</div>`;
readmeSection.classList.remove("hidden");
} catch (err) {
console.error("Failed to load README", err);
readmeSection.classList.add("hidden");
}
} else if (readmeSection) {
readmeSection.classList.add("hidden");
}
const custom = data.activities?.find((a) => a.type === 4);
updateCustomStatus(custom);
const filtered = data.activities
?.filter((a) => a.type !== 4)
?.sort((a, b) => {
@ -428,6 +474,47 @@ function updatePresence(data) {
updateElapsedAndProgress();
getAllNoAsset();
}
if (data.kv?.snow === "true") loadEffectScript("snow");
if (data.kv?.rain === "true") loadEffectScript("rain");
if (data.kv?.stars === "true") loadEffectScript("stars");
const loadingOverlay = document.getElementById("loading-overlay");
if (loadingOverlay) {
loadingOverlay.style.opacity = "0";
setTimeout(() => loadingOverlay.remove(), 500);
}
}
function updateCustomStatus(custom) {
const userInfoInner = document.querySelector(".user-info");
const customStatus = userInfoInner?.querySelector(".custom-status");
if (!userInfoInner) return;
if (custom) {
let emojiHTML = "";
if (custom.emoji?.id) {
const emojiUrl = `https://cdn.discordapp.com/emojis/${custom.emoji.id}.${custom.emoji.animated ? "gif" : "png"}`;
emojiHTML = `<img src="${emojiUrl}" alt="${custom.emoji.name}" class="custom-emoji">`;
} else if (custom.emoji?.name) {
emojiHTML = `${custom.emoji.name} `;
}
const html = `
<p class="custom-status">
${emojiHTML}${custom.state ? `<span class="custom-status-text">${custom.state}</span>` : ""}
</p>
`;
if (customStatus) {
customStatus.outerHTML = html;
} else {
userInfoInner.insertAdjacentHTML("beforeend", html);
}
} else if (customStatus) {
customStatus.remove();
}
}
async function getAllNoAsset() {
@ -454,3 +541,13 @@ async function getAllNoAsset() {
}
}
}
function loadEffectScript(effect) {
const existing = document.querySelector(`script[data-effect="${effect}"]`);
if (existing) return;
const script = document.createElement("script");
script.src = `/public/js/${effect}.js`;
script.dataset.effect = effect;
document.head.appendChild(script);
}

View file

@ -1,84 +1,82 @@
document.addEventListener("DOMContentLoaded", () => {
const snowContainer = document.createElement("div");
snowContainer.style.position = "fixed";
snowContainer.style.top = "0";
snowContainer.style.left = "0";
snowContainer.style.width = "100vw";
snowContainer.style.height = "100vh";
snowContainer.style.pointerEvents = "none";
document.body.appendChild(snowContainer);
const snowContainer = document.createElement("div");
snowContainer.style.position = "fixed";
snowContainer.style.top = "0";
snowContainer.style.left = "0";
snowContainer.style.width = "100vw";
snowContainer.style.height = "100vh";
snowContainer.style.pointerEvents = "none";
document.body.appendChild(snowContainer);
const maxSnowflakes = 60;
const snowflakes = [];
const mouse = { x: -100, y: -100 };
const maxSnowflakes = 60;
const snowflakes = [];
const mouse = { x: -100, y: -100 };
document.addEventListener("mousemove", (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
document.addEventListener("mousemove", (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
const createSnowflake = () => {
if (snowflakes.length >= maxSnowflakes) {
const oldestSnowflake = snowflakes.shift();
snowContainer.removeChild(oldestSnowflake);
}
const snowflake = document.createElement("div");
snowflake.classList.add("snowflake");
snowflake.style.position = "absolute";
snowflake.style.width = `${Math.random() * 3 + 2}px`;
snowflake.style.height = snowflake.style.width;
snowflake.style.background = "white";
snowflake.style.borderRadius = "50%";
snowflake.style.opacity = Math.random();
snowflake.style.left = `${Math.random() * window.innerWidth}px`;
snowflake.style.top = `-${snowflake.style.height}`;
snowflake.speed = Math.random() * 3 + 2;
snowflake.directionX = (Math.random() - 0.5) * 0.5;
snowflake.directionY = Math.random() * 0.5 + 0.5;
snowflakes.push(snowflake);
snowContainer.appendChild(snowflake);
};
setInterval(createSnowflake, 80);
function updateSnowflakes() {
snowflakes.forEach((snowflake, index) => {
const rect = snowflake.getBoundingClientRect();
const dx = rect.left + rect.width / 2 - mouse.x;
const dy = rect.top + rect.height / 2 - mouse.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
snowflake.directionX += (dx / distance) * 0.02;
snowflake.directionY += (dy / distance) * 0.02;
} else {
snowflake.directionX += (Math.random() - 0.5) * 0.01;
snowflake.directionY += (Math.random() - 0.5) * 0.01;
}
snowflake.style.left = `${rect.left + snowflake.directionX * snowflake.speed}px`;
snowflake.style.top = `${rect.top + snowflake.directionY * snowflake.speed}px`;
if (rect.top + rect.height >= window.innerHeight) {
snowContainer.removeChild(snowflake);
snowflakes.splice(index, 1);
}
if (
rect.left > window.innerWidth ||
rect.top > window.innerHeight ||
rect.left < 0
) {
snowflake.style.left = `${Math.random() * window.innerWidth}px`;
snowflake.style.top = `-${snowflake.style.height}`;
}
});
requestAnimationFrame(updateSnowflakes);
const createSnowflake = () => {
if (snowflakes.length >= maxSnowflakes) {
const oldestSnowflake = snowflakes.shift();
snowContainer.removeChild(oldestSnowflake);
}
updateSnowflakes();
});
const snowflake = document.createElement("div");
snowflake.classList.add("snowflake");
snowflake.style.position = "absolute";
snowflake.style.width = `${Math.random() * 3 + 2}px`;
snowflake.style.height = snowflake.style.width;
snowflake.style.background = "white";
snowflake.style.borderRadius = "50%";
snowflake.style.opacity = Math.random();
snowflake.style.left = `${Math.random() * window.innerWidth}px`;
snowflake.style.top = `-${snowflake.style.height}`;
snowflake.speed = Math.random() * 3 + 2;
snowflake.directionX = (Math.random() - 0.5) * 0.5;
snowflake.directionY = Math.random() * 0.5 + 0.5;
snowflakes.push(snowflake);
snowContainer.appendChild(snowflake);
};
setInterval(createSnowflake, 80);
function updateSnowflakes() {
snowflakes.forEach((snowflake, index) => {
const rect = snowflake.getBoundingClientRect();
const dx = rect.left + rect.width / 2 - mouse.x;
const dy = rect.top + rect.height / 2 - mouse.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
snowflake.directionX += (dx / distance) * 0.02;
snowflake.directionY += (dy / distance) * 0.02;
} else {
snowflake.directionX += (Math.random() - 0.5) * 0.01;
snowflake.directionY += (Math.random() - 0.5) * 0.01;
}
snowflake.style.left = `${rect.left + snowflake.directionX * snowflake.speed}px`;
snowflake.style.top = `${rect.top + snowflake.directionY * snowflake.speed}px`;
if (rect.top + rect.height >= window.innerHeight) {
snowContainer.removeChild(snowflake);
snowflakes.splice(index, 1);
}
if (
rect.left > window.innerWidth ||
rect.top > window.innerHeight ||
rect.left < 0
) {
snowflake.style.left = `${Math.random() * window.innerWidth}px`;
snowflake.style.top = `-${snowflake.style.height}`;
}
});
requestAnimationFrame(updateSnowflakes);
}
updateSnowflakes();

View file

@ -1,67 +1,65 @@
document.addEventListener("DOMContentLoaded", () => {
const container = document.createElement("div");
container.style.position = "fixed";
container.style.top = "0";
container.style.left = "0";
container.style.width = "100vw";
container.style.height = "100vh";
container.style.pointerEvents = "none";
container.style.overflow = "hidden";
container.style.zIndex = "9999";
document.body.appendChild(container);
const container = document.createElement("div");
container.style.position = "fixed";
container.style.top = "0";
container.style.left = "0";
container.style.width = "100vw";
container.style.height = "100vh";
container.style.pointerEvents = "none";
container.style.overflow = "hidden";
container.style.zIndex = "9999";
document.body.appendChild(container);
for (let i = 0; i < 60; i++) {
const star = document.createElement("div");
const size = Math.random() * 2 + 1;
star.style.position = "absolute";
star.style.width = `${size}px`;
star.style.height = `${size}px`;
star.style.background = "white";
star.style.borderRadius = "50%";
star.style.opacity = Math.random();
star.style.top = `${Math.random() * 100}vh`;
star.style.left = `${Math.random() * 100}vw`;
star.style.animation = `twinkle ${Math.random() * 3 + 2}s infinite alternate ease-in-out`;
container.appendChild(star);
}
for (let i = 0; i < 60; i++) {
const star = document.createElement("div");
const size = Math.random() * 2 + 1;
star.style.position = "absolute";
star.style.width = `${size}px`;
star.style.height = `${size}px`;
star.style.background = "white";
star.style.borderRadius = "50%";
star.style.opacity = Math.random();
star.style.top = `${Math.random() * 100}vh`;
star.style.left = `${Math.random() * 100}vw`;
star.style.animation = `twinkle ${Math.random() * 3 + 2}s infinite alternate ease-in-out`;
container.appendChild(star);
}
function createShootingStar() {
const star = document.createElement("div");
star.classList.add("shooting-star");
function createShootingStar() {
const star = document.createElement("div");
star.classList.add("shooting-star");
let x = Math.random() * window.innerWidth * 0.8;
let y = Math.random() * window.innerHeight * 0.3;
const angle = (Math.random() * Math.PI) / 6 + Math.PI / 8;
const speed = 10;
const totalFrames = 60;
let x = Math.random() * window.innerWidth * 0.8;
let y = Math.random() * window.innerHeight * 0.3;
const angle = (Math.random() * Math.PI) / 6 + Math.PI / 8;
const speed = 10;
const totalFrames = 60;
const deg = angle * (180 / Math.PI);
const deg = angle * (180 / Math.PI);
star.style.left = `${x}px`;
star.style.top = `${y}px`;
star.style.transform = `rotate(${deg}deg)`;
container.appendChild(star);
let frame = 0;
function animate() {
x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;
star.style.left = `${x}px`;
star.style.top = `${y}px`;
star.style.transform = `rotate(${deg}deg)`;
star.style.opacity = `${1 - frame / totalFrames}`;
container.appendChild(star);
let frame = 0;
function animate() {
x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;
star.style.left = `${x}px`;
star.style.top = `${y}px`;
star.style.opacity = `${1 - frame / totalFrames}`;
frame++;
if (frame < totalFrames) {
requestAnimationFrame(animate);
} else {
container.removeChild(star);
}
frame++;
if (frame < totalFrames) {
requestAnimationFrame(animate);
} else {
container.removeChild(star);
}
animate();
}
setInterval(() => {
if (Math.random() < 0.3) createShootingStar();
}, 1000);
});
animate();
}
setInterval(() => {
if (Math.random() < 0.3) createShootingStar();
}, 1000);