重构首页为机构落地页,新增终端路由,时区感知 Polymarket 市场发现

This commit is contained in:
2569718930@qq.com
2026-05-25 00:16:53 +08:00
parent 45e9c28437
commit e4d123d94d
23 changed files with 1232 additions and 623 deletions
+2 -1
View File
@@ -54,9 +54,10 @@ export function getAnalyticsSessionId() {
export function markAnalyticsOnce(key: string, scope: "local" | "session" = "session") {
if (!isClient()) return false;
const storage = scope === "local" ? window.localStorage : window.sessionStorage;
const normalizedKey = `polyweather:analytics:once:${key}`;
try {
const storage = scope === "local" ? window.localStorage : window.sessionStorage;
if (!storage) return true;
if (storage.getItem(normalizedKey) === "1") {
return false;
}
+34 -10
View File
@@ -58,8 +58,14 @@ async function fetchJson<T>(
options?: { cache?: RequestCache; timeoutMs?: number },
): Promise<T> {
const timeoutMs = options?.timeoutMs;
const controller = timeoutMs ? new AbortController() : null;
const timeoutId = controller
const controller =
timeoutMs && typeof AbortController !== "undefined"
? new AbortController()
: null;
const timeoutId =
controller &&
typeof window !== "undefined" &&
typeof window.setTimeout === "function"
? window.setTimeout(() => controller.abort(), timeoutMs)
: null;
const headers = await buildBrowserBackendHeaders({
@@ -80,7 +86,9 @@ async function fetchJson<T>(
throw error;
} finally {
if (timeoutId != null) {
window.clearTimeout(timeoutId);
if (typeof window.clearTimeout === "function") {
window.clearTimeout(timeoutId);
}
}
}
@@ -222,7 +230,11 @@ function readLegacyCache(raw: string): CityCacheBundle {
export const dashboardClient = {
clearCityDetailCache() {
if (!isClient()) return;
window.sessionStorage.removeItem(CACHE_KEY);
try {
window.sessionStorage?.removeItem(CACHE_KEY);
} catch {
// Storage can be unavailable in embedded/private browser contexts.
}
},
async getCities() {
@@ -232,13 +244,24 @@ export const dashboardClient = {
sendPriorityWarmHint(timezone?: string | null) {
if (!isClient()) return;
if (
typeof fetch !== "function" ||
typeof Intl === "undefined" ||
!window.sessionStorage
) {
return;
}
const tz = String(
timezone || Intl.DateTimeFormat().resolvedOptions().timeZone || "",
).trim();
if (!tz) return;
const cacheKey = `${PRIORITY_WARM_SESSION_KEY}:${tz}`;
if (window.sessionStorage.getItem(cacheKey)) return;
window.sessionStorage.setItem(cacheKey, "1");
try {
if (window.sessionStorage.getItem(cacheKey)) return;
window.sessionStorage.setItem(cacheKey, "1");
} catch {
return;
}
const params = new URLSearchParams({ timezone: tz });
void fetch(`/api/system/priority-warm?${params.toString()}`, {
method: "POST",
@@ -532,10 +555,11 @@ export const dashboardClient = {
const entries = Object.fromEntries(
topEntries.map((e) => [e.cityName, { cachedAt: e.cachedAt, detail: e.detail, revision: e.revision }]),
);
window.sessionStorage.setItem(
CACHE_KEY,
JSON.stringify({ entries }),
);
try {
window.sessionStorage?.setItem(CACHE_KEY, JSON.stringify({ entries }));
} catch {
// Storage can be unavailable in embedded/private browser contexts.
}
},
writeCityDetailCache(data: Record<string, CityDetail>) {
+1 -1
View File
@@ -382,7 +382,7 @@ export function normalizeLocale(value?: string | null): Locale {
export function getInitialLocaleFromNavigator(): Locale {
if (typeof window === "undefined") return DEFAULT_LOCALE;
return normalizeLocale(window.navigator.language);
return normalizeLocale(window.navigator?.language);
}
export function formatMessage(