return null bio if the raw bio is null
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m20s

This commit is contained in:
Lee 2024-04-25 08:09:59 +01:00
parent 2b8b135cf8
commit ae19233ddf
2 changed files with 66 additions and 43 deletions

@ -12,76 +12,96 @@
// @run-at document-end // @run-at document-end
// ==/UserScript== // ==/UserScript==
let loaded = false;
/** /**
* Fetches the player from ScoreSaber Utils. * Fetches data from an API endpoint.
* *
* @param {string} id the player's ID * @param {string} url The URL of the API endpoint
* @returns the player's data * @returns The JSON response from the API
*/ */
async function fetchPlayer(id) { async function fetchData(url) {
const response = await fetch(`https://ssu.fascinated.cc/account/${id}`); const response = await fetch(url);
return await response.json(); return await response.json();
} }
/** /**
* Handles the player page logic. * Inserts a stat into the specified container.
*/
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.
* *
* @param {string} containerSelector The selector for the container to insert the stat into
* @param {string} stat The stat name * @param {string} stat The stat name
* @param {string} value The stat value * @param {string} value The stat value
* @param {string} hoverText The hover text * @param {string} hoverText The hover text
*/ */
function addStat(stat, value, hoverText) { function addStat(containerSelector, stat, value, hoverText) {
const statsElement = document.getElementsByClassName("stats-container")[0]; const container = document.querySelector(containerSelector);
const svelteClass = statsElement.getAttribute("class").split(" ")[1]; if (!container) return;
const svelteClass = container.getAttribute("class").split(" ")[1];
const statElement = document.createElement("div"); const statElement = document.createElement("div");
statElement.className = `stat-item ${svelteClass}`; statElement.className = `stat-item ${svelteClass}`;
statElement.innerHTML = ` statElement.innerHTML = `
<span class="stat-title ${svelteClass}">${stat}</span> <span class="stat-title ${svelteClass}">${stat}</span>
<span class="stat-spacer ${svelteClass}"></span> <span class="stat-spacer ${svelteClass}"></span>
<span class="stat-content ${svelteClass} has-hover" title="${hoverText}">${value}</span> <span class="stat-content ${svelteClass} has-hover" title="${hoverText}">${value}</span>
`; `;
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) { function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }
async function load() { /**
"use strict"; * Loads ScoreSaber Utils data on player pages.
if (loaded) return; */
async function loadPlayerData() {
const path = window.location.pathname; const path = window.location.pathname;
const isPlayerPage = path.startsWith("/u/"); const isPlayerPage = path.startsWith("/u/");
if (isPlayerPage) { if (!isPlayerPage) {
// Wait for the stats container to load // Only run on player pages
while (document.getElementsByClassName("stats-container").length === 0) { return;
await sleep(250);
}
playerPage();
} }
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();

@ -163,6 +163,9 @@ public class Account {
* @return The bio. * @return The bio.
*/ */
public static Bio fromRaw(String raw) { public static Bio fromRaw(String raw) {
if (raw == null || raw.isEmpty()) {
return null;
}
return new Bio( return new Bio(
raw.split("\n"), raw.split("\n"),
raw.replaceAll("<[^>]*>", "").split("\n") raw.replaceAll("<[^>]*>", "").split("\n")