diff --git a/viewer/src/api.ts b/viewer/src/api.ts index 72dc618..ee049ed 100644 --- a/viewer/src/api.ts +++ b/viewer/src/api.ts @@ -1,15 +1,19 @@ import type { EventsResponse, ExclusionsMap, QuestData } from "./types"; -const DATA_URL = import.meta.env.VITE_DATA_URL as string; +function getDataUrl(): string { + const url = import.meta.env.VITE_DATA_URL; + if (!url) throw new Error("VITE_DATA_URL is not set"); + return url; +} export async function fetchEvents(signal?: AbortSignal): Promise { - const res = await fetch(`${DATA_URL}/events.json`, { signal }); + const res = await fetch(`${getDataUrl()}/events.json`, { signal }); if (!res.ok) throw new Error(`Failed to fetch events: ${res.status}`); return res.json(); } export async function fetchExclusions(signal?: AbortSignal): Promise { - const res = await fetch(`${DATA_URL}/exclusions.json`, { signal }); + const res = await fetch(`${getDataUrl()}/exclusions.json`, { signal }); if (!res.ok) return {}; return res.json(); } @@ -19,7 +23,7 @@ export async function fetchQuestData( questId: string, signal?: AbortSignal, ): Promise { - const res = await fetch(`${DATA_URL}/${eventId}/${questId}.json`, { signal }); + const res = await fetch(`${getDataUrl()}/${eventId}/${questId}.json`, { signal }); // S3 + CloudFront では未作成のオブジェクトに対して 403 が返るため、 // 404 と同様に「データ未登録」として扱い、エラーではなく null を返す if (res.status === 403 || res.status === 404) return null; diff --git a/viewer/src/components/ReportTable.tsx b/viewer/src/components/ReportTable.tsx index 2f2e559..9ff799e 100644 --- a/viewer/src/components/ReportTable.tsx +++ b/viewer/src/components/ReportTable.tsx @@ -3,7 +3,7 @@ import { createExcludedIdSet, isOutlier } from "../aggregate"; import { formatItemHeader, formatNote, formatTimestamp } from "../formatters"; import { useSortState } from "../hooks/useSortState"; import type { SortKey } from "../reportTableUtils"; -import { sortReports } from "../reportTableUtils"; +import { getReporterName, sortReports } from "../reportTableUtils"; import type { Exclusion, ItemOutlierStats, ItemStats, Report } from "../types"; import { sortIndicator, @@ -80,13 +80,13 @@ export function ReportTable({ reports, exclusions, itemNames, outlierStats, stat return ( {excluded ? "除外" : "有効"} - + - {r.reporterName || r.reporter || "匿名"} + {getReporterName(r)} {r.runcount} diff --git a/viewer/src/reporterSummaryUtils.ts b/viewer/src/reporterSummaryUtils.ts index 0dac7c6..0493372 100644 --- a/viewer/src/reporterSummaryUtils.ts +++ b/viewer/src/reporterSummaryUtils.ts @@ -1,3 +1,4 @@ +import { getReporterName } from "./reportTableUtils"; import type { ExclusionsMap, QuestData, SortDir } from "./types"; export interface ReportDetail { @@ -33,7 +34,7 @@ export function aggregateReporters( for (const r of qd.reports) { if (excludedIds.has(r.id)) continue; - const name = r.reporterName || r.reporter || "匿名"; + const name = getReporterName(r); const entry = map.get(name) ?? { reporter: name, xId: r.reporter || "",