fix issue with badge loading, profile indef loading if no user, remove unused files, organize the js
All checks were successful
Code quality checks / biome (push) Successful in 15s
All checks were successful
Code quality checks / biome (push) Successful in 15s
This commit is contained in:
parent
634d919239
commit
1020e3ee26
5 changed files with 158 additions and 236 deletions
|
@ -1,5 +1,12 @@
|
||||||
|
const head = document.querySelector("head");
|
||||||
|
const userId = head?.dataset.userId;
|
||||||
const activityProgressMap = new Map();
|
const activityProgressMap = new Map();
|
||||||
|
|
||||||
|
let instanceUri = head?.dataset.instanceUri;
|
||||||
|
let badgeURL = head?.dataset.badgeUrl;
|
||||||
|
let socket;
|
||||||
|
let badgesLoaded = false;
|
||||||
|
|
||||||
function formatTime(ms) {
|
function formatTime(ms) {
|
||||||
const totalSecs = Math.floor(ms / 1000);
|
const totalSecs = Math.floor(ms / 1000);
|
||||||
const hours = Math.floor(totalSecs / 3600);
|
const hours = Math.floor(totalSecs / 3600);
|
||||||
|
@ -78,57 +85,14 @@ function updateElapsedAndProgress() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateElapsedAndProgress();
|
function loadEffectScript(effect) {
|
||||||
setInterval(updateElapsedAndProgress, 1000);
|
const existing = document.querySelector(`script[data-effect="${effect}"]`);
|
||||||
|
if (existing) return;
|
||||||
|
|
||||||
const head = document.querySelector("head");
|
const script = document.createElement("script");
|
||||||
const userId = head?.dataset.userId;
|
script.src = `/public/js/${effect}.js`;
|
||||||
let instanceUri = head?.dataset.instanceUri;
|
script.dataset.effect = effect;
|
||||||
let badgeURL = head?.dataset.badgeUrl;
|
document.head.appendChild(script);
|
||||||
|
|
||||||
if (userId && instanceUri) {
|
|
||||||
if (!instanceUri.startsWith("http")) {
|
|
||||||
instanceUri = `https://${instanceUri}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wsUri = instanceUri
|
|
||||||
.replace(/^http:/, "ws:")
|
|
||||||
.replace(/^https:/, "wss:")
|
|
||||||
.replace(/\/$/, "");
|
|
||||||
|
|
||||||
const socket = new WebSocket(`${wsUri}/socket`);
|
|
||||||
|
|
||||||
let heartbeatInterval = null;
|
|
||||||
|
|
||||||
socket.addEventListener("open", () => {});
|
|
||||||
|
|
||||||
socket.addEventListener("message", (event) => {
|
|
||||||
const payload = JSON.parse(event.data);
|
|
||||||
|
|
||||||
if (payload.op === 1 && payload.d?.heartbeat_interval) {
|
|
||||||
heartbeatInterval = setInterval(() => {
|
|
||||||
socket.send(JSON.stringify({ op: 3 }));
|
|
||||||
}, payload.d.heartbeat_interval);
|
|
||||||
|
|
||||||
socket.send(
|
|
||||||
JSON.stringify({
|
|
||||||
op: 2,
|
|
||||||
d: {
|
|
||||||
subscribe_to_id: userId,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payload.t === "INIT_STATE" || payload.t === "PRESENCE_UPDATE") {
|
|
||||||
updatePresence(payload.d);
|
|
||||||
requestAnimationFrame(() => updateElapsedAndProgress());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.addEventListener("close", () => {
|
|
||||||
if (heartbeatInterval) clearInterval(heartbeatInterval);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveActivityImage(img, applicationId) {
|
function resolveActivityImage(img, applicationId) {
|
||||||
|
@ -280,16 +244,7 @@ function buildActivityHTML(activity) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (badgeURL && badgeURL !== "null" && userId) {
|
async function loadBadges(userId, options = {}) {
|
||||||
if (!badgeURL.startsWith("http")) {
|
|
||||||
badgeURL = `https://${badgeURL}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!badgeURL.endsWith("/")) {
|
|
||||||
badgeURL += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadBadges(userId, options = {}) {
|
|
||||||
const {
|
const {
|
||||||
services = [],
|
services = [],
|
||||||
seperated = false,
|
seperated = false,
|
||||||
|
@ -355,20 +310,10 @@ if (badgeURL && badgeURL !== "null" && userId) {
|
||||||
target.innerHTML = "";
|
target.innerHTML = "";
|
||||||
target.classList.add("hidden");
|
target.classList.add("hidden");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
loadBadges(userId, {
|
|
||||||
services: [],
|
|
||||||
seperated: true,
|
|
||||||
cache: true,
|
|
||||||
targetId: "badges",
|
|
||||||
serviceOrder: ["discord", "equicord", "reviewdb", "vencord"],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePresence(data) {
|
async function updatePresence(data) {
|
||||||
const cssLink = data.kv?.css;
|
const cssLink = data.kv?.css;
|
||||||
|
|
||||||
if (cssLink) {
|
if (cssLink) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/css?url=${encodeURIComponent(cssLink)}`);
|
const res = await fetch(`/api/css?url=${encodeURIComponent(cssLink)}`);
|
||||||
|
@ -384,10 +329,37 @@ async function updatePresence(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarWrapper = document.querySelector(".avatar-wrapper");
|
const avatarWrapper = document.querySelector(".avatar-wrapper");
|
||||||
|
const avatarImg = avatarWrapper?.querySelector(".avatar");
|
||||||
const avatarImg = document.querySelector(".avatar-wrapper .avatar");
|
|
||||||
const usernameEl = document.querySelector(".username");
|
const usernameEl = document.querySelector(".username");
|
||||||
|
|
||||||
|
if (!data.discord_user) {
|
||||||
|
const loadingOverlay = document.getElementById("loading-overlay");
|
||||||
|
if (loadingOverlay) {
|
||||||
|
loadingOverlay.innerHTML = `
|
||||||
|
<div class="error-message">
|
||||||
|
<p>Failed to load user data.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
loadingOverlay.style.opacity = "1";
|
||||||
|
avatarWrapper.classList.add("hidden");
|
||||||
|
avatarImg.classList.add("hidden");
|
||||||
|
usernameEl.classList.add("hidden");
|
||||||
|
document.title = "Error";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!badgesLoaded) {
|
||||||
|
loadBadges(userId, {
|
||||||
|
services: [],
|
||||||
|
seperated: true,
|
||||||
|
cache: true,
|
||||||
|
targetId: "badges",
|
||||||
|
serviceOrder: ["discord", "equicord", "reviewdb", "vencord"],
|
||||||
|
});
|
||||||
|
badgesLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (avatarImg && data.discord_user?.avatar) {
|
if (avatarImg && data.discord_user?.avatar) {
|
||||||
const newAvatarUrl = `https://cdn.discordapp.com/avatars/${data.discord_user.id}/${data.discord_user.avatar}`;
|
const newAvatarUrl = `https://cdn.discordapp.com/avatars/${data.discord_user.id}/${data.discord_user.avatar}`;
|
||||||
avatarImg.src = newAvatarUrl;
|
avatarImg.src = newAvatarUrl;
|
||||||
|
@ -582,12 +554,60 @@ async function getAllNoAsset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadEffectScript(effect) {
|
if (instanceUri) {
|
||||||
const existing = document.querySelector(`script[data-effect="${effect}"]`);
|
if (!instanceUri.startsWith("http")) {
|
||||||
if (existing) return;
|
instanceUri = `https://${instanceUri}`;
|
||||||
|
}
|
||||||
|
|
||||||
const script = document.createElement("script");
|
const wsUri = instanceUri
|
||||||
script.src = `/public/js/${effect}.js`;
|
.replace(/^http:/, "ws:")
|
||||||
script.dataset.effect = effect;
|
.replace(/^https:/, "wss:")
|
||||||
document.head.appendChild(script);
|
.replace(/\/$/, "");
|
||||||
|
|
||||||
|
socket = new WebSocket(`${wsUri}/socket`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (badgeURL && badgeURL !== "null" && userId) {
|
||||||
|
if (!badgeURL.startsWith("http")) {
|
||||||
|
badgeURL = `https://${badgeURL}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!badgeURL.endsWith("/")) {
|
||||||
|
badgeURL += "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userId && instanceUri) {
|
||||||
|
let heartbeatInterval = null;
|
||||||
|
|
||||||
|
socket.addEventListener("message", (event) => {
|
||||||
|
const payload = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (payload.op === 1 && payload.d?.heartbeat_interval) {
|
||||||
|
heartbeatInterval = setInterval(() => {
|
||||||
|
socket.send(JSON.stringify({ op: 3 }));
|
||||||
|
}, payload.d.heartbeat_interval);
|
||||||
|
|
||||||
|
socket.send(
|
||||||
|
JSON.stringify({
|
||||||
|
op: 2,
|
||||||
|
d: {
|
||||||
|
subscribe_to_id: userId,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.t === "INIT_STATE" || payload.t === "PRESENCE_UPDATE") {
|
||||||
|
updatePresence(payload.d);
|
||||||
|
requestAnimationFrame(() => updateElapsedAndProgress());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.addEventListener("close", () => {
|
||||||
|
if (heartbeatInterval) clearInterval(heartbeatInterval);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateElapsedAndProgress();
|
||||||
|
setInterval(updateElapsedAndProgress, 1000);
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Error</title>
|
|
||||||
<link rel="stylesheet" href="/public/css/error.css">
|
|
||||||
<meta name="color-scheme" content="dark">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="error-container">
|
|
||||||
<div class="error-title">Something went wrong</div>
|
|
||||||
<div class="error-message">
|
|
||||||
<%= message || "An unexpected error occurred." %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -27,7 +27,7 @@
|
||||||
<div class="avatar-status-wrapper">
|
<div class="avatar-status-wrapper">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
<img class="avatar hidden" src="">
|
<img class="avatar hidden" src="">
|
||||||
<div class="status-indicator offline"></div>
|
<div class="status-indicator offline hidden"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<div class="user-info-inner">
|
<div class="user-info-inner">
|
||||||
|
|
72
types/lanyard.d.ts
vendored
72
types/lanyard.d.ts
vendored
|
@ -1,72 +0,0 @@
|
||||||
interface DiscordUser {
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
avatar: string;
|
|
||||||
discriminator: string;
|
|
||||||
clan?: string | null;
|
|
||||||
avatar_decoration_data?: {
|
|
||||||
sku_id: string;
|
|
||||||
asset: string;
|
|
||||||
expires_at: string | null;
|
|
||||||
};
|
|
||||||
bot: boolean;
|
|
||||||
global_name: string;
|
|
||||||
primary_guild?: string | null;
|
|
||||||
collectibles?: {
|
|
||||||
enabled: boolean;
|
|
||||||
disabled: boolean;
|
|
||||||
};
|
|
||||||
display_name: string;
|
|
||||||
public_flags: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Activity {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
type: number;
|
|
||||||
state: string;
|
|
||||||
created_at: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SpotifyData {
|
|
||||||
track_id: string;
|
|
||||||
album_id: string;
|
|
||||||
album_name: string;
|
|
||||||
artist_name: string;
|
|
||||||
track_name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Kv {
|
|
||||||
[key: string]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LanyardData {
|
|
||||||
kv: Kv;
|
|
||||||
discord_user: DiscordUser;
|
|
||||||
activities: Activity[];
|
|
||||||
discord_status: string;
|
|
||||||
active_on_discord_web: boolean;
|
|
||||||
active_on_discord_desktop: boolean;
|
|
||||||
active_on_discord_mobile: boolean;
|
|
||||||
listening_to_spotify?: boolean;
|
|
||||||
spotify?: SpotifyData;
|
|
||||||
spotify_status: string;
|
|
||||||
active_on_spotify: boolean;
|
|
||||||
active_on_xbox: boolean;
|
|
||||||
active_on_playstation: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
type LanyardSuccess = {
|
|
||||||
success: true;
|
|
||||||
data: LanyardData;
|
|
||||||
};
|
|
||||||
|
|
||||||
type LanyardError = {
|
|
||||||
success: false;
|
|
||||||
error: {
|
|
||||||
code: string;
|
|
||||||
message: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type LanyardResponse = LanyardSuccess | LanyardError;
|
|
9
types/logger.d.ts
vendored
9
types/logger.d.ts
vendored
|
@ -1,9 +0,0 @@
|
||||||
type ILogMessagePart = { value: string; color: string };
|
|
||||||
|
|
||||||
type ILogMessageParts = {
|
|
||||||
level: ILogMessagePart;
|
|
||||||
filename: ILogMessagePart;
|
|
||||||
readableTimestamp: ILogMessagePart;
|
|
||||||
message: ILogMessagePart;
|
|
||||||
[key: string]: ILogMessagePart;
|
|
||||||
};
|
|
Loading…
Add table
Reference in a new issue