From f1553d2eebbbb3407c4e73e4b53eeb94eb62dcfc Mon Sep 17 00:00:00 2001 From: wrt122311 <1720122311@qq.com> Date: Fri, 24 Apr 2026 20:12:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20add=20ranking=20mode=20selector=20(?= =?UTF-8?q?=E6=97=A5=E6=A6=9C/=E5=91=A8=E6=A6=9C/=E6=9C=88=E6=A6=9C=20etc.?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a sub-toolbar in the ranking tab with 7 modes: day/week/month/ day_male/day_female/week_original/week_rookie. Clicking a mode clears the grid and reloads with the new mode parameter. Co-Authored-By: Claude Sonnet 4.6 --- web/pixiv_dialog.css | 38 ++++++++++++++++++++++++++ web/pixiv_extension.js | 61 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/web/pixiv_dialog.css b/web/pixiv_dialog.css index 9d80214..9d502f3 100644 --- a/web/pixiv_dialog.css +++ b/web/pixiv_dialog.css @@ -190,6 +190,44 @@ .px-login-tab.active { background: #2a2a3e; color: #cba6f7; } .px-login-tab:hover { color: #cdd6f4; } +/* Ranking pane */ +.px-ranking-pane { + display: flex; + flex-direction: column; + flex: 1; + overflow: hidden; + min-height: 0; +} + +.px-rank-bar { + display: flex; + gap: 4px; + padding: 6px 8px; + border-bottom: 1px solid #3a3a5c; + flex-shrink: 0; + flex-wrap: wrap; + background: #181825; +} + +.px-rank-btn { + padding: 3px 10px; + background: transparent; + border: 1px solid #45475a; + color: #7f849c; + border-radius: 4px; + cursor: pointer; + font-size: 11px; +} +.px-rank-btn:hover { color: #cdd6f4; border-color: #7f849c; } +.px-rank-btn.active { background: #313244; color: #cba6f7; border-color: #cba6f7; } + +.px-rank-grid-wrap { + flex: 1; + overflow: hidden; + display: flex; + min-height: 0; +} + /* Artist pane */ .px-artist-pane { display: flex; diff --git a/web/pixiv_extension.js b/web/pixiv_extension.js index bc74a6f..c661e30 100644 --- a/web/pixiv_extension.js +++ b/web/pixiv_extension.js @@ -36,6 +36,7 @@ function initNodeBrowser(container, idsWidget) { loading: false, activeArtistId: null, artistNextUrl: null, + rankingMode: "day", }, }; @@ -256,11 +257,58 @@ function switchTab(ctx, tabName) { renderSelectedPane(ctx); } else if (tabName === "artists") { renderArtistPane(ctx); + } else if (tabName === "ranking") { + renderRankingPane(ctx); } else { openMainBrowser(ctx); } } +// ── Ranking pane ────────────────────────────────────────────────────────────── +const RANKING_MODES = [ + { id: "day", label: "日榜" }, + { id: "week", label: "周榜" }, + { id: "month", label: "月榜" }, + { id: "day_male", label: "男性向" }, + { id: "day_female", label: "女性向" }, + { id: "week_original", label: "原创" }, + { id: "week_rookie", label: "新人" }, +]; + +function renderRankingPane(ctx) { + const { contentEl, S } = ctx; + contentEl.innerHTML = ` +
+
+ ${RANKING_MODES.map(m => + `` + ).join("")} +
+
+
+
+ +
+
+
+ `; + contentEl.querySelectorAll(".px-rank-btn").forEach(btn => { + btn.addEventListener("click", () => { + if (S.rankingMode === btn.dataset.mode) return; + S.rankingMode = btn.dataset.mode; + S.nextUrls["ranking"] = undefined; + contentEl.querySelectorAll(".px-rank-btn").forEach(b => b.classList.remove("active")); + btn.classList.add("active"); + const grid = contentEl.querySelector(".px-grid"); + if (grid) grid.innerHTML = ""; + loadMoreImages(ctx, "ranking"); + }); + }); + S.nextUrls["ranking"] = undefined; + loadMoreImages(ctx, "ranking"); + setupInfiniteScroll(ctx, "ranking"); +} + // ── Main image browser ──────────────────────────────────────────────────────── async function openMainBrowser(ctx) { const { contentEl, S } = ctx; @@ -276,12 +324,13 @@ async function openMainBrowser(ctx) { setupInfiniteScroll(ctx, tab); } -async function fetchImages(tab, nextUrl) { - const params = nextUrl ? `?next_url=${encodeURIComponent(nextUrl)}` : ""; +async function fetchImages(tab, nextUrl, S) { + const np = nextUrl ? `&next_url=${encodeURIComponent(nextUrl)}` : ""; + const q = nextUrl ? `?next_url=${encodeURIComponent(nextUrl)}` : ""; const urls = { - recommended: `/pixiv/recommended${params}`, - ranking: `/pixiv/ranking${params}`, - bookmarks: `/pixiv/bookmarks${params}`, + recommended: `/pixiv/recommended${q}`, + ranking: `/pixiv/ranking?mode=${encodeURIComponent(S?.rankingMode || "day")}${np}`, + bookmarks: `/pixiv/bookmarks${q}`, }; const resp = await fetch(urls[tab]); if (!resp.ok) { @@ -304,7 +353,7 @@ async function loadMoreImages(ctx, tab) { if (loadEl) loadEl.style.display = "flex"; try { - const data = await fetchImages(tab, nextUrl); + const data = await fetchImages(tab, nextUrl, S); if (S.activeTab !== tab) return; // switched while awaiting S.nextUrls[tab] = data.next_url ?? null; const gridEl = contentEl.querySelector(".px-grid");