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
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:
parent
2b8b135cf8
commit
ae19233ddf
@ -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")
|
||||||
|
Loading…
Reference in New Issue
Block a user