Fix scores from friends
This commit is contained in:
parent
d73c1ac495
commit
f2181c7cf3
BIN
assets/notlikesteve.webp
Normal file
BIN
assets/notlikesteve.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 744 B |
BIN
assets/peepohigh.webp
Normal file
BIN
assets/peepohigh.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
@ -307,6 +307,15 @@ span:empty {
|
|||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
opacity: 0.92;
|
opacity: 0.92;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#friendScoresHeaderImg {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
#friendScoresList {
|
#friendScoresList {
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="friendScores" aria-live="polite">
|
<div id="friendScores" aria-live="polite">
|
||||||
<div id="friendScoresHeader">Mutual friends on BeatLeader</div>
|
<div id="friendScoresHeader"><span id="friendScoresHeaderText">frenz!</span> <img id="friendScoresHeaderImg" src="assets/peepohigh.webp" alt=""></div>
|
||||||
<ol id="friendScoresList"></ol>
|
<ol id="friendScoresList"></ol>
|
||||||
<div id="friendScoresEmpty">No map loaded</div>
|
<div id="friendScoresEmpty">No map loaded</div>
|
||||||
</div>
|
</div>
|
||||||
@ -66,6 +66,11 @@
|
|||||||
<label>Show time: <input id="timeInput" type="checkbox"></label>
|
<label>Show time: <input id="timeInput" type="checkbox"></label>
|
||||||
<label>Show score: <input id="scoreInput" type="checkbox"></label>
|
<label>Show score: <input id="scoreInput" type="checkbox"></label>
|
||||||
<label>Show friend scores: <input id="friendsInput" type="checkbox"></label>
|
<label>Show friend scores: <input id="friendsInput" type="checkbox"></label>
|
||||||
|
<label>Friend list mode: <select id="friendModeInput">
|
||||||
|
<option value="mutual">Followed + follower (mutual)</option>
|
||||||
|
<option value="following">Following (I follow them)</option>
|
||||||
|
<option value="followers">Followers (they follow me)</option>
|
||||||
|
</select></label>
|
||||||
<label>Show BSR / map id: <input id="bsrInput" type="checkbox"></label>
|
<label>Show BSR / map id: <input id="bsrInput" type="checkbox"></label>
|
||||||
<label>Position: <select id="positionInput">
|
<label>Position: <select id="positionInput">
|
||||||
<option value="[false,false]">Top left</option>
|
<option value="[false,false]">Top left</option>
|
||||||
|
|||||||
39
index.js
39
index.js
@ -118,16 +118,18 @@ async function fetchAllFollowers(playerId, type2, maxPages = 100) {
|
|||||||
}
|
}
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
async function fetchMutualFriendIds(playerId, maxPages = 100) {
|
async function fetchFriendIds(playerId, mode, maxPages = 100) {
|
||||||
const canonicalPlayerId = await resolveBeatLeaderPlayerId(playerId);
|
const canonicalPlayerId = await resolveBeatLeaderPlayerId(playerId);
|
||||||
const [following, followers] = await Promise.all([
|
const [following, followers] = await Promise.all([
|
||||||
fetchAllFollowers(canonicalPlayerId, "Following", maxPages),
|
fetchAllFollowers(canonicalPlayerId, "Following", maxPages),
|
||||||
fetchAllFollowers(canonicalPlayerId, "Followers", maxPages)
|
fetchAllFollowers(canonicalPlayerId, "Followers", maxPages)
|
||||||
]);
|
]);
|
||||||
const followingIds = new Set(following.map((entry) => String(entry.id)));
|
const followingIds = new Set(following.map((entry) => String(entry.id)));
|
||||||
|
const followerIds = new Set(followers.map((entry) => String(entry.id)));
|
||||||
|
if (mode === "following") return followingIds;
|
||||||
|
if (mode === "followers") return followerIds;
|
||||||
const mutuals = /* @__PURE__ */ new Set();
|
const mutuals = /* @__PURE__ */ new Set();
|
||||||
for (const entry of followers) {
|
for (const id of followerIds) {
|
||||||
const id = String(entry.id);
|
|
||||||
if (followingIds.has(id)) {
|
if (followingIds.has(id)) {
|
||||||
mutuals.add(id);
|
mutuals.add(id);
|
||||||
}
|
}
|
||||||
@ -277,6 +279,8 @@ var mistakes = must("mistakes");
|
|||||||
var friendScoresPanel = must("friendScores");
|
var friendScoresPanel = must("friendScores");
|
||||||
var friendScoresList = must("friendScoresList");
|
var friendScoresList = must("friendScoresList");
|
||||||
var friendScoresEmpty = must("friendScoresEmpty");
|
var friendScoresEmpty = must("friendScoresEmpty");
|
||||||
|
var friendScoresHeaderText = must("friendScoresHeaderText");
|
||||||
|
var friendScoresHeaderImg = must("friendScoresHeaderImg");
|
||||||
var currentMapHash = "";
|
var currentMapHash = "";
|
||||||
var friendScoreRequestId = 0;
|
var friendScoreRequestId = 0;
|
||||||
function updateScore(score) {
|
function updateScore(score) {
|
||||||
@ -288,13 +292,17 @@ function updateScore(score) {
|
|||||||
function clearFriendScores(message) {
|
function clearFriendScores(message) {
|
||||||
friendScoresList.replaceChildren();
|
friendScoresList.replaceChildren();
|
||||||
friendScoresEmpty.textContent = message;
|
friendScoresEmpty.textContent = message;
|
||||||
|
friendScoresHeaderText.textContent = "frenz?";
|
||||||
|
friendScoresHeaderImg.src = "assets/notlikesteve.webp";
|
||||||
friendScoresPanel.classList.remove("has-items", "is-loading");
|
friendScoresPanel.classList.remove("has-items", "is-loading");
|
||||||
}
|
}
|
||||||
function renderFriendScores(items) {
|
function renderFriendScores(items) {
|
||||||
friendScoresList.replaceChildren();
|
friendScoresList.replaceChildren();
|
||||||
friendScoresPanel.classList.toggle("has-items", items.length > 0);
|
friendScoresPanel.classList.toggle("has-items", items.length > 0);
|
||||||
friendScoresPanel.classList.remove("is-loading");
|
friendScoresPanel.classList.remove("is-loading");
|
||||||
friendScoresEmpty.textContent = items.length ? "" : "No mutual scores on this map";
|
friendScoresEmpty.textContent = items.length ? "" : "No friend scores on this map";
|
||||||
|
friendScoresHeaderText.textContent = items.length ? "frenz!" : "frenz?";
|
||||||
|
friendScoresHeaderImg.src = items.length ? "assets/peepohigh.webp" : "assets/notlikesteve.webp";
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
li.className = "friend-score-item";
|
li.className = "friend-score-item";
|
||||||
@ -329,7 +337,7 @@ async function refreshMapFriendScores() {
|
|||||||
try {
|
try {
|
||||||
const [leaderboards, mutualFriendIds] = await Promise.all([
|
const [leaderboards, mutualFriendIds] = await Promise.all([
|
||||||
fetchBLLeaderboardsByHash(hash),
|
fetchBLLeaderboardsByHash(hash),
|
||||||
fetchMutualFriendIds(playerId)
|
fetchFriendIds(playerId, settings.friendMode)
|
||||||
]);
|
]);
|
||||||
if (requestId !== friendScoreRequestId) return;
|
if (requestId !== friendScoreRequestId) return;
|
||||||
if (leaderboards.length === 0) {
|
if (leaderboards.length === 0) {
|
||||||
@ -337,7 +345,8 @@ async function refreshMapFriendScores() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mutualFriendIds.size === 0) {
|
if (mutualFriendIds.size === 0) {
|
||||||
clearFriendScores("No mutual BeatLeader followers");
|
const relationLabel = settings.friendMode === "following" ? "No followed BeatLeader players" : settings.friendMode === "followers" ? "No BeatLeader followers" : "No mutual BeatLeader followers";
|
||||||
|
clearFriendScores(relationLabel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const scores = await fetchAllMapScoresByHash(hash, leaderboards);
|
const scores = await fetchAllMapScoresByHash(hash, leaderboards);
|
||||||
@ -371,6 +380,7 @@ var settings = {
|
|||||||
time: true,
|
time: true,
|
||||||
score: true,
|
score: true,
|
||||||
friends: true,
|
friends: true,
|
||||||
|
friendMode: "mutual",
|
||||||
bsr: false,
|
bsr: false,
|
||||||
debug: false,
|
debug: false,
|
||||||
mockBsr: "4f4e4",
|
mockBsr: "4f4e4",
|
||||||
@ -451,6 +461,13 @@ for (const key of [
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
var friendModeInput = must("friendModeInput");
|
||||||
|
friendModeInput.value = settings.friendMode;
|
||||||
|
friendModeInput.onchange = () => {
|
||||||
|
settings.friendMode = friendModeInput.value;
|
||||||
|
saveSettings();
|
||||||
|
void refreshMapFriendScores();
|
||||||
|
};
|
||||||
var mockBsrInput = must("mockBsrInput");
|
var mockBsrInput = must("mockBsrInput");
|
||||||
mockBsrInput.value = settings.mockBsr;
|
mockBsrInput.value = settings.mockBsr;
|
||||||
mockBsrInput.oninput = () => {
|
mockBsrInput.oninput = () => {
|
||||||
@ -495,6 +512,7 @@ var requestListEl = must("requestList");
|
|||||||
var requestOverlayEl = must("requestOverlay");
|
var requestOverlayEl = must("requestOverlay");
|
||||||
var requestEmptyEl = must("requestEmpty");
|
var requestEmptyEl = must("requestEmpty");
|
||||||
var requestTitleCache = /* @__PURE__ */ new Map();
|
var requestTitleCache = /* @__PURE__ */ new Map();
|
||||||
|
var requestTitleMisses = /* @__PURE__ */ new Set();
|
||||||
function useRequestHistorySim() {
|
function useRequestHistorySim() {
|
||||||
return settings.debug || new URLSearchParams(location.search).get("debug") === "1";
|
return settings.debug || new URLSearchParams(location.search).get("debug") === "1";
|
||||||
}
|
}
|
||||||
@ -544,19 +562,26 @@ function requesterLine(item) {
|
|||||||
return parts.length ? parts.join(" ") : item.rqn || "";
|
return parts.length ? parts.join(" ") : item.rqn || "";
|
||||||
}
|
}
|
||||||
async function enrichRequestTitle(key, titleEl) {
|
async function enrichRequestTitle(key, titleEl) {
|
||||||
|
if (requestTitleMisses.has(key)) return;
|
||||||
if (requestTitleCache.has(key)) {
|
if (requestTitleCache.has(key)) {
|
||||||
titleEl.textContent = requestTitleCache.get(key) ?? "";
|
titleEl.textContent = requestTitleCache.get(key) ?? "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const map = await fetchBeatSaverMapById(key);
|
const map = await fetchBeatSaverMapById(key);
|
||||||
if (!map) return;
|
if (!map) {
|
||||||
|
requestTitleMisses.add(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const name = map.metadata?.songName ?? map.name;
|
const name = map.metadata?.songName ?? map.name;
|
||||||
if (name && typeof name === "string") {
|
if (name && typeof name === "string") {
|
||||||
requestTitleCache.set(key, name);
|
requestTitleCache.set(key, name);
|
||||||
titleEl.textContent = name;
|
titleEl.textContent = name;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
requestTitleMisses.add(key);
|
||||||
} catch {
|
} catch {
|
||||||
|
requestTitleMisses.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function renderRequestList(items) {
|
function renderRequestList(items) {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import type {
|
|||||||
const BASE_URL = "https://api.beatleader.com";
|
const BASE_URL = "https://api.beatleader.com";
|
||||||
const PAGE_SIZE = 100;
|
const PAGE_SIZE = 100;
|
||||||
const USE_RUNTIME_PROXY = typeof document !== "undefined";
|
const USE_RUNTIME_PROXY = typeof document !== "undefined";
|
||||||
|
export type FriendMode = "mutual" | "following" | "followers";
|
||||||
|
|
||||||
function beatleaderUrl(path: string): string {
|
function beatleaderUrl(path: string): string {
|
||||||
if (USE_RUNTIME_PROXY) {
|
if (USE_RUNTIME_PROXY) {
|
||||||
@ -162,15 +163,21 @@ async function fetchAllFollowers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchMutualFriendIds(playerId: string, maxPages = 100): Promise<Set<string>> {
|
export async function fetchMutualFriendIds(playerId: string, maxPages = 100): Promise<Set<string>> {
|
||||||
|
return fetchFriendIds(playerId, "mutual", maxPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchFriendIds(playerId: string, mode: FriendMode, maxPages = 100): Promise<Set<string>> {
|
||||||
const canonicalPlayerId = await resolveBeatLeaderPlayerId(playerId);
|
const canonicalPlayerId = await resolveBeatLeaderPlayerId(playerId);
|
||||||
const [following, followers] = await Promise.all([
|
const [following, followers] = await Promise.all([
|
||||||
fetchAllFollowers(canonicalPlayerId, "Following", maxPages),
|
fetchAllFollowers(canonicalPlayerId, "Following", maxPages),
|
||||||
fetchAllFollowers(canonicalPlayerId, "Followers", maxPages),
|
fetchAllFollowers(canonicalPlayerId, "Followers", maxPages),
|
||||||
]);
|
]);
|
||||||
const followingIds = new Set(following.map((entry) => String(entry.id)));
|
const followingIds = new Set(following.map((entry) => String(entry.id)));
|
||||||
|
const followerIds = new Set(followers.map((entry) => String(entry.id)));
|
||||||
|
if (mode === "following") return followingIds;
|
||||||
|
if (mode === "followers") return followerIds;
|
||||||
const mutuals = new Set<string>();
|
const mutuals = new Set<string>();
|
||||||
for (const entry of followers) {
|
for (const id of followerIds) {
|
||||||
const id = String(entry.id);
|
|
||||||
if (followingIds.has(id)) {
|
if (followingIds.has(id)) {
|
||||||
mutuals.add(id);
|
mutuals.add(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,8 @@ import { fetchBeatSaverMapById, fetchBeatSaverMeta } from "./beatsaver.ts";
|
|||||||
import {
|
import {
|
||||||
fetchAllMapScoresByHash,
|
fetchAllMapScoresByHash,
|
||||||
fetchBLLeaderboardsByHash,
|
fetchBLLeaderboardsByHash,
|
||||||
fetchMutualFriendIds,
|
fetchFriendIds,
|
||||||
|
type FriendMode,
|
||||||
normalizeAccuracy,
|
normalizeAccuracy,
|
||||||
} from "./beatleader.ts";
|
} from "./beatleader.ts";
|
||||||
|
|
||||||
@ -176,6 +177,8 @@ const mistakes = must<HTMLElement>("mistakes");
|
|||||||
const friendScoresPanel = must<HTMLElement>("friendScores");
|
const friendScoresPanel = must<HTMLElement>("friendScores");
|
||||||
const friendScoresList = must<HTMLOListElement>("friendScoresList");
|
const friendScoresList = must<HTMLOListElement>("friendScoresList");
|
||||||
const friendScoresEmpty = must<HTMLElement>("friendScoresEmpty");
|
const friendScoresEmpty = must<HTMLElement>("friendScoresEmpty");
|
||||||
|
const friendScoresHeaderText = must<HTMLElement>("friendScoresHeaderText");
|
||||||
|
const friendScoresHeaderImg = must<HTMLImageElement>("friendScoresHeaderImg");
|
||||||
|
|
||||||
let currentMapHash = "";
|
let currentMapHash = "";
|
||||||
let friendScoreRequestId = 0;
|
let friendScoreRequestId = 0;
|
||||||
@ -190,6 +193,8 @@ function updateScore(score: Score) {
|
|||||||
function clearFriendScores(message: string) {
|
function clearFriendScores(message: string) {
|
||||||
friendScoresList.replaceChildren();
|
friendScoresList.replaceChildren();
|
||||||
friendScoresEmpty.textContent = message;
|
friendScoresEmpty.textContent = message;
|
||||||
|
friendScoresHeaderText.textContent = "frenz?";
|
||||||
|
friendScoresHeaderImg.src = "assets/notlikesteve.webp";
|
||||||
friendScoresPanel.classList.remove("has-items", "is-loading");
|
friendScoresPanel.classList.remove("has-items", "is-loading");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +202,9 @@ function renderFriendScores(items: Array<{ name: string; acc: number }>) {
|
|||||||
friendScoresList.replaceChildren();
|
friendScoresList.replaceChildren();
|
||||||
friendScoresPanel.classList.toggle("has-items", items.length > 0);
|
friendScoresPanel.classList.toggle("has-items", items.length > 0);
|
||||||
friendScoresPanel.classList.remove("is-loading");
|
friendScoresPanel.classList.remove("is-loading");
|
||||||
friendScoresEmpty.textContent = items.length ? "" : "No mutual scores on this map";
|
friendScoresEmpty.textContent = items.length ? "" : "No friend scores on this map";
|
||||||
|
friendScoresHeaderText.textContent = items.length ? "frenz!" : "frenz?";
|
||||||
|
friendScoresHeaderImg.src = items.length ? "assets/peepohigh.webp" : "assets/notlikesteve.webp";
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
li.className = "friend-score-item";
|
li.className = "friend-score-item";
|
||||||
@ -233,7 +240,7 @@ async function refreshMapFriendScores() {
|
|||||||
try {
|
try {
|
||||||
const [leaderboards, mutualFriendIds] = await Promise.all([
|
const [leaderboards, mutualFriendIds] = await Promise.all([
|
||||||
fetchBLLeaderboardsByHash(hash),
|
fetchBLLeaderboardsByHash(hash),
|
||||||
fetchMutualFriendIds(playerId),
|
fetchFriendIds(playerId, settings.friendMode),
|
||||||
]);
|
]);
|
||||||
if (requestId !== friendScoreRequestId) return;
|
if (requestId !== friendScoreRequestId) return;
|
||||||
if (leaderboards.length === 0) {
|
if (leaderboards.length === 0) {
|
||||||
@ -241,7 +248,12 @@ async function refreshMapFriendScores() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mutualFriendIds.size === 0) {
|
if (mutualFriendIds.size === 0) {
|
||||||
clearFriendScores("No mutual BeatLeader followers");
|
const relationLabel = settings.friendMode === "following"
|
||||||
|
? "No followed BeatLeader players"
|
||||||
|
: settings.friendMode === "followers"
|
||||||
|
? "No BeatLeader followers"
|
||||||
|
: "No mutual BeatLeader followers";
|
||||||
|
clearFriendScores(relationLabel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const scores = await fetchAllMapScoresByHash(hash, leaderboards);
|
const scores = await fetchAllMapScoresByHash(hash, leaderboards);
|
||||||
@ -280,6 +292,7 @@ interface Settings {
|
|||||||
time: boolean;
|
time: boolean;
|
||||||
score: boolean;
|
score: boolean;
|
||||||
friends: boolean;
|
friends: boolean;
|
||||||
|
friendMode: FriendMode;
|
||||||
bsr: boolean;
|
bsr: boolean;
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
mockBsr: string;
|
mockBsr: string;
|
||||||
@ -296,6 +309,7 @@ const settings: Settings = {
|
|||||||
time: true,
|
time: true,
|
||||||
score: true,
|
score: true,
|
||||||
friends: true,
|
friends: true,
|
||||||
|
friendMode: "mutual",
|
||||||
bsr: false,
|
bsr: false,
|
||||||
debug: false,
|
debug: false,
|
||||||
mockBsr: "4f4e4",
|
mockBsr: "4f4e4",
|
||||||
@ -380,6 +394,14 @@ for (const key of ["cover", "mapInfo", "time", "score", "friends", "bsr", "debug
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const friendModeInput = must<HTMLSelectElement>("friendModeInput");
|
||||||
|
friendModeInput.value = settings.friendMode;
|
||||||
|
friendModeInput.onchange = () => {
|
||||||
|
settings.friendMode = friendModeInput.value as FriendMode;
|
||||||
|
saveSettings();
|
||||||
|
void refreshMapFriendScores();
|
||||||
|
};
|
||||||
|
|
||||||
const mockBsrInput = must<HTMLInputElement>("mockBsrInput");
|
const mockBsrInput = must<HTMLInputElement>("mockBsrInput");
|
||||||
mockBsrInput.value = settings.mockBsr;
|
mockBsrInput.value = settings.mockBsr;
|
||||||
mockBsrInput.oninput = () => {
|
mockBsrInput.oninput = () => {
|
||||||
@ -430,6 +452,7 @@ const requestListEl = must<HTMLOListElement>("requestList");
|
|||||||
const requestOverlayEl = must<HTMLElement>("requestOverlay");
|
const requestOverlayEl = must<HTMLElement>("requestOverlay");
|
||||||
const requestEmptyEl = must<HTMLElement>("requestEmpty");
|
const requestEmptyEl = must<HTMLElement>("requestEmpty");
|
||||||
const requestTitleCache = new Map<string, string>();
|
const requestTitleCache = new Map<string, string>();
|
||||||
|
const requestTitleMisses = new Set<string>();
|
||||||
|
|
||||||
function useRequestHistorySim() {
|
function useRequestHistorySim() {
|
||||||
return settings.debug || new URLSearchParams(location.search).get("debug") === "1";
|
return settings.debug || new URLSearchParams(location.search).get("debug") === "1";
|
||||||
@ -473,20 +496,26 @@ function requesterLine(item: ChatRequestEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function enrichRequestTitle(key: string, titleEl: HTMLElement) {
|
async function enrichRequestTitle(key: string, titleEl: HTMLElement) {
|
||||||
|
if (requestTitleMisses.has(key)) return;
|
||||||
if (requestTitleCache.has(key)) {
|
if (requestTitleCache.has(key)) {
|
||||||
titleEl.textContent = requestTitleCache.get(key) ?? "";
|
titleEl.textContent = requestTitleCache.get(key) ?? "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const map = await fetchBeatSaverMapById(key);
|
const map = await fetchBeatSaverMapById(key);
|
||||||
if (!map) return;
|
if (!map) {
|
||||||
|
requestTitleMisses.add(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const name = map.metadata?.songName ?? map.name;
|
const name = map.metadata?.songName ?? map.name;
|
||||||
if (name && typeof name === "string") {
|
if (name && typeof name === "string") {
|
||||||
requestTitleCache.set(key, name);
|
requestTitleCache.set(key, name);
|
||||||
titleEl.textContent = name;
|
titleEl.textContent = name;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
requestTitleMisses.add(key);
|
||||||
} catch {
|
} catch {
|
||||||
// keep !bsr placeholder
|
requestTitleMisses.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user