@@ -28,7 +28,7 @@ import {
2828import {
2929 loadSleepTrackerSettings ,
3030} from "./data/settings"
31- import { palette , scoreEmoji , scoreTone } from "./theme"
31+ import { bedtimeEmoji , bedtimeTone , palette , scoreTone } from "./theme"
3232import {
3333 average ,
3434 chunkArray ,
@@ -47,13 +47,37 @@ const BG_SMALL = { style: "systemBackground" as any, shape: { type: "rect" as co
4747const BG_LARGE = { style : "systemBackground" as any , shape : { type : "rect" as const , cornerRadius : 24 } }
4848const CHART_HIDDEN = { chartLegend : "hidden" as const }
4949const 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+
5377function 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-
197213function 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