v0.5.59: item counter evidence for fears, catch up Web features to site version.
Ship OpenDota counter-stats reordering for feared items, finalize SITE_VERSION/docs for rankings/streamers/trends/matches/mechanics and draft archetypes, and ignore regenerable Web data caches. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+2756
-41
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* Local defaults; production export overwrites via export_relations_site.py. */
|
||||
var SITE_VERSION = "0.4.2";
|
||||
var SITE_VERSION = "0.5.59";
|
||||
var ABILITY_VIDEO_BASE = "";
|
||||
var STATIC_ASSET_BASE = "";
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>上分帝</title>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<title>DOTA2 上分帝</title>
|
||||
<link rel="icon" href="/ui-icon/dota2_logo.png" type="image/png" />
|
||||
<link rel="stylesheet" href="/style.css?v=0.5.59" />
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<img class="brand-logo" src="ui-icon/dota2_logo.png" alt="Dota 2" />
|
||||
<div class="brand" aria-label="Dota 2 上分帝">
|
||||
<img class="brand-logo" src="/ui-icon/dota2_logo_wordmark.png" alt="Dota 2" />
|
||||
<span class="brand-title">上分帝</span>
|
||||
</div>
|
||||
<a
|
||||
@@ -24,6 +25,10 @@
|
||||
</a>
|
||||
<nav class="main-tabs" aria-label="主分页">
|
||||
<button type="button" class="main-tab active" data-page="heroes">英雄</button>
|
||||
<button type="button" class="main-tab" data-page="rankings">排行</button>
|
||||
<button type="button" class="main-tab" data-page="streamers">主播</button>
|
||||
<button type="button" class="main-tab" data-page="trends">走势</button>
|
||||
<button type="button" class="main-tab" data-page="mechanics">机制</button>
|
||||
<button type="button" class="main-tab" data-page="items">物品</button>
|
||||
<button type="button" class="main-tab" data-page="patches">版本</button>
|
||||
</nav>
|
||||
@@ -44,6 +49,67 @@
|
||||
<div class="columns" id="columns"></div>
|
||||
</main>
|
||||
|
||||
<main id="rankings-view" class="board rankings-board hidden">
|
||||
<div class="rankings-cluster">
|
||||
<div class="rankings-center-wrap">
|
||||
<div class="rankings-body" id="rankings-body"></div>
|
||||
<aside class="rankings-aside" aria-label="排行筛选">
|
||||
<h2 class="rankings-title">
|
||||
<span class="rankings-title-row">
|
||||
<span class="rankings-kicker" id="rankings-kicker">Immortal 排行榜</span>
|
||||
<span id="rankings-tip-slot"></span>
|
||||
</span>
|
||||
</h2>
|
||||
<div class="rankings-regions" id="rankings-regions" role="tablist" aria-label="选择地区"></div>
|
||||
<p class="rankings-sub" id="rankings-sub"></p>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<main id="streamers-view" class="board rankings-board streamers-board hidden">
|
||||
<div class="rankings-cluster">
|
||||
<div class="rankings-center-wrap streamers-center-wrap">
|
||||
<div class="rankings-body streamers-body" id="streamers-body"></div>
|
||||
<footer class="streamers-foot" id="streamers-foot" aria-hidden="true"></footer>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<main id="trends-view" class="board rankings-board trends-board hidden">
|
||||
<div class="rankings-cluster">
|
||||
<div class="rankings-center-wrap trends-center-wrap">
|
||||
<div class="rankings-body" id="trends-body"></div>
|
||||
<aside class="rankings-aside" aria-label="走势筛选">
|
||||
<h2 class="rankings-title">
|
||||
<span class="rankings-title-row">
|
||||
<span class="rankings-kicker" id="trends-kicker">过去 8 周走势</span>
|
||||
</span>
|
||||
</h2>
|
||||
<div class="trends-brackets" id="trends-brackets" aria-label="选择段位"></div>
|
||||
<div class="trends-sort" id="trends-sort" role="tablist" aria-label="排序"></div>
|
||||
<p class="rankings-sub" id="trends-sub"></p>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<main id="mechanics-view" class="board rankings-board mechanics-board hidden">
|
||||
<div class="rankings-cluster">
|
||||
<div class="rankings-center-wrap mechanics-center-wrap">
|
||||
<div class="rankings-body mechanics-body" id="mechanics-body"></div>
|
||||
<aside class="rankings-aside" aria-label="机制筛选">
|
||||
<h2 class="rankings-title">
|
||||
<span class="rankings-title-row">
|
||||
<span class="rankings-kicker">机制查询</span>
|
||||
</span>
|
||||
</h2>
|
||||
<div class="mechanics-effects" id="mechanics-effects" aria-label="选择状态效果"></div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<main id="items-view" class="board items-board hidden">
|
||||
<div class="items-cluster">
|
||||
<div class="items-main">
|
||||
@@ -70,8 +136,8 @@
|
||||
|
||||
<section class="detail" id="detail" aria-live="polite"></section>
|
||||
|
||||
<script src="/config.js?v=0.4.2"></script>
|
||||
<script src="/router.js?v=0.4.2"></script>
|
||||
<script src="/app.js?v=0.4.2"></script>
|
||||
<script src="/config.js?v=0.5.59"></script>
|
||||
<script src="/router.js?v=0.5.59"></script>
|
||||
<script src="/app.js?v=0.5.59"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+94
-7
@@ -1,11 +1,20 @@
|
||||
/* global window, history, location */
|
||||
|
||||
/**
|
||||
* Hash-based router for the relations preview (web/relations).
|
||||
* Hash-based router for the Climperor web site (web/relations).
|
||||
*
|
||||
* Synchronizes the browser URL with app state across these dimensions:
|
||||
* - page: heroes | items | patches (top-level tab)
|
||||
* - hero: selected hero key + detail sub-tab (skills|core|fears|patches)
|
||||
* - page: heroes | rankings | streamers | trends | mechanics | items | patches (top-level tab)
|
||||
* - hero: selected hero key + detail sub-tab
|
||||
* (skills|core|fears|trends|matchups|matches|streamers|patches; legacy stats → trends)
|
||||
* - rankings: Immortal leaderboard region
|
||||
* #/rankings[/region] (legacy #/rankings/meta[/bracket] → players / china)
|
||||
* - streamers: curated Douyin streamer directory
|
||||
* #/streamers
|
||||
* - trends: medal bracket for the 8-week win/pick board
|
||||
* #/trends[/bracket][?sort=pr] (default bracket legend, sort wr omitted)
|
||||
* - mechanics: applies-effect query (dispel / CC)
|
||||
* #/mechanics[/{effect}] (default effect basic_dispel omitted)
|
||||
* - item: selected shop item key (items page)
|
||||
* - patch: selected version string (patches page; latest when absent)
|
||||
* - query params: tags=csv (heroes), q=search text (heroes + items)
|
||||
@@ -21,8 +30,44 @@
|
||||
*/
|
||||
|
||||
const ROUTE_DEFAULT = "#/heroes";
|
||||
const VALID_PAGES = ["heroes", "items", "patches"];
|
||||
const VALID_DETAIL_TABS = ["skills", "core", "fears", "patches"];
|
||||
const VALID_PAGES = ["heroes", "rankings", "streamers", "trends", "mechanics", "items", "patches"];
|
||||
const VALID_DETAIL_TABS = [
|
||||
"skills",
|
||||
"core",
|
||||
"fears",
|
||||
"trends",
|
||||
"stats",
|
||||
"matchups",
|
||||
"matches",
|
||||
"streamers",
|
||||
"patches",
|
||||
];
|
||||
const DEFAULT_RANKING_REGION = "china";
|
||||
const DEFAULT_TRENDS_BRACKET = "legend";
|
||||
const DEFAULT_TRENDS_SORT = "wr_end";
|
||||
const VALID_TRENDS_SORTS = ["wr_end", "pr_end"];
|
||||
const TRENDS_SORT_URL = { wr_end: "wr", pr_end: "pr" };
|
||||
const TRENDS_SORT_FROM_URL = { wr: "wr_end", pr: "pr_end", wr_end: "wr_end", pr_end: "pr_end" };
|
||||
const DEFAULT_MECHANIC_EFFECT = "basic_dispel";
|
||||
const VALID_MECHANIC_EFFECTS = [
|
||||
"basic_dispel",
|
||||
"strong_dispel",
|
||||
"root",
|
||||
"disarm",
|
||||
"silence",
|
||||
"mute",
|
||||
"stun",
|
||||
"hex",
|
||||
"break",
|
||||
"sleep",
|
||||
"fear",
|
||||
"taunt",
|
||||
"blind",
|
||||
"leash",
|
||||
"invis",
|
||||
"ethereal",
|
||||
"cyclone",
|
||||
];
|
||||
|
||||
let _deps = null;
|
||||
|
||||
@@ -46,6 +91,10 @@ function parseHash(hash) {
|
||||
detailTab: null,
|
||||
itemKey: null,
|
||||
patchVersion: null,
|
||||
rankingRegion: null,
|
||||
trendsBracket: null,
|
||||
trendsSort: null,
|
||||
mechanicEffect: null,
|
||||
tags: null,
|
||||
query: null,
|
||||
itemQuery: null,
|
||||
@@ -64,6 +113,15 @@ function parseHash(hash) {
|
||||
if (page === "heroes") {
|
||||
if (segs[1]) out.heroKey = safeDecode(segs[1]);
|
||||
if (segs[2]) out.detailTab = safeDecode(segs[2]);
|
||||
} else if (page === "rankings") {
|
||||
// Legacy #/rankings/meta[/bracket] → Immortal players board (default region).
|
||||
if (segs[1] && segs[1] !== "meta") {
|
||||
out.rankingRegion = safeDecode(segs[1]);
|
||||
}
|
||||
} else if (page === "trends") {
|
||||
if (segs[1]) out.trendsBracket = safeDecode(segs[1]);
|
||||
} else if (page === "mechanics") {
|
||||
if (segs[1]) out.mechanicEffect = safeDecode(segs[1]);
|
||||
} else if (page === "items") {
|
||||
if (segs[1]) out.itemKey = safeDecode(segs[1]);
|
||||
} else if (page === "patches") {
|
||||
@@ -81,6 +139,12 @@ function parseHash(hash) {
|
||||
if (page === "items") out.itemQuery = qParam;
|
||||
else out.query = qParam;
|
||||
}
|
||||
if (page === "trends") {
|
||||
const sortParam = params.get("sort");
|
||||
if (sortParam && TRENDS_SORT_FROM_URL[sortParam]) {
|
||||
out.trendsSort = TRENDS_SORT_FROM_URL[sortParam];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -99,10 +163,33 @@ function serializeHash(state) {
|
||||
if (state.page === "heroes") {
|
||||
if (state.selectedKey) {
|
||||
hash += "/" + encodeURIComponent(state.selectedKey);
|
||||
if (state.detailTab && VALID_DETAIL_TABS.includes(state.detailTab)) {
|
||||
hash += "/" + encodeURIComponent(state.detailTab);
|
||||
let tab = state.detailTab;
|
||||
if (tab === "stats") tab = "trends"; // normalize legacy alias in URL
|
||||
if (tab && VALID_DETAIL_TABS.includes(tab) && tab !== "stats") {
|
||||
hash += "/" + encodeURIComponent(tab);
|
||||
}
|
||||
}
|
||||
} else if (state.page === "rankings") {
|
||||
// Omit region when it is the default (china) — bare #/rankings means China.
|
||||
const region = state.rankingRegion || DEFAULT_RANKING_REGION;
|
||||
if (region && region !== DEFAULT_RANKING_REGION) {
|
||||
hash += "/" + encodeURIComponent(region);
|
||||
}
|
||||
} else if (state.page === "trends") {
|
||||
// Omit bracket when it is the default (legend) — bare #/trends means legend.
|
||||
const bracket = state.trendsBracket || DEFAULT_TRENDS_BRACKET;
|
||||
if (bracket && bracket !== DEFAULT_TRENDS_BRACKET) {
|
||||
hash += "/" + encodeURIComponent(bracket);
|
||||
}
|
||||
const sort = state.trendsSort || DEFAULT_TRENDS_SORT;
|
||||
if (VALID_TRENDS_SORTS.includes(sort) && sort !== DEFAULT_TRENDS_SORT) {
|
||||
hash += "?sort=" + encodeURIComponent(TRENDS_SORT_URL[sort] || sort);
|
||||
}
|
||||
} else if (state.page === "mechanics") {
|
||||
const effect = state.mechanicEffect || DEFAULT_MECHANIC_EFFECT;
|
||||
if (effect && effect !== DEFAULT_MECHANIC_EFFECT) {
|
||||
hash += "/" + encodeURIComponent(effect);
|
||||
}
|
||||
} else if (state.page === "items") {
|
||||
if (state.selectedItemKey) {
|
||||
hash += "/" + encodeURIComponent(state.selectedItemKey);
|
||||
|
||||
+1711
-2
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user