feat: add Today environment summary
ci / gitleaks (push) Successful in 51s
ci / docker (push) Successful in 4m34s

This commit is contained in:
2026-09-16 12:23:59 +08:00
parent ed6d999ffb
commit 0a4d5f2f05
12 changed files with 1405 additions and 7 deletions
+16 -2
View File
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { createApp, h } from 'vue'
import { useTaskDueClock } from './task-due-clock'
import { useTaskDueClock, watchShanghaiDateRollover } from './task-due-clock'
const cleanups: Array<() => void> = []
@@ -10,12 +10,13 @@ afterEach(() => {
vi.restoreAllMocks()
})
function mountClock() {
function mountClock(onShanghaiDateRollover?: () => void) {
let clock: ReturnType<typeof useTaskDueClock> | undefined
const host = document.createElement('div')
const app = createApp({
setup() {
clock = useTaskDueClock()
if (onShanghaiDateRollover) watchShanghaiDateRollover(clock, onShanghaiDateRollover)
return () => h('span', String(clock!.value))
},
})
@@ -65,6 +66,19 @@ describe('useTaskDueClock', () => {
expect(vi.getTimerCount()).toBe(1)
})
it('refreshes once when the shared visible clock crosses Shanghai midnight', () => {
vi.useFakeTimers()
vi.setSystemTime(new Date('2026-09-16T15:59:30.000Z'))
const refresh = vi.fn()
mountClock(refresh)
vi.advanceTimersByTime(30_000)
expect(refresh).toHaveBeenCalledTimes(1)
vi.advanceTimersByTime(60_000)
expect(refresh).toHaveBeenCalledTimes(1)
})
it('removes visibility, focus and pageshow listeners and clears the timer on unmount', () => {
vi.useFakeTimers()
const removeDocument = vi.spyOn(document, 'removeEventListener')
+20 -1
View File
@@ -1,4 +1,23 @@
import { onMounted, onUnmounted, ref, type Ref } from 'vue'
import { onMounted, onUnmounted, ref, watch, type Ref } from 'vue'
export function shanghaiDateKey(nowMs = Date.now()) {
return new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).format(new Date(nowMs))
}
export function watchShanghaiDateRollover(clock: Ref<number>, refresh: () => void) {
let dateKey = shanghaiDateKey(clock.value)
return watch(clock, (nowMs) => {
const nextKey = shanghaiDateKey(nowMs)
if (nextKey === dateKey) return
dateKey = nextKey
refresh()
}, { flush: 'sync' })
}
function nextRefreshDelay(nowMs: number) {
const now = new Date(nowMs)