Must be ranked higher than pleb to use tools
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import {
|
||||
formatToolRequirementSummary,
|
||||
meetsToolRequirement,
|
||||
DEFAULT_ADMIN_RANK_FALLBACK,
|
||||
type BeatLeaderPlayerProfile,
|
||||
type ToolRequirement
|
||||
} from '$lib/utils/plebsaber-utils';
|
||||
@@ -12,10 +13,22 @@
|
||||
export let requirement: ToolRequirement | null = null;
|
||||
export let customLockedMessage: string | null = null;
|
||||
export let showCurrentRank = true;
|
||||
export let adminRank: number | null = null;
|
||||
|
||||
$: hasAccess = meetsToolRequirement(player, requirement);
|
||||
$: summary = formatToolRequirementSummary(requirement);
|
||||
$: lockedMessage = customLockedMessage ?? requirement?.lockedMessage ?? null;
|
||||
$: requirementContext = { adminRank };
|
||||
$: hasAccess = meetsToolRequirement(player, requirement, requirementContext);
|
||||
$: summary = formatToolRequirementSummary(requirement, requirementContext);
|
||||
$: fallbackBaseline = DEFAULT_ADMIN_RANK_FALLBACK;
|
||||
$: resolvedBaseline = typeof adminRank === 'number' && Number.isFinite(adminRank) && adminRank > 0
|
||||
? adminRank
|
||||
: fallbackBaseline;
|
||||
$: baselineCopy = resolvedBaseline
|
||||
? `players ranked better than pleb (#${resolvedBaseline.toLocaleString()})`
|
||||
: 'players ranked better than pleb';
|
||||
$: defaultLockedMessage = requirement?.requiresBetterRankThanAdmin
|
||||
? `You must be a BL Patreon supporter or ${baselineCopy} to use this tool.`
|
||||
: requirement?.lockedMessage ?? null;
|
||||
$: lockedMessage = customLockedMessage ?? defaultLockedMessage;
|
||||
$: showLockedMessage = lockedMessage && lockedMessage !== summary ? lockedMessage : null;
|
||||
$: playerRank = typeof player?.rank === 'number' ? player?.rank ?? null : null;
|
||||
$: playerRankDisplay = playerRank !== null ? `#${playerRank.toLocaleString()}` : null;
|
||||
@@ -26,7 +39,7 @@
|
||||
{:else}
|
||||
<div class="mt-6 rounded-md border border-amber-500/40 bg-amber-500/10 p-4 text-sm text-amber-100 leading-relaxed">
|
||||
<p class="font-semibold text-amber-200">
|
||||
Tools are restricted to <a class="underline hover:text-white" href={BL_PATREON_URL} target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> (and the top 3k ranked players).
|
||||
Tools are restricted to <a class="underline hover:text-white" href={BL_PATREON_URL} target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> (and {baselineCopy}).
|
||||
</p>
|
||||
{#if summary}
|
||||
<p class="mt-1">{summary}</p>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { dev } from '$app/environment';
|
||||
import beatleaderLogo from '$lib/assets/beatleader-logo.png';
|
||||
|
||||
import { DEFAULT_ADMIN_RANK_FALLBACK, PLEB_BEATLEADER_ID } from '$lib/utils/plebsaber-utils';
|
||||
const links = [
|
||||
{ href: '/', label: 'Home' },
|
||||
{ href: '/tools', label: 'Tools' },
|
||||
@@ -37,6 +37,8 @@
|
||||
let loginHref = '/auth/beatleader/login';
|
||||
let checkingSession = true;
|
||||
let menuOpen = false;
|
||||
let adminRank: number | null = null;
|
||||
let adminFallbackRank = DEFAULT_ADMIN_RANK_FALLBACK;
|
||||
|
||||
const getProfileUrl = (id?: string) => (id ? `https://beatleader.com/u/${encodeURIComponent(id)}` : 'https://beatleader.com');
|
||||
|
||||
@@ -64,6 +66,18 @@
|
||||
};
|
||||
}
|
||||
|
||||
function extractAdminBaseline(payload: unknown): { rank: number | null; fallback: number } | null {
|
||||
if (!payload || typeof payload !== 'object') return null;
|
||||
const baseline = (payload as { adminBaseline?: { rank?: unknown; fallback?: unknown } }).adminBaseline;
|
||||
if (!baseline || typeof baseline !== 'object') return null;
|
||||
const rank = (baseline as { rank?: unknown }).rank;
|
||||
const fallback = (baseline as { fallback?: unknown }).fallback;
|
||||
return {
|
||||
rank: typeof rank === 'number' && Number.isFinite(rank) && rank > 0 ? rank : null,
|
||||
fallback: typeof fallback === 'number' && Number.isFinite(fallback) && fallback > 0 ? fallback : DEFAULT_ADMIN_RANK_FALLBACK
|
||||
};
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const redirectTarget = `${window.location.pathname}${window.location.search}${window.location.hash}` || '/';
|
||||
loginHref = `/auth/beatleader/login?redirect_uri=${encodeURIComponent(redirectTarget)}`;
|
||||
@@ -77,6 +91,11 @@
|
||||
if (profile) {
|
||||
user = profile;
|
||||
}
|
||||
const baseline = extractAdminBaseline(json);
|
||||
if (baseline) {
|
||||
adminRank = baseline.rank;
|
||||
adminFallbackRank = baseline.fallback;
|
||||
}
|
||||
} else if (res.status === 401) {
|
||||
try {
|
||||
const body = (await res.json()) as Record<string, unknown>;
|
||||
@@ -103,6 +122,12 @@
|
||||
function closeMenu() {
|
||||
menuOpen = false;
|
||||
}
|
||||
|
||||
$: baselineRank = (adminRank ?? adminFallbackRank ?? DEFAULT_ADMIN_RANK_FALLBACK);
|
||||
$: requiresWarning = typeof user?.rank === 'number' && Number.isFinite(user.rank)
|
||||
? (user.rank as number) > baselineRank
|
||||
: false;
|
||||
$: baselineCopy = baselineRank ? `pleb (#${baselineRank.toLocaleString()})` : 'pleb';
|
||||
</script>
|
||||
|
||||
<header class="sticky top-0 z-40 backdrop-blur supports-[backdrop-filter]:bg-surface/50 border-b border-white/10">
|
||||
@@ -142,12 +167,15 @@
|
||||
</button>
|
||||
{#if menuOpen}
|
||||
<div class="dropdown" role="menu">
|
||||
{#if typeof user.rank === 'number' && user.rank > 3000}
|
||||
{#if requiresWarning}
|
||||
<div class="dropdown-warning">
|
||||
<strong>Heads up:</strong>
|
||||
<span>Tools are limited to <a class="underline" href="https://www.patreon.com/BeatLeader" target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> or players ranked in the global top 3k.</span>
|
||||
<span>Tools are limited to <a class="underline" href="https://www.patreon.com/BeatLeader" target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> or players ranked better than {baselineCopy}.</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if user?.id === PLEB_BEATLEADER_ID}
|
||||
<a href="/tools/stats" class="dropdown-item" on:click={closeMenu}>Stats</a>
|
||||
{/if}
|
||||
{#if dev}
|
||||
<a href="/testing" class="dropdown-item" on:click={closeMenu}>Testing</a>
|
||||
{/if}
|
||||
@@ -185,12 +213,15 @@
|
||||
<span class="text-sm text-muted">Connecting…</span>
|
||||
{:else if user}
|
||||
<div class="border border-white/10 rounded-md overflow-hidden">
|
||||
{#if typeof user.rank === 'number' && user.rank > 3000}
|
||||
{#if requiresWarning}
|
||||
<div class="dropdown-warning mobile">
|
||||
<strong>Heads up:</strong>
|
||||
<span>Tools are limited to <a class="underline" href="https://www.patreon.com/BeatLeader" target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> or players inside the global top 3k.</span>
|
||||
<span>Tools are limited to <a class="underline" href="https://www.patreon.com/BeatLeader" target="_blank" rel="noreferrer noopener">BeatLeader supporters</a> or players ranked better than {baselineCopy}.</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if user?.id === PLEB_BEATLEADER_ID}
|
||||
<a href="/tools/stats" class="dropdown-item" on:click={close}>Stats</a>
|
||||
{/if}
|
||||
{#if dev}
|
||||
<a href="/testing" class="dropdown-item" on:click={close}>Testing</a>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user