Skip to content

Commit 08877e6

Browse files
committed
Fixes #1:Sleep-Tracker:小组件刷新逻辑调整;入睡时间显示调整
1 parent 01e3eef commit 08877e6

3 files changed

Lines changed: 53 additions & 33 deletions

File tree

Sleep-Tracker/tabs/TrendsTab.tsx

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from "scripting"
1717
import { buildDashboardBundle, type DashboardDay } from "../data/dashboard"
1818
import { MetricTile, SoftCard } from "../components/common"
19-
import { palette, scoreEmoji, scoreLabel, scoreTone, stageColor } from "../theme"
19+
import { bedtimeEmoji, bedtimeTone, palette, scoreLabel, scoreTone, stageColor } from "../theme"
2020
import type { SleepTrackerSettings, SleepTrackerSnapshot } from "../types"
2121
import {
2222
addDays,
@@ -342,52 +342,38 @@ function buildStageSummary(days: DashboardDay[]) {
342342
]
343343
}
344344

345-
function calendarScoreBackground(score: number | null): string {
346-
if (score == null) return "#D9DCE8"
347-
if (score >= 85) return "#80D9B8"
348-
if (score >= 75) return "#FDB44E"
349-
if (score >= 65) return "#FF9C7B"
350-
return "#FF7B7B"
351-
}
352-
353345
function calendarBucketLabel(bucket: TrendBucket, mode: TrendMode): string {
354346
if (mode === "year" || mode === "all") return bucket.label
355347
return formatMonthDayFromKey(bucket.key).replace("月", "/").replace("日", "")
356348
}
357349

358350
function buildCalendarItems(buckets: TrendBucket[], mode: TrendMode, placeholder = false) {
359-
const placeholderTimes = ["22:41", "23:14", "22:58", "23:37", "22:26", "23:05"]
360-
const placeholderScores = [92, 84, 77, 69, 88, 73]
361-
362-
return buckets.map((bucket, index) => {
351+
return buckets.map((bucket) => {
363352
if (placeholder) {
364353
return {
365354
key: bucket.key,
366355
label: calendarBucketLabel(bucket, mode),
367356
bedtime: null,
368357
emoji: null,
369-
background: calendarScoreBackground(null),
358+
background: bedtimeTone(null),
370359
}
371360
}
372361

373362
const daysWithBedtime = bucket.days.filter((day) => day.bedtimeISO)
374363
const bedtimeValues = daysWithBedtime
375364
.map((day) => wrappedMinutes(day.bedtimeISO))
376365
.filter((value): value is number => value != null)
377-
const scores = daysWithBedtime
378-
.map((day) => day.sleepScore)
379-
.filter((value): value is number => value != null)
380-
const averageScore = scores.length ? average(scores) : null
366+
const displayBedtime = bedtimeValues.length ? average(bedtimeValues) : null
381367

382368
return {
383369
key: bucket.key,
384370
label: calendarBucketLabel(bucket, mode),
385371
bedtime:
386372
mode === "week" || mode === "month"
387373
? formatClockFromISO(daysWithBedtime[0]?.bedtimeISO)
388-
: formatWrappedClock(bedtimeValues.length ? average(bedtimeValues) : null),
389-
emoji: scoreEmoji(averageScore),
390-
background: calendarScoreBackground(averageScore),
374+
: formatWrappedClock(displayBedtime),
375+
emoji: bedtimeEmoji(displayBedtime),
376+
background: bedtimeTone(displayBedtime),
391377
}
392378
})
393379
}

Sleep-Tracker/theme.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,24 @@ export function scoreEmoji(score: number | null): string {
6565
return "😣"
6666
}
6767

68+
export function bedtimeEmoji(minutes: number | null): string {
69+
if (minutes == null || !Number.isFinite(minutes)) return "😴"
70+
if (minutes <= 23 * 60 + 30) return "😄"
71+
if (minutes <= 24 * 60 + 30) return "🙂"
72+
if (minutes <= 25 * 60 + 30) return "😐"
73+
if (minutes <= 26 * 60 + 30) return "😕"
74+
return "😣"
75+
}
76+
77+
export function bedtimeTone(minutes: number | null): string {
78+
if (minutes == null || !Number.isFinite(minutes)) return "#D9DCE8"
79+
if (minutes <= 23 * 60 + 30) return "#80D9B8"
80+
if (minutes <= 24 * 60 + 30) return "#A9C7FF"
81+
if (minutes <= 25 * 60 + 30) return "#FDB44E"
82+
if (minutes <= 26 * 60 + 30) return "#FF9C7B"
83+
return "#FF7B7B"
84+
}
85+
6886
export function scoreTone(score: number | null): string {
6987
if (score == null) return "secondaryLabel"
7088
if (score >= 85) return palette.accentDeep

Sleep-Tracker/widget.tsx

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
import {
2929
loadSleepTrackerSettings,
3030
} from "./data/settings"
31-
import { palette, scoreEmoji, scoreTone } from "./theme"
31+
import { bedtimeEmoji, bedtimeTone, palette, scoreTone } from "./theme"
3232
import {
3333
average,
3434
chunkArray,
@@ -47,13 +47,37 @@ const BG_SMALL = { style: "systemBackground" as any, shape: { type: "rect" as co
4747
const BG_LARGE = { style: "systemBackground" as any, shape: { type: "rect" as const, cornerRadius: 24 } }
4848
const CHART_HIDDEN = { chartLegend: "hidden" as const }
4949
const WIDGET_QUERY_DAYS = 60
50+
const WIDGET_RELOAD_TIMES = [
51+
{ hour: 0, minute: 5 },
52+
{ hour: 7, minute: 30 },
53+
{ hour: 9, minute: 30 },
54+
{ hour: 12, minute: 30 },
55+
{ hour: 18, minute: 30 },
56+
]
5057

5158
// ── Helpers ──
5259

60+
function reloadDateAt(base: Date, hour: number, minute: number): Date {
61+
return new Date(base.getFullYear(), base.getMonth(), base.getDate(), hour, minute)
62+
}
63+
64+
function nextReloadDate(now = new Date()): Date {
65+
for (const item of WIDGET_RELOAD_TIMES) {
66+
const candidate = reloadDateAt(now, item.hour, item.minute)
67+
if (candidate.getTime() > now.getTime() + 60 * 1000) {
68+
return candidate
69+
}
70+
}
71+
72+
const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1)
73+
const firstReload = WIDGET_RELOAD_TIMES[0]
74+
return reloadDateAt(tomorrow, firstReload.hour, firstReload.minute)
75+
}
76+
5377
function reloadPolicy() {
5478
return {
5579
policy: "after" as const,
56-
date: new Date(Date.now() + 3 * 60 * 60 * 1000),
80+
date: nextReloadDate(),
5781
}
5882
}
5983

@@ -186,14 +210,6 @@ function formatWrappedClock(minutes: number | null): string {
186210
return `${`${Math.floor(n / 60)}`.padStart(2, "0")}:${`${n % 60}`.padStart(2, "0")}`
187211
}
188212

189-
function bedtimeBadgeTone(score: number | null) {
190-
if (score == null) return "tertiarySystemFill"
191-
if (score >= 85) return "#80D9B8"
192-
if (score >= 75) return "#FDB44E"
193-
if (score >= 65) return "#FF9C7B"
194-
return "#FF7B7B"
195-
}
196-
197213
function bedtimeSummary(days: DashboardDay[]) {
198214
const sleepDays = days.filter((day) => day.bedtimeISO)
199215
const bedtimeValues = sleepDays.map((day) => wrappedMinutes(day.bedtimeISO)).filter((value): value is number => value != null)
@@ -221,9 +237,9 @@ function BedtimeStrip(props: { days: DashboardDay[]; count: number; rows?: numbe
221237
<Text
222238
font={{ size: 22 } as any}
223239
frame={{ width: 34, height: 34, alignment: "center" as any }}
224-
background={{ style: bedtimeBadgeTone(day.sleepScore) as any, shape: { type: "rect", cornerRadius: 17 } } as any}
240+
background={{ style: bedtimeTone(wrappedMinutes(day.bedtimeISO)) as any, shape: { type: "rect", cornerRadius: 17 } } as any}
225241
>
226-
{day.bedtimeISO ? scoreEmoji(day.sleepScore) : "—"}
242+
{day.bedtimeISO ? bedtimeEmoji(wrappedMinutes(day.bedtimeISO)) : "—"}
227243
</Text>
228244
<Text font="caption2" foregroundStyle="secondaryLabel" lineLimit={1}>
229245
{day.bedtimeISO ? formatClockFromISO(day.bedtimeISO) : "--"}

0 commit comments

Comments
 (0)