mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-30 07:21:32 -07:00
feat(stats): persist trend title visibility and add per-chart title limit
Hidden-title selections in the Trends tab now survive relaunches via localStorage, and a 'Top N per chart' selector (All/3/5/7/10, also persisted) restores the old top-N declutter behavior on demand.
This commit is contained in:
@@ -1,5 +1,62 @@
|
||||
import type { PerAnimeDataPoint } from './StackedTrendChart';
|
||||
|
||||
const HIDDEN_TITLES_KEY = 'subminer-stats-trends-hidden-titles';
|
||||
const MAX_TITLES_KEY = 'subminer-stats-trends-max-titles';
|
||||
|
||||
export const MAX_TITLES_OPTIONS = [3, 5, 7, 10] as const;
|
||||
|
||||
function getStorage(): Storage | null {
|
||||
try {
|
||||
return globalThis.localStorage ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function loadHiddenTitles(): Set<string> {
|
||||
try {
|
||||
const raw = getStorage()?.getItem(HIDDEN_TITLES_KEY);
|
||||
const parsed: unknown = raw ? JSON.parse(raw) : [];
|
||||
if (!Array.isArray(parsed)) return new Set();
|
||||
return new Set(parsed.filter((value): value is string => typeof value === 'string'));
|
||||
} catch {
|
||||
return new Set();
|
||||
}
|
||||
}
|
||||
|
||||
export function saveHiddenTitles(hidden: ReadonlySet<string>): void {
|
||||
try {
|
||||
getStorage()?.setItem(HIDDEN_TITLES_KEY, JSON.stringify([...hidden]));
|
||||
} catch {
|
||||
// Storage can be blocked in private/restricted contexts; keep the in-memory choice.
|
||||
}
|
||||
}
|
||||
|
||||
export function loadMaxTitles(): number | null {
|
||||
try {
|
||||
const raw = getStorage()?.getItem(MAX_TITLES_KEY);
|
||||
if (raw === null || raw === undefined) return null;
|
||||
const value = Number(raw);
|
||||
return Number.isInteger(value) && value > 0 ? value : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function saveMaxTitles(value: number | null): void {
|
||||
try {
|
||||
const storage = getStorage();
|
||||
if (!storage) return;
|
||||
if (value === null) {
|
||||
storage.removeItem(MAX_TITLES_KEY);
|
||||
} else {
|
||||
storage.setItem(MAX_TITLES_KEY, String(value));
|
||||
}
|
||||
} catch {
|
||||
// Storage can be blocked in private/restricted contexts; keep the in-memory choice.
|
||||
}
|
||||
}
|
||||
|
||||
export function buildAnimeVisibilityOptions(datasets: PerAnimeDataPoint[][]): string[] {
|
||||
const totals = new Map<string, number>();
|
||||
for (const dataset of datasets) {
|
||||
|
||||
Reference in New Issue
Block a user