@@ -19,6 +19,11 @@ const getEarliestTime = (times: Array<number | undefined>) => {
1919 return validTimes . length ? Math . min ( ...validTimes ) : undefined ;
2020} ;
2121
22+ const getLatestTime = ( times : Array < number | undefined > ) => {
23+ const validTimes = times . filter ( ( time ) : time is number => time !== undefined ) ;
24+ return validTimes . length ? Math . max ( ...validTimes ) : undefined ;
25+ } ;
26+
2227export const formatElapsedMMSS = ( startTime : number | string | undefined , now : Date ) => {
2328 const start = typeof startTime === 'number' ? startTime : getTime ( startTime ) ;
2429
@@ -36,6 +41,20 @@ export const formatElapsedMMSS = (startTime: number | string | undefined, now: D
3641export const getGroupScheduledStartTime = ( group ?: RemoteActivityGroup ) =>
3742 getEarliestTime ( group ?. scheduledActivities . map ( ( activity ) => getTime ( activity . startTime ) ) || [ ] ) ;
3843
44+ const getActiveGroupsScheduledStartTime = ( groups : RemoteActivityGroup [ ] ) =>
45+ getEarliestTime (
46+ groups . flatMap ( ( group ) =>
47+ group . scheduledActivities . map ( ( activity ) => getTime ( activity . startTime ) ) ,
48+ ) ,
49+ ) ;
50+
51+ const getActiveGroupsScheduledEndTime = ( groups : RemoteActivityGroup [ ] ) =>
52+ getLatestTime (
53+ groups . flatMap ( ( group ) =>
54+ group . scheduledActivities . map ( ( activity ) => getTime ( activity . endTime ) ) ,
55+ ) ,
56+ ) ;
57+
3958export const getActiveGroupStartTime = ( groups : RemoteActivityGroup [ ] ) =>
4059 getEarliestTime (
4160 groups . flatMap ( ( group ) => {
@@ -51,6 +70,33 @@ export const getActiveGroupStartTime = (groups: RemoteActivityGroup[]) =>
5170 } ) ,
5271 ) ;
5372
73+ export const getActiveGroupsScheduledDuration = ( groups : RemoteActivityGroup [ ] ) => {
74+ const start = getActiveGroupsScheduledStartTime ( groups ) ;
75+ const end = getActiveGroupsScheduledEndTime ( groups ) ;
76+
77+ if ( start === undefined || end === undefined || end <= start ) {
78+ return undefined ;
79+ }
80+
81+ return end - start ;
82+ } ;
83+
84+ const formatDurationMinutes = ( duration : number | undefined ) => {
85+ if ( duration === undefined ) {
86+ return '0 minutes' ;
87+ }
88+
89+ const minutes = Math . max ( 1 , Math . round ( duration / MINUTE ) ) ;
90+ const unit = minutes === 1 ? 'minute' : 'minutes' ;
91+
92+ return `${ minutes } ${ unit } ` ;
93+ } ;
94+
95+ export const formatElapsedDuration = ( groups : RemoteActivityGroup [ ] , now : Date ) =>
96+ `${ formatElapsedMMSS ( getActiveGroupStartTime ( groups ) , now ) } / ${ formatDurationMinutes (
97+ getActiveGroupsScheduledDuration ( groups ) ,
98+ ) } `;
99+
54100export const formatNextActivityOffset = ( nextGroup : RemoteActivityGroup | undefined , now : Date ) => {
55101 const nextStart = getGroupScheduledStartTime ( nextGroup ) ;
56102
@@ -79,25 +125,31 @@ export const formatNextActivityOffset = (nextGroup: RemoteActivityGroup | undefi
79125
80126export const getRemoteBarProgress = ( {
81127 activeGroups,
82- nextGroup,
83128 now,
84129} : {
85130 activeGroups : RemoteActivityGroup [ ] ;
86- nextGroup ?: RemoteActivityGroup ;
87131 now : Date ;
88132} ) => {
89133 const activeStart = getActiveGroupStartTime ( activeGroups ) ;
90- const nextStart = getGroupScheduledStartTime ( nextGroup ) ;
91-
92- if ( activeStart === undefined || nextStart === undefined ) {
93- return nextStart !== undefined && now . getTime ( ) >= nextStart ? 100 : 0 ;
94- }
95-
96- const duration = nextStart - activeStart ;
134+ const duration = getActiveGroupsScheduledDuration ( activeGroups ) ;
97135
98- if ( duration <= 0 ) {
99- return now . getTime ( ) >= nextStart ? 100 : 0 ;
136+ if ( activeStart === undefined || duration === undefined ) {
137+ return {
138+ percent : 0 ,
139+ tone : 'normal' as const ,
140+ } ;
100141 }
101142
102- return clampPercent ( ( ( now . getTime ( ) - activeStart ) / duration ) * 100 ) ;
143+ const elapsed = Math . max ( 0 , now . getTime ( ) - activeStart ) ;
144+ const percent = ( elapsed / duration ) * 100 ;
145+
146+ return {
147+ percent : clampPercent ( percent ) ,
148+ tone :
149+ percent > 100
150+ ? ( 'overdue' as const )
151+ : percent >= 95
152+ ? ( 'warning' as const )
153+ : ( 'normal' as const ) ,
154+ } ;
103155} ;
0 commit comments