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:
parent
bd680ab607
commit
3b6c68c25d
18 changed files with 571 additions and 667 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue