feat(ts): 实现 Polaris 可交互首页

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-02 23:53:28 +08:00
co-authored by Claude Opus 4.8
parent 95c3da0f71
commit c3d2a40c1f
71 changed files with 15613 additions and 46 deletions
@@ -0,0 +1,61 @@
"use client"
import { useSyncExternalStore } from "react"
import { getDelayUntilNextMinute } from "@/features/home/lib/date-time"
type Listener = () => void
const listeners = new Set<Listener>()
let currentTime: Date | null = null
let timeoutId: number | undefined
function emitCurrentTime(): Date {
const nextTime = new Date()
currentTime = nextTime
listeners.forEach((listener) => listener())
return nextTime
}
function scheduleNextTick() {
const observedTime = emitCurrentTime()
// 每次 tick 都重新对齐;标签页休眠或主线程阻塞后不会把延迟永久带入后续分钟。
timeoutId = window.setTimeout(
scheduleNextTick,
getDelayUntilNextMinute(observedTime),
)
}
function startClock() {
scheduleNextTick()
}
function stopClock() {
if (timeoutId !== undefined) window.clearTimeout(timeoutId)
timeoutId = undefined
currentTime = null
}
function subscribe(listener: Listener) {
listeners.add(listener)
if (listeners.size === 1) startClock()
return () => {
listeners.delete(listener)
if (listeners.size === 0) stopClock()
}
}
function getSnapshot() {
return currentTime
}
function getServerSnapshot() {
return null
}
export function useClock(): Date | null {
// 服务端与 hydration 首帧固定为空;订阅建立后再读取浏览器时间,避免首屏不一致。
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
}