Skip to content

Instantly share code, notes, and snippets.

@respektive
Last active June 7, 2025 10:44
Show Gist options
  • Select an option

  • Save respektive/7795fecf6dd559cd0570dd29516b4eab to your computer and use it in GitHub Desktop.

Select an option

Save respektive/7795fecf6dd559cd0570dd29516b4eab to your computer and use it in GitHub Desktop.
Ranked Score Rank on osu! user profiles.
// ==UserScript==
// @name Ranked Score Rank
// @namespace https://gist.github.com/respektive/7795fecf6dd559cd0570dd29516b4eab/
// @version 0.7
// @description Adds the Ranked Score Rank on user profiles.
// @author respektive
// @match http://osu.ppy.sh/*
// @match https://osu.ppy.sh/*
// @grant none
// @updateURL https://gist.githubusercontent.com/respektive/7795fecf6dd559cd0570dd29516b4eab/raw/ranked-score-rank.user.js
// @downloadURL https://gist.githubusercontent.com/respektive/7795fecf6dd559cd0570dd29516b4eab/raw/ranked-score-rank.user.js
// ==/UserScript==
(function () {
'use strict';
let scoreRankVisible = false;
async function addScoreRank() {
const ranksElement = document.querySelector(".profile-detail__values");
const modesElement = document.querySelector(".game-mode-link--active");
if (!modesElement) {
return;
}
if (ranksElement) {
const path = window.location.pathname.split("/");
const userId = path[2];
const mode = modesElement.dataset.mode;
const scoreRankInfo = await (await fetch(`https://score.respektive.pw/u/${userId}?mode=${mode}`)).json();
const scoreRank = scoreRankInfo[0].rank;
const scoreRankHighest = scoreRankInfo[0].rank_highest.rank;
const scoreRankHighestDate = new Date(Date.parse(scoreRankInfo[0].rank_highest.updated_at));
// Add element to page
let scoreRankElement = document.createElement("div");
scoreRankElement.classList.add("value-display", "value-display--rank");
let scoreRankLabel = document.createElement("div");
scoreRankLabel.classList.add("value-display__label");
scoreRankLabel.innerHTML = "Score Ranking";
scoreRankElement.append(scoreRankLabel);
let scoreRankValue = document.createElement("div");
scoreRankValue.classList.add("value-display__value");
scoreRankElement.append(scoreRankValue);
let rank = document.createElement("div");
// Show a dash even if user has no score rank, so it can still show the peak rank if available
if (scoreRank === 0) {
rank.innerHTML = "-";
} else {
rank.innerHTML = `#${scoreRank.toLocaleString()}`;
}
// Add peak score rank if available
if (scoreRankHighest) {
const scoreRankTooltip = `Highest Rank: #${scoreRankHighest.toLocaleString()} on ${new Intl.DateTimeFormat('en-GB', { dateStyle: 'medium' }).format(scoreRankHighestDate)}`;
rank.setAttribute("data-html-title", scoreRankTooltip);
rank.setAttribute("title", "");
}
scoreRankValue.append(rank);
if (!scoreRankVisible) {
ranksElement.append(scoreRankElement);
scoreRankVisible = true;
}
}
}
let lastUrl = location.href;
new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
scoreRankVisible = false;
setTimeout(onUrlChange, 1500);
}
}).observe(document, { subtree: true, childList: true });
function onUrlChange() {
observer.observe(document, { childList: true, subtree: true });
}
const observer = new MutationObserver(check)
observer.observe(document, { childList: true, subtree: true });
function check(changes, observer) {
if (document.querySelector(".profile-detail")) {
observer.disconnect();
addScoreRank();
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment