fix: pending roll sets group expected times as due

This commit is contained in:
Carlos Valente
2026-03-13 22:07:07 +01:00
committed by Carlos Valente
parent a7a78702b1
commit 1cee679397
2 changed files with 27 additions and 23 deletions
+5 -5
View File
@@ -202,20 +202,20 @@ export const useGroupTimerOverView = createSelector((state: RuntimeStore) => ({
clock: state.clock,
mode: state.offset.mode,
groupExpectedEnd: state.offset.expectedGroupEnd,
// we can force these numbers to 0 for this use case to avoid null checks
actualGroupStart: state.rundown.actualGroupStart ?? 0,
actualGroupStart: state.rundown.actualGroupStart,
currentDay: state.rundown.currentDay ?? 0,
playback: state.timer.playback,
phase: state.timer.phase,
}));
export const useFlagTimerOverView = createSelector((state: RuntimeStore) => ({
clock: state.clock,
mode: state.offset.mode,
// we can force these numbers to 0 for this use case to avoid null checks
actualStart: state.rundown.actualStart ?? 0,
plannedStart: state.rundown.plannedStart ?? 0,
actualStart: state.rundown.actualStart,
plannedStart: state.rundown.plannedStart,
currentDay: state.rundown.currentDay ?? 0,
playback: state.timer.playback,
phase: state.timer.phase,
}));
/* ======================= View specific subscriptions ======================= */
@@ -208,26 +208,28 @@ export function MetadataTimes() {
}
function GroupTimes() {
const { clock, mode, groupExpectedEnd, actualGroupStart, currentDay, playback } = useGroupTimerOverView();
const { clock, mode, groupExpectedEnd, actualGroupStart, currentDay, playback, phase } = useGroupTimerOverView();
const currentGroupId = useCurrentGroupId();
const group = useEntry(currentGroupId) as OntimeGroup | null;
const active = isPlaybackActive(playback);
const hasRunningTimer = phase !== TimerPhase.Pending && isPlaybackActive(playback) ;
// the group end time dose not encode any day offsets so it is calculated with group start time and duration
// the group end time does not encode any day offsets so it is calculated with group start time and duration
const plannedGroupEnd = (() => {
if (!active) return null;
if (!hasRunningTimer) return null;
if (!group || group.timeStart === null) return null;
const normalizedClock = clock + currentDay * dayInMs;
return mode === OffsetMode.Absolute
? group.timeStart + group.duration - normalizedClock
: actualGroupStart + group.duration - normalizedClock;
if (mode === OffsetMode.Absolute) {
return group.timeStart + group.duration - normalizedClock;
}
if (actualGroupStart === null) return null;
return actualGroupStart + group.duration - normalizedClock;
})();
const plannedTimeUntilGroupEnd = formatDueTime(plannedGroupEnd, 3, TimerType.CountDown);
const expectedGroupEnd = groupExpectedEnd !== null ? groupExpectedEnd - clock : null;
const expectedGroupEnd = hasRunningTimer && groupExpectedEnd !== null ? groupExpectedEnd - clock : null;
const expectedTimeUntilGroupEnd = formatDueTime(expectedGroupEnd, 3, TimerType.CountDown);
return (
@@ -238,7 +240,7 @@ function GroupTimes() {
<span
className={cx([
style.time,
(!group || !active) && style.muted,
(!group || !hasRunningTimer) && style.muted,
plannedTimeUntilGroupEnd === 'due' && style.dueTime,
])}
>
@@ -250,7 +252,7 @@ function GroupTimes() {
<span
className={cx([
style.time,
!groupExpectedEnd && style.muted,
expectedGroupEnd === null && style.muted,
expectedTimeUntilGroupEnd === 'due' && style.dueTime,
])}
>
@@ -262,25 +264,27 @@ function GroupTimes() {
}
function FlagTimes() {
const { clock, mode, actualStart, plannedStart, playback, currentDay } = useFlagTimerOverView();
const { clock, mode, actualStart, plannedStart, playback, currentDay, phase } = useFlagTimerOverView();
const { id, expectedStart } = useNextFlag();
const entry = useEntry(id) as OntimeEvent | null;
const active = isPlaybackActive(playback);
const hasRunningTimer = phase !== TimerPhase.Pending && isPlaybackActive(playback);
const plannedFlagStart = (() => {
if (!active) return null;
if (!hasRunningTimer) return null;
if (!entry) return null;
const normalizedTimeStart = entry.timeStart + entry.dayOffset * dayInMs;
const normalizedClock = clock + currentDay * dayInMs;
return mode === OffsetMode.Absolute
? normalizedTimeStart - normalizedClock
: normalizedTimeStart + actualStart - plannedStart - normalizedClock;
if (mode === OffsetMode.Absolute) {
return normalizedTimeStart - normalizedClock;
}
if (actualStart === null || plannedStart === null) return null;
return normalizedTimeStart + actualStart - plannedStart - normalizedClock;
})();
const plannedTimeUntilDisplay = formatDueTime(plannedFlagStart, 3, TimerType.CountDown);
const expectedTimeUntil = expectedStart !== null ? expectedStart - clock : null;
const expectedTimeUntil = hasRunningTimer && expectedStart !== null ? expectedStart - clock : null;
const expectedTimeUntilDisplay = formatDueTime(expectedTimeUntil, 3, TimerType.CountDown);
const title = entry?.title ?? null;
@@ -294,7 +298,7 @@ function FlagTimes() {
data-testid='flag-plannedStart'
className={cx([
style.time,
(!entry || !active) && style.muted,
(!entry || !hasRunningTimer) && style.muted,
plannedTimeUntilDisplay === 'due' && style.dueTime,
])}
>