重构首页为机构落地页,新增终端路由,时区感知 Polymarket 市场发现
This commit is contained in:
@@ -4,7 +4,19 @@ import { useEffect } from "react";
|
||||
|
||||
export function RegisterSW() {
|
||||
useEffect(() => {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
|
||||
navigator.serviceWorker
|
||||
.getRegistrations()
|
||||
.then((registrations) =>
|
||||
Promise.all(registrations.map((registration) => registration.unregister())),
|
||||
)
|
||||
.catch(() => {});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
|
||||
navigator.serviceWorker.register("/sw.js").catch(() => {});
|
||||
}
|
||||
}, []);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -102,12 +102,12 @@ export function AiPinnedForecastView({
|
||||
<div className="scan-ai-workspace empty">
|
||||
<div className="scan-empty-state">
|
||||
<div className="scan-empty-title">
|
||||
{isEn ? "Click a city on the map" : "从分布视图点击城市"}
|
||||
{isEn ? "Select a city from the market list" : "从市场列表选择城市"}
|
||||
</div>
|
||||
<div className="scan-empty-copy">
|
||||
{isEn
|
||||
? "Selected cities will appear here as deep analysis blocks."
|
||||
: "被点击的城市会加入深度分析页,并保留为城市分析区块。"}
|
||||
: "选中的城市会加入深度分析页,并保留为城市分析区块。"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -127,8 +127,8 @@ export function AiPinnedForecastView({
|
||||
</div>
|
||||
<p>
|
||||
{isEn
|
||||
? "Map clicks add cities here. City analysis stays here until you remove it."
|
||||
: "地图点击会把城市加入这里;城市分析会保留,直到你手动移除。"}
|
||||
? "Market-list selections add cities here. City analysis stays here until you remove it."
|
||||
: "市场列表选择会把城市加入这里;城市分析会保留,直到你手动移除。"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="scan-ai-city-jumpbar" aria-label={isEn ? "Selected city shortcuts" : "已选城市快捷跳转"}>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import type { Dispatch, SetStateAction } from "react";
|
||||
import { LogIn, MessageCircle, Moon, Sun, UserRound } from "lucide-react";
|
||||
import { LogIn, UserRound } from "lucide-react";
|
||||
import { ProFeaturePaywall } from "@/components/dashboard/ProFeaturePaywall";
|
||||
import { LoadingSignal } from "@/components/dashboard/scan-terminal/LoadingSignal";
|
||||
import type { Locale } from "@/lib/i18n";
|
||||
|
||||
export type ScanTerminalContentView = "city-list" | "analysis" | "map";
|
||||
export type ScanTerminalContentView = "city-list" | "analysis";
|
||||
|
||||
type ThemeMode = "dark" | "light";
|
||||
|
||||
@@ -34,8 +34,8 @@ export function ScanTerminalLoadingScreen({
|
||||
</strong>
|
||||
<span>
|
||||
{isEn
|
||||
? "Start from the map, then open city cards to verify weather evidence"
|
||||
: "从地图选城市,再打开决策卡验证天气证据"}
|
||||
? "Loading paid decision cards, city evidence, and market signals"
|
||||
: "正在加载付费决策卡、城市证据和市场信号"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="scan-topbar-actions">
|
||||
@@ -91,8 +91,8 @@ export function ScanTerminalTopBar({
|
||||
</strong>
|
||||
<span>
|
||||
{isEn
|
||||
? "Start from the map, then open city cards to verify weather evidence"
|
||||
: "从地图选城市,再打开决策卡验证天气证据"}
|
||||
? "Paid workspace for city evidence, model signals, and weather-market decisions"
|
||||
: "面向付费用户的城市证据、模型信号与天气市场决策工作区"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="scan-topbar-actions">
|
||||
|
||||
@@ -37,6 +37,9 @@ export function useScanTerminalQuery({
|
||||
showLoading?: boolean;
|
||||
} = {}) => {
|
||||
if (proAccessLoading || !isPro) return;
|
||||
if (typeof fetch !== "function" || typeof AbortController === "undefined") {
|
||||
return;
|
||||
}
|
||||
if (forceRefresh) {
|
||||
lastForcedScanRefreshAtRef.current = Date.now();
|
||||
}
|
||||
@@ -75,6 +78,13 @@ export function useScanTerminalQuery({
|
||||
|
||||
useEffect(() => {
|
||||
if (proAccessLoading || !isPro) return;
|
||||
if (
|
||||
typeof window === "undefined" ||
|
||||
typeof window.setInterval !== "function" ||
|
||||
typeof window.clearInterval !== "function"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const intervalId = window.setInterval(() => {
|
||||
if (
|
||||
!shouldRunAutoTerminalRefresh({
|
||||
|
||||
@@ -10,6 +10,13 @@ export function useUserLocalClock() {
|
||||
|
||||
useEffect(() => {
|
||||
setUserLocalTime(formatUserLocalTime());
|
||||
if (
|
||||
typeof window === "undefined" ||
|
||||
typeof window.setInterval !== "function" ||
|
||||
typeof window.clearInterval !== "function"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const intervalId = window.setInterval(() => {
|
||||
setUserLocalTime(formatUserLocalTime());
|
||||
}, 10_000);
|
||||
|
||||
Reference in New Issue
Block a user