Skip to content

Commit

Permalink
view options
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Aug 4, 2024
1 parent a503607 commit 1a7bf93
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

$timeline-entry-height: 20px;
$lane-height: 120px;
$distance-from-timeline: 0.5rem;
$timeline-height: 1rem;

.timeline {
Expand All @@ -13,7 +12,6 @@ $timeline-height: 1rem;

.timelineEvents {
position: relative;
top: $distance-from-timeline;
height: 100%;
}

Expand All @@ -30,7 +28,7 @@ $timeline-height: 1rem;
content: '';
position: absolute;
box-sizing: content-box;
top: - calc($distance-from-timeline + $timeline-height);
top: -$timeline-height;
left: 0;
right: 0;
height: $timeline-height;
Expand Down
20 changes: 9 additions & 11 deletions apps/client/src/features/viewers/timeline/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { memo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useViewportSize } from '@mantine/hooks';
import { isOntimeEvent, MaybeNumber, OntimeEvent } from 'ontime-types';
import { dayInMs, getFirstEvent, getLastEvent, MILLIS_PER_HOUR } from 'ontime-utils';
Expand All @@ -18,16 +17,16 @@ function useTimeline(rundown: OntimeEvent[]) {
const lastEnd = lastEvent?.timeEnd ?? 0;
const normalisedLastEnd = lastEnd < firstStart ? lastEnd + dayInMs : lastEnd;

// timeline is padded to nearest hours (floor and ceil)
const startHour = getStartHour(firstStart) * MILLIS_PER_HOUR;
const endHour = getEndHour(normalisedLastEnd) * MILLIS_PER_HOUR;
// we make sure the end accounts for delays
const accumulatedDelay = lastEvent?.delay ?? 0;
// timeline is padded to nearest hours (floor and ceil)
const startHour = getStartHour(firstStart);
const endHour = getEndHour(normalisedLastEnd + accumulatedDelay);

return {
rundown: rundown,
startHour,
endHour,
accumulatedDelay,
};
}

Expand All @@ -42,13 +41,12 @@ function Timeline(props: TimelineProps) {
const { selectedEventId, rundown: baseRundown } = props;
const { width: screenWidth } = useViewportSize();
const timelineData = useTimeline(baseRundown);
const [searchParams] = useSearchParams();

if (timelineData === null) {
return null;
}

const { rundown, startHour, endHour, accumulatedDelay } = timelineData;
const { rundown, startHour, endHour } = timelineData;

let hasTimelinePassedMidnight = false;
let previousEventStartTime: MaybeNumber = null;
Expand All @@ -57,8 +55,8 @@ function Timeline(props: TimelineProps) {

return (
<div className={style.timeline}>
<TimelineMarkers rundown={rundown} />
<ProgressBar startHour={startHour} endHour={endHour + accumulatedDelay} />
<TimelineMarkers startHour={startHour} endHour={endHour} />
<ProgressBar startHour={startHour} endHour={endHour} />
<div className={style.timelineEvents}>
{rundown.map((event) => {
// for now we dont render delays and blocks
Expand All @@ -82,8 +80,8 @@ function Timeline(props: TimelineProps) {
previousEventStartTime = normalisedStart;

const { left: elementLeftPosition, width: elementWidth } = getElementPosition(
startHour,
endHour + accumulatedDelay,
startHour * MILLIS_PER_HOUR,
endHour * MILLIS_PER_HOUR,
normalisedStart + (event.delay ?? 0),
event.duration,
screenWidth,
Expand Down
10 changes: 6 additions & 4 deletions apps/client/src/features/viewers/timeline/TimelineEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ export function TimelineEntry(props: TimelineEntryProps) {
{showTitle && <div>{title}</div>}
</div>
<div className={style.timeOverview} data-status={status}>
<div className={style.duration}>{formattedDuration}</div>
<TimelineEntryStatus status={status} start={delayedStart} />
{status !== 'done' && (
<>
<div className={style.duration}>{formattedDuration}</div>
<TimelineEntryStatus status={status} start={delayedStart} />
</>
)}
</div>
</div>
);
Expand All @@ -84,8 +88,6 @@ function TimelineEntryStatus(props: TimelineEntryStatusProps) {
statusText = getLocalizedString('timeline.live');
} else if (statusText === 'pending') {
statusText = getLocalizedString('timeline.due');
} else if (statusText === 'done') {
statusText = getLocalizedString('timeline.done');
}

return <div className={style.status}>{statusText}</div>;
Expand Down
19 changes: 9 additions & 10 deletions apps/client/src/features/viewers/timeline/TimelinePage.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { MaybeString, OntimeEvent, ProjectData, Settings } from 'ontime-types';

import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
import { formatTime, getDefaultFormat } from '../../../common/utils/time';
import { useTranslation } from '../../../translation/TranslationProvider';
import { isStringBoolean } from '../common/viewUtils';

import Section from './timeline-section/TimelineSection';
import Timeline from './Timeline';
import { getTimelineOptions } from './timeline.options';
import { getFormattedTimeToStart, getUpcomingEvents } from './timeline.utils';
import { getFormattedTimeToStart, getScopedRundown, getUpcomingEvents } from './timeline.utils';

import style from './TimelinePage.module.scss';

Expand All @@ -30,15 +28,18 @@ interface TimelinePageProps {
* There is little point splitting or memoising top level elements
*/
export default function TimelinePage(props: TimelinePageProps) {
const { backstageEvents, events, general, selectedId, settings, time } = props;
const { events, general, selectedId, settings, time } = props;

const [searchParams] = useSearchParams();
const { getLocalizedString } = useTranslation();
const clock = formatTime(time.clock);

const scopedRundown = useMemo(() => {
return getScopedRundown(events, selectedId);
}, [events, selectedId]);

const { now, next, followedBy } = useMemo(() => {
return getUpcomingEvents(backstageEvents, selectedId);
}, [backstageEvents, selectedId]);
return getUpcomingEvents(scopedRundown, selectedId);
}, [scopedRundown, selectedId]);

// populate options
const defaultFormat = getDefaultFormat(settings?.timeFormat);
Expand All @@ -50,8 +51,6 @@ export default function TimelinePage(props: TimelinePageProps) {
const followedByText =
followedBy !== null ? `${followedBy.title} · ${getFormattedTimeToStart(followedBy, time.clock, dueText)}` : '-';

const hideBackstage = isStringBoolean(searchParams.get('hideBackstage'));

return (
<div className={style.timeline}>
<ViewParamsEditor viewOptions={progressOptions} />
Expand All @@ -62,7 +61,7 @@ export default function TimelinePage(props: TimelinePageProps) {
<Section title={getLocalizedString('timeline.live')} content={titleNow} category='now' />
<Section title={getLocalizedString('timeline.followedby')} content={followedByText} category='next' />
</div>
<Timeline selectedEventId={selectedId} rundown={hideBackstage ? events : backstageEvents} />
<Timeline selectedEventId={selectedId} rundown={scopedRundown} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { OntimeEvent } from 'ontime-types';

import { getTimelineSections } from '../timeline.utils';
import { makeTimelineSections } from '../timeline.utils';

import style from './TimelineMarkers.module.scss';

interface TimelineMarkersProps {
rundown: OntimeEvent[];
startHour: number;
endHour: number;
}

export default function TimelineMarkers(props: TimelineMarkersProps) {
const { rundown } = props;
const { startHour, endHour } = props;

const elements = getTimelineSections(rundown);
const elements = makeTimelineSections(startHour, endHour);

return (
<div className={style.markers}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { MILLIS_PER_HOUR } from 'ontime-utils';

import { useClock } from '../../../../common/hooks/useSocket';
import { getRelativePositionX } from '../timeline.utils';

Expand All @@ -12,7 +14,7 @@ export default function ProgressBar(props: ProgressBarProps) {
const { startHour, endHour } = props;
const { clock } = useClock();

const width = getRelativePositionX(startHour, endHour, clock);
const width = getRelativePositionX(startHour * MILLIS_PER_HOUR, endHour * MILLIS_PER_HOUR, clock);

return (
<div className={style.progressBar}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getTimelineOptions = (timeFormat: string): ViewOption[] => {
},
{
id: 'hideBackstage',
title: 'Hide Backstage Events',
title: 'Hide Private Events',
description: 'Whether to hide non-public events',
type: 'boolean',
defaultValue: false,
Expand Down
49 changes: 27 additions & 22 deletions apps/client/src/features/viewers/timeline/timeline.utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { isOntimeEvent, MaybeString, OntimeEvent, OntimeRundown } from 'ontime-types';
import { isOntimeEvent, MaybeString, OntimeEvent } from 'ontime-types';
import {
dayInMs,
getEventWithId,
getFirstEvent,
getLastEvent,
getNextEvent,
MILLIS_PER_HOUR,
millisToString,
Expand All @@ -12,6 +11,7 @@ import {

import { clamp } from '../../../common/utils/math';
import { formatDuration } from '../../../common/utils/time';
import { isStringBoolean } from '../common/viewUtils';

import type { ProgressStatus } from './TimelineEntry';

Expand Down Expand Up @@ -72,26 +72,6 @@ export function makeTimelineSections(firstHour: number, lastHour: number) {
return timelineSections;
}

/**
* Extracts the timeline sections from a rundown
*/
export function getTimelineSections(rundown: OntimeRundown): string[] {
if (rundown.length === 0) {
return [];
}
const { firstEvent } = getFirstEvent(rundown);
const { lastEvent } = getLastEvent(rundown);
const firstStart = firstEvent?.timeStart ?? 0;
const lastEnd = lastEvent?.timeEnd ?? 0;
const normalisedLastEnd = lastEnd < firstStart ? lastEnd + dayInMs : lastEnd;

const startHour = getStartHour(firstStart);
const endHour = getEndHour(normalisedLastEnd);

const elements = makeTimelineSections(startHour, endHour);
return elements;
}

/**
* Returns a formatted label for a progress status
*/
Expand All @@ -107,6 +87,31 @@ export function getStatusLabel(timeToStart: number, status: ProgressStatus): str
return formatDuration(timeToStart);
}

export function getScopedRundown(rundown: OntimeEvent[], selectedEventId: MaybeString): OntimeEvent[] {
if (rundown.length === 0) {
return [];
}

const params = new URL(document.location.href).searchParams;
const hideBackstage = isStringBoolean(params.get('hideBackstage'));
const hidePast = isStringBoolean(params.get('hidePast'));

let scopedRundown = [...rundown];

if (hidePast && selectedEventId) {
const currentIndex = rundown.findIndex((event) => event.id === selectedEventId);
if (currentIndex >= 0) {
scopedRundown = scopedRundown.slice(currentIndex);
}
}

if (hideBackstage) {
scopedRundown = scopedRundown.filter((event) => event.isPublic);
}

return scopedRundown;
}

type UpcomingEvents = {
now: OntimeEvent | null;
next: OntimeEvent | null;
Expand Down

0 comments on commit 1a7bf93

Please sign in to comment.