From ae19233ddf1ec0867b238f71da7336896542b459 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 25 Apr 2024 08:09:59 +0100 Subject: [PATCH] return null bio if the raw bio is null --- scoresaber-utils.user.js | 106 +++++++++++------- .../backend/model/account/Account.java | 3 + 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/scoresaber-utils.user.js b/scoresaber-utils.user.js index 8aaed9b..7dc2f5d 100644 --- a/scoresaber-utils.user.js +++ b/scoresaber-utils.user.js @@ -12,76 +12,96 @@ // @run-at document-end // ==/UserScript== -let loaded = false; - /** - * Fetches the player from ScoreSaber Utils. + * Fetches data from an API endpoint. * - * @param {string} id the player's ID - * @returns the player's data + * @param {string} url The URL of the API endpoint + * @returns The JSON response from the API */ -async function fetchPlayer(id) { - const response = await fetch(`https://ssu.fascinated.cc/account/${id}`); +async function fetchData(url) { + const response = await fetch(url); return await response.json(); } /** - * Handles the player page logic. - */ -async function playerPage() { - console.log("Player page loaded!"); - const id = window.location.pathname.split("/")[2]; - const player = await fetchPlayer(id); - - addStat( - "+1 PP", - player.rawPerGlobalPerformancePoints.toFixed(2) + "pp", - "The amount of pp to increase the global pp by 1pp" - ); -} - -/** - * Inserts a stat into the player's stats. + * Inserts a stat into the specified container. * + * @param {string} containerSelector The selector for the container to insert the stat into * @param {string} stat The stat name * @param {string} value The stat value * @param {string} hoverText The hover text */ -function addStat(stat, value, hoverText) { - const statsElement = document.getElementsByClassName("stats-container")[0]; - const svelteClass = statsElement.getAttribute("class").split(" ")[1]; +function addStat(containerSelector, stat, value, hoverText) { + const container = document.querySelector(containerSelector); + if (!container) return; + + const svelteClass = container.getAttribute("class").split(" ")[1]; const statElement = document.createElement("div"); statElement.className = `stat-item ${svelteClass}`; statElement.innerHTML = ` - ${stat} - - ${value} + ${stat} + + ${value} `; - statsElement.appendChild(statElement); + container.appendChild(statElement); } +/** + * Delays execution for the specified duration. + * + * @param {number} ms The duration to delay in milliseconds + * @returns A promise that resolves after the delay + */ function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } -async function load() { - "use strict"; - if (loaded) return; - +/** + * Loads ScoreSaber Utils data on player pages. + */ +async function loadPlayerData() { const path = window.location.pathname; const isPlayerPage = path.startsWith("/u/"); - if (isPlayerPage) { - // Wait for the stats container to load - while (document.getElementsByClassName("stats-container").length === 0) { - await sleep(250); - } - - playerPage(); + if (!isPlayerPage) { + // Only run on player pages + return; } - loaded = true; + // Wait for the stats container to load + while (!document.querySelector(".stats-container")) { + await sleep(250); + } + const playerId = path.split("/")[2]; + + // Get the title element + const titleElement = document.querySelector(".title.is-5.player.has-text-centered-mobile"); + if (!titleElement) return; + const svelteClass = titleElement + .getAttribute("class") + .split(" ") + .find((c) => c.startsWith("svelte")); + + // Add a loading indicator + const loadingElement = document.createElement("span"); + loadingElement.className = `title-header pp ${svelteClass}`; + loadingElement.textContent = "Loading ScoreSaber Utils Data..."; + titleElement.appendChild(loadingElement); + + try { + const playerData = await fetchData(`https://ssu.fascinated.cc/account/${playerId}`); + addStat( + ".stats-container", + "+1 PP", + `${playerData.rawPerGlobalPerformancePoints.toFixed(2)}pp`, + "The amount of pp to increase the global pp by 1pp" + ); + } catch (error) { + console.error("Failed to load player data:", error); + } + // Remove the loading indicator + loadingElement.remove(); } -load(); +loadPlayerData(); diff --git a/src/main/java/cc/fascinated/backend/model/account/Account.java b/src/main/java/cc/fascinated/backend/model/account/Account.java index 2af43b5..84b51a0 100644 --- a/src/main/java/cc/fascinated/backend/model/account/Account.java +++ b/src/main/java/cc/fascinated/backend/model/account/Account.java @@ -163,6 +163,9 @@ public class Account { * @return The bio. */ public static Bio fromRaw(String raw) { + if (raw == null || raw.isEmpty()) { + return null; + } return new Bio( raw.split("\n"), raw.replaceAll("<[^>]*>", "").split("\n")