forked from creations/profilePage
add rain and snow kv options fix issue with activity header not showing when no initial activity
This commit is contained in:
parent
66744ddd10
commit
78c2eb4545
7 changed files with 319 additions and 133 deletions
|
@ -40,6 +40,30 @@ body {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.snowflake {
|
||||||
|
position: absolute;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.raindrop {
|
||||||
|
position: absolute;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-header.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.user-card {
|
.user-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -291,7 +291,6 @@ function updatePresence(data) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let status = "offline";
|
let status = "offline";
|
||||||
console.log(data.activities.some((activity) => activity.type === 1));
|
|
||||||
if (data.activities.some((activity) => activity.type === 1)) {
|
if (data.activities.some((activity) => activity.type === 1)) {
|
||||||
status = "streaming";
|
status = "streaming";
|
||||||
} else {
|
} else {
|
||||||
|
@ -339,11 +338,15 @@ function updatePresence(data) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const activityList = document.querySelector(".activities");
|
const activityList = document.querySelector(".activities");
|
||||||
|
const activitiesTitle = document.querySelector(".activity-header");
|
||||||
|
|
||||||
if (activityList) {
|
if (activityList && activitiesTitle) {
|
||||||
activityList.innerHTML = "";
|
|
||||||
if (filtered?.length) {
|
if (filtered?.length) {
|
||||||
activityList.innerHTML = filtered.map(buildActivityHTML).join("");
|
activityList.innerHTML = filtered.map(buildActivityHTML).join("");
|
||||||
|
activitiesTitle.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
activityList.innerHTML = "";
|
||||||
|
activitiesTitle.classList.add("hidden");
|
||||||
}
|
}
|
||||||
updateElapsedAndProgress();
|
updateElapsedAndProgress();
|
||||||
}
|
}
|
||||||
|
|
77
public/js/rain.js
Normal file
77
public/js/rain.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
const rainContainer = document.createElement("div");
|
||||||
|
rainContainer.style.position = "fixed";
|
||||||
|
rainContainer.style.top = "0";
|
||||||
|
rainContainer.style.left = "0";
|
||||||
|
rainContainer.style.width = "100vw";
|
||||||
|
rainContainer.style.height = "100vh";
|
||||||
|
rainContainer.style.pointerEvents = "none";
|
||||||
|
document.body.appendChild(rainContainer);
|
||||||
|
|
||||||
|
const maxRaindrops = 100;
|
||||||
|
const raindrops = [];
|
||||||
|
const mouse = { x: -100, y: -100 };
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", (e) => {
|
||||||
|
mouse.x = e.clientX;
|
||||||
|
mouse.y = e.clientY;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getRaindropColor = () => {
|
||||||
|
const htmlTag = document.documentElement;
|
||||||
|
return htmlTag.getAttribute("data-theme") === "dark"
|
||||||
|
? "rgba(173, 216, 230, 0.8)"
|
||||||
|
: "rgba(70, 130, 180, 0.8)";
|
||||||
|
};
|
||||||
|
|
||||||
|
const createRaindrop = () => {
|
||||||
|
if (raindrops.length >= maxRaindrops) {
|
||||||
|
const oldestRaindrop = raindrops.shift();
|
||||||
|
rainContainer.removeChild(oldestRaindrop);
|
||||||
|
}
|
||||||
|
|
||||||
|
const raindrop = document.createElement("div");
|
||||||
|
raindrop.classList.add("raindrop");
|
||||||
|
raindrop.style.position = "absolute";
|
||||||
|
raindrop.style.width = "2px";
|
||||||
|
raindrop.style.height = `${Math.random() * 10 + 10}px`;
|
||||||
|
raindrop.style.background = getRaindropColor();
|
||||||
|
raindrop.style.borderRadius = "1px";
|
||||||
|
raindrop.style.left = `${Math.random() * window.innerWidth}px`;
|
||||||
|
raindrop.style.top = `-${raindrop.style.height}`;
|
||||||
|
raindrop.style.opacity = Math.random() * 0.5 + 0.3;
|
||||||
|
raindrop.speed = Math.random() * 6 + 4;
|
||||||
|
raindrop.directionX = (Math.random() - 0.5) * 0.2;
|
||||||
|
raindrop.directionY = Math.random() * 0.5 + 0.8;
|
||||||
|
|
||||||
|
raindrops.push(raindrop);
|
||||||
|
rainContainer.appendChild(raindrop);
|
||||||
|
};
|
||||||
|
|
||||||
|
setInterval(createRaindrop, 50);
|
||||||
|
|
||||||
|
function updateRaindrops() {
|
||||||
|
raindrops.forEach((raindrop, index) => {
|
||||||
|
const rect = raindrop.getBoundingClientRect();
|
||||||
|
|
||||||
|
raindrop.style.left = `${rect.left + raindrop.directionX * raindrop.speed}px`;
|
||||||
|
raindrop.style.top = `${rect.top + raindrop.directionY * raindrop.speed}px`;
|
||||||
|
|
||||||
|
if (rect.top + rect.height >= window.innerHeight) {
|
||||||
|
rainContainer.removeChild(raindrop);
|
||||||
|
raindrops.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
rect.left > window.innerWidth ||
|
||||||
|
rect.top > window.innerHeight ||
|
||||||
|
rect.left < 0
|
||||||
|
) {
|
||||||
|
raindrop.style.left = `${Math.random() * window.innerWidth}px`;
|
||||||
|
raindrop.style.top = `-${raindrop.style.height}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
requestAnimationFrame(updateRaindrops);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRaindrops();
|
84
public/js/snow.js
Normal file
84
public/js/snow.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
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 maxSnowflakes = 60;
|
||||||
|
const snowflakes = [];
|
||||||
|
const mouse = { x: -100, y: -100 };
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSnowflakes();
|
||||||
|
});
|
|
@ -52,6 +52,8 @@ async function handler(request: ExtendedRequest): Promise<Response> {
|
||||||
},
|
},
|
||||||
instance,
|
instance,
|
||||||
readme,
|
readme,
|
||||||
|
allowSnow: presence.kv.snow || false,
|
||||||
|
allowRain: presence.kv.rain || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return await renderEjsTemplate("index", ejsTemplateData);
|
return await renderEjsTemplate("index", ejsTemplateData);
|
||||||
|
|
|
@ -51,6 +51,8 @@ async function handler(): Promise<Response> {
|
||||||
},
|
},
|
||||||
instance,
|
instance,
|
||||||
readme,
|
readme,
|
||||||
|
allowSnow: presence.kv.snow || false,
|
||||||
|
allowRain: presence.kv.rain || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return await renderEjsTemplate("index", ejsTemplateData);
|
return await renderEjsTemplate("index", ejsTemplateData);
|
||||||
|
|
|
@ -13,6 +13,13 @@
|
||||||
<link rel="stylesheet" href="/public/css/index.css">
|
<link rel="stylesheet" href="/public/css/index.css">
|
||||||
<script src="/public/js/index.js" defer></script>
|
<script src="/public/js/index.js" defer></script>
|
||||||
|
|
||||||
|
<% if (allowSnow) { %>
|
||||||
|
<script src="/public/js/snow.js" defer></script>
|
||||||
|
<% } %>
|
||||||
|
<% if(allowRain) { %>
|
||||||
|
<script src="/public/js/rain.js" defer></script>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<meta name="color-scheme" content="dark">
|
<meta name="color-scheme" content="dark">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -59,14 +66,14 @@
|
||||||
let filtered = activities
|
let filtered = activities
|
||||||
.filter(a => a.type !== 4)
|
.filter(a => a.type !== 4)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const priority = { 2: 0, 1: 1, 3: 2 }; // Listening, Streaming, Watching ? should i keep this
|
const priority = { 2: 0, 1: 1, 3: 2 };
|
||||||
const aPriority = priority[a.type] ?? 99;
|
const aPriority = priority[a.type] ?? 99;
|
||||||
const bPriority = priority[b.type] ?? 99;
|
const bPriority = priority[b.type] ?? 99;
|
||||||
return aPriority - bPriority;
|
return aPriority - bPriority;
|
||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
<% if (filtered.length > 0) { %>
|
|
||||||
<h2>Activities</h2>
|
<h2 class="activity-header <%= filtered.length === 0 ? 'hidden' : '' %>">Activities</h2>
|
||||||
<ul class="activities">
|
<ul class="activities">
|
||||||
<% filtered.forEach(activity => {
|
<% filtered.forEach(activity => {
|
||||||
const start = activity.timestamps?.start;
|
const start = activity.timestamps?.start;
|
||||||
|
@ -81,20 +88,16 @@
|
||||||
|
|
||||||
function resolveActivityImage(img, applicationId) {
|
function resolveActivityImage(img, applicationId) {
|
||||||
if (!img) return null;
|
if (!img) return null;
|
||||||
|
|
||||||
if (img.startsWith("mp:external/")) {
|
if (img.startsWith("mp:external/")) {
|
||||||
return `https://media.discordapp.net/external/${img.slice("mp:external/".length)}`;
|
return `https://media.discordapp.net/external/${img.slice("mp:external/".length)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img.includes("/https/")) {
|
if (img.includes("/https/")) {
|
||||||
const clean = img.split("/https/")[1];
|
const clean = img.split("/https/")[1];
|
||||||
return clean ? `https://${clean}` : null;
|
return clean ? `https://${clean}` : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img.startsWith("spotify:")) {
|
if (img.startsWith("spotify:")) {
|
||||||
return `https://i.scdn.co/image/${img.split(":")[1]}`;
|
return `https://i.scdn.co/image/${img.split(":")[1]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `https://cdn.discordapp.com/app-assets/${applicationId}/${img}.png`;
|
return `https://cdn.discordapp.com/app-assets/${applicationId}/${img}.png`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,9 +124,7 @@
|
||||||
<li class="activity">
|
<li class="activity">
|
||||||
<div class="activity-wrapper">
|
<div class="activity-wrapper">
|
||||||
<div class="activity-type-wrapper">
|
<div class="activity-type-wrapper">
|
||||||
<span class="activity-type-label" data-type="<%= activity.type %>">
|
<span class="activity-type-label" data-type="<%= activity.type %>"><%= activityType %></span>
|
||||||
<%= activityType %>
|
|
||||||
</span>
|
|
||||||
<% if (start && progress === null) { %>
|
<% if (start && progress === null) { %>
|
||||||
<div class="activity-timestamp" data-start="<%= start %>">
|
<div class="activity-timestamp" data-start="<%= start %>">
|
||||||
<% const started = new Date(start); %>
|
<% const started = new Date(start); %>
|
||||||
|
@ -133,17 +134,15 @@
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="activity-wrapper-inner">
|
<div class="activity-wrapper-inner">
|
||||||
<% if (art) { %>
|
<% if (art) { %>
|
||||||
<div class="activity-image-wrapper">
|
<div class="activity-image-wrapper">
|
||||||
<img class="activity-image" src="<%= art %>" alt="Art" <% activity.assets?.large_text ? `title="${activity.assets.large_text}"` : '' %>>
|
<img class="activity-image" src="<%= art %>" alt="Art" <%= activity.assets?.large_text ? `title="${activity.assets.large_text}"` : '' %>>
|
||||||
<% if (smallArt) { %>
|
<% if (smallArt) { %>
|
||||||
<img class="activity-image-small" src="<%= smallArt %>" alt="Small Art" <% activity.assets?.small_text ? `title="${activity.assets.small_text}"` : '' %>>
|
<img class="activity-image-small" src="<%= smallArt %>" alt="Small Art" <%= activity.assets?.small_text ? `title="${activity.assets.small_text}"` : '' %>>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="inner-content">
|
<div class="inner-content">
|
||||||
<%
|
<%
|
||||||
|
@ -156,7 +155,6 @@
|
||||||
<div class="activity-header <%= progress !== null ? 'no-timestamp' : '' %>">
|
<div class="activity-header <%= progress !== null ? 'no-timestamp' : '' %>">
|
||||||
<span class="activity-name"><%= primaryLine %></span>
|
<span class="activity-name"><%= primaryLine %></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if (secondaryLine) { %>
|
<% if (secondaryLine) { %>
|
||||||
<div class="activity-detail"><%= secondaryLine %></div>
|
<div class="activity-detail"><%= secondaryLine %></div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
@ -172,27 +170,24 @@
|
||||||
let buttonUrl = null;
|
let buttonUrl = null;
|
||||||
if (typeof button === 'object' && button.url) {
|
if (typeof button === 'object' && button.url) {
|
||||||
buttonUrl = button.url;
|
buttonUrl = button.url;
|
||||||
}
|
} else if (index === 0 && activity.url) {
|
||||||
else if (index === 0 && activity.url) {
|
|
||||||
buttonUrl = activity.url;
|
buttonUrl = activity.url;
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
<% if (buttonUrl) { %>
|
<% if (buttonUrl) { %>
|
||||||
<a href="<%= buttonUrl %>" class="activity-button" target="_blank" rel="noopener noreferrer"><%= buttonLabel %></a>
|
<a href="<%= buttonUrl %>" class="activity-button" target="_blank" rel="noopener noreferrer"><%= buttonLabel %></a>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% }); %>
|
<% }) %>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if (progress !== null) { %>
|
<% if (progress !== null) { %>
|
||||||
<div class="progress-bar" data-start="<%= start %>" data-end="<%= end %>">
|
<div class="progress-bar" data-start="<%= start %>" data-end="<%= end %>">
|
||||||
<div class="progress-fill" <%= progress !== null ? `style="width: ${progress}%"` : '' %>></div>
|
<div class="progress-fill" <%= progress !== null ? `style="width: ${progress}%"` : '' %>></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if (start && end) { %>
|
<% if (start && end) { %>
|
||||||
<div class="progress-time-labels" data-start="<%= start %>" data-end="<%= end %>">
|
<div class="progress-time-labels" data-start="<%= start %>" data-end="<%= end %>">
|
||||||
<span class="progress-current"></span>
|
<span class="progress-current"></span>
|
||||||
|
@ -202,9 +197,8 @@
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<% }) %>
|
<% }); %>
|
||||||
</ul>
|
</ul>
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<% if (readme) { %>
|
<% if (readme) { %>
|
||||||
<section class="readme">
|
<section class="readme">
|
||||||
|
|
Loading…
Add table
Reference in a new issue