新增 v1.5.6 升级公告,3 天后自动消失

公告展示决策终端 hero 重设计、DEB 统一、亮色补全等变更摘要。
localStorage 记录首次访问时间,超过 3 天自动隐藏。
补全 scan-upgrade-announcement 暗色主题基础样式。

Tested: tsc 全过
This commit is contained in:
2569718930@qq.com
2026-05-06 18:59:20 +08:00
parent 52fa7b0bb3
commit 30a6ff7986
2 changed files with 93 additions and 0 deletions
@@ -115,6 +115,20 @@ function ScanTerminalScreen() {
const [activeView, setActiveView] = useState<ContentView>("map");
const [mapSelectedCityName, setMapSelectedCityName] = useState<string | null>(null);
const [showScanPaywall, setShowScanPaywall] = useState(false);
const [showAnnouncement, setShowAnnouncement] = useState(false);
useEffect(() => {
const key = "polyweather_v156_announcement_seen_at";
const seen = localStorage.getItem(key);
const now = Date.now();
if (!seen) {
localStorage.setItem(key, String(now));
setShowAnnouncement(true);
return;
}
const elapsed = now - Number(seen);
setShowAnnouncement(elapsed < 3 * 24 * 60 * 60 * 1000);
}, []);
const userLocalTime = useUserLocalClock();
const { setThemeMode, themeMode } = useScanTerminalTheme();
const lastMapSelectedCityRef = useRef<string>("");
@@ -508,6 +522,29 @@ function ScanTerminalScreen() {
locale={locale}
/>
{showAnnouncement ? (
<section className="scan-upgrade-announcement" aria-label={isEn ? "Upgrade announcement" : "升级公告"}>
<div className="scan-upgrade-announcement-copy">
<span>{isEn ? "v1.5.6 upgrade" : "v1.5.6 升级公告"}</span>
<strong>
{isEn ? "Scan terminal is upgraded to v1.5.6" : "决策终端已升级到 v1.5.6"}
</strong>
<p>
{isEn
? "City decision cards have been redesigned with a compact hero layout and consistent DEB data source. Sticky headers are removed for smoother scrolling."
: "城市决策卡 hero 布局重新设计,三指标并列对比更直观;DEB 数据源统一不再出现不一致;去除顶部固定效果滚动更流畅。"}
</p>
</div>
<ul>
<li>{isEn ? "Redesigned decision card hero" : "重设计城市决策卡 hero 布局"}</li>
<li>{isEn ? "Unified DEB data source" : "统一 DEB 数据源"}</li>
<li>{isEn ? "Light theme coverage" : "亮色主题补全覆盖"}</li>
<li>{isEn ? "HKO observatory AI read" : "香港天文台观测 AI 解读"}</li>
<li>{isEn ? "Smoother scrolling experience" : "滚动体验优化"}</li>
</ul>
</section>
) : null}
<section className="scan-list-section">
<div className="scan-list-header">
<div className="scan-list-tabs">