mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 14:14:17 +00:00
refactor: extract countdown data to hook
This commit is contained in:
committed by
Carlos Valente
parent
20ee391525
commit
f23adfa45c
@@ -51,6 +51,7 @@ export default function AppRouter() {
|
|||||||
path='countdown'
|
path='countdown'
|
||||||
element={
|
element={
|
||||||
<ViewLoader>
|
<ViewLoader>
|
||||||
|
<ViewNavigationMenu isLockable />
|
||||||
<Countdown />
|
<Countdown />
|
||||||
</ViewLoader>
|
</ViewLoader>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,3 +242,9 @@ export const useTimerSocket = createSelector((state: RuntimeStore) => ({
|
|||||||
aux3: state.auxtimer3.current,
|
aux3: state.auxtimer3.current,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const useCountdownSocket = createSelector((state: RuntimeStore) => ({
|
||||||
|
playback: state.timer.playback,
|
||||||
|
current: state.timer.current,
|
||||||
|
clock: state.clock,
|
||||||
|
}));
|
||||||
|
|||||||
@@ -1,64 +1,52 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { IoAdd } from 'react-icons/io5';
|
import { IoAdd } from 'react-icons/io5';
|
||||||
import {
|
import { EntryId, isOntimeEvent, isPlayableEvent, OntimeEvent, OntimeView } from 'ontime-types';
|
||||||
CustomFields,
|
|
||||||
EntryId,
|
|
||||||
isOntimeEvent,
|
|
||||||
isPlayableEvent,
|
|
||||||
OntimeEvent,
|
|
||||||
OntimeView,
|
|
||||||
ProjectData,
|
|
||||||
Settings,
|
|
||||||
} from 'ontime-types';
|
|
||||||
|
|
||||||
import Button from '../../common/components/buttons/Button';
|
import Button from '../../common/components/buttons/Button';
|
||||||
import Empty from '../../common/components/state/Empty';
|
import Empty from '../../common/components/state/Empty';
|
||||||
|
import EmptyPage from '../../common/components/state/EmptyPage';
|
||||||
import ViewLogo from '../../common/components/view-logo/ViewLogo';
|
import ViewLogo from '../../common/components/view-logo/ViewLogo';
|
||||||
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
|
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
|
import { useClock } from '../../common/hooks/useSocket';
|
||||||
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
||||||
import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
|
|
||||||
import { formatTime, getDefaultFormat } from '../../common/utils/time';
|
import { formatTime, getDefaultFormat } from '../../common/utils/time';
|
||||||
import SuperscriptTime from '../../features/viewers/common/superscript-time/SuperscriptTime';
|
import SuperscriptTime from '../../features/viewers/common/superscript-time/SuperscriptTime';
|
||||||
import { useTranslation } from '../../translation/TranslationProvider';
|
import { useTranslation } from '../../translation/TranslationProvider';
|
||||||
|
import Loader from '../common/loader/Loader';
|
||||||
|
|
||||||
import { getCountdownOptions, useCountdownOptions } from './countdown.options';
|
import { getCountdownOptions, useCountdownOptions } from './countdown.options';
|
||||||
import { getOrderedSubscriptions } from './countdown.utils';
|
import { getOrderedSubscriptions } from './countdown.utils';
|
||||||
import CountdownSelect from './CountdownSelect';
|
import CountdownSelect from './CountdownSelect';
|
||||||
import CountdownSubscriptions from './CountdownSubscriptions';
|
import CountdownSubscriptions from './CountdownSubscriptions';
|
||||||
|
import { CountdownData, useCountdownData } from './useCountdownData';
|
||||||
|
|
||||||
import './Countdown.scss';
|
import './Countdown.scss';
|
||||||
|
|
||||||
interface CountdownProps {
|
export default function CountdownLoader() {
|
||||||
customFields: CustomFields;
|
const { data, status } = useCountdownData();
|
||||||
events: OntimeEvent[];
|
|
||||||
general: ProjectData;
|
|
||||||
time: ViewExtendedTimer;
|
|
||||||
isMirrored: boolean;
|
|
||||||
selectedId: EntryId | null;
|
|
||||||
settings: Settings | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Countdown({
|
|
||||||
customFields,
|
|
||||||
events,
|
|
||||||
general,
|
|
||||||
time,
|
|
||||||
isMirrored,
|
|
||||||
selectedId,
|
|
||||||
settings,
|
|
||||||
}: CountdownProps) {
|
|
||||||
const { getLocalizedString } = useTranslation();
|
|
||||||
const { subscriptions } = useCountdownOptions();
|
|
||||||
const [editMode, setEditMode] = useState(false);
|
|
||||||
|
|
||||||
useWindowTitle('Countdown');
|
useWindowTitle('Countdown');
|
||||||
|
|
||||||
|
if (status === 'pending') {
|
||||||
|
return <Loader />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'error') {
|
||||||
|
return <EmptyPage text='There was an error fetching data, please refresh the page.' />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Countdown {...data} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Countdown({ customFields, events, projectData, isMirrored, settings }: CountdownData) {
|
||||||
|
const { getLocalizedString } = useTranslation();
|
||||||
|
const { subscriptions } = useCountdownOptions();
|
||||||
|
|
||||||
|
const [editMode, setEditMode] = useState(false);
|
||||||
|
|
||||||
// gather rundown data
|
// gather rundown data
|
||||||
const playableEvents = events.filter((event) => isOntimeEvent(event) && isPlayableEvent(event));
|
const playableEvents = events.filter((event) => isOntimeEvent(event) && isPlayableEvent(event));
|
||||||
|
|
||||||
// gather timer data
|
|
||||||
const clock = formatTime(time.clock);
|
|
||||||
|
|
||||||
// gather presentation data
|
// gather presentation data
|
||||||
const hasEvents = playableEvents.length > 0;
|
const hasEvents = playableEvents.length > 0;
|
||||||
|
|
||||||
@@ -73,12 +61,9 @@ export default function Countdown({
|
|||||||
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
|
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
|
||||||
<ViewParamsEditor target={OntimeView.Countdown} viewOptions={countdownOptions} />
|
<ViewParamsEditor target={OntimeView.Countdown} viewOptions={countdownOptions} />
|
||||||
<div className='project-header'>
|
<div className='project-header'>
|
||||||
{general?.logo && <ViewLogo name={general.logo} className='logo' />}
|
{projectData?.logo && <ViewLogo name={projectData.logo} className='logo' />}
|
||||||
<div className='title'>{general.title}</div>
|
<div className='title'>{projectData.title}</div>
|
||||||
<div className='clock-container'>
|
<CountdownClock />
|
||||||
<div className='label'>{getLocalizedString('common.time_now')}</div>
|
|
||||||
<SuperscriptTime time={clock} className='time' />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!hasEvents && <Empty text={getLocalizedString('common.no_data')} className='empty-container' />}
|
{!hasEvents && <Empty text={getLocalizedString('common.no_data')} className='empty-container' />}
|
||||||
@@ -91,9 +76,7 @@ export default function Countdown({
|
|||||||
<CountdownContents
|
<CountdownContents
|
||||||
playableEvents={playableEvents}
|
playableEvents={playableEvents}
|
||||||
subscriptions={subscriptions}
|
subscriptions={subscriptions}
|
||||||
time={time}
|
|
||||||
goToEditMode={() => setEditMode(true)}
|
goToEditMode={() => setEditMode(true)}
|
||||||
selectedId={selectedId}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -102,13 +85,11 @@ export default function Countdown({
|
|||||||
|
|
||||||
interface CountdownContentsProps {
|
interface CountdownContentsProps {
|
||||||
playableEvents: OntimeEvent[];
|
playableEvents: OntimeEvent[];
|
||||||
selectedId: EntryId | null;
|
|
||||||
subscriptions: EntryId[];
|
subscriptions: EntryId[];
|
||||||
time: ViewExtendedTimer;
|
|
||||||
goToEditMode: () => void;
|
goToEditMode: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CountdownContents({ playableEvents, selectedId, subscriptions, time, goToEditMode }: CountdownContentsProps) {
|
function CountdownContents({ playableEvents, subscriptions, goToEditMode }: CountdownContentsProps) {
|
||||||
const { getLocalizedString } = useTranslation();
|
const { getLocalizedString } = useTranslation();
|
||||||
|
|
||||||
if (subscriptions.length === 0) {
|
if (subscriptions.length === 0) {
|
||||||
@@ -135,12 +116,20 @@ function CountdownContents({ playableEvents, selectedId, subscriptions, time, go
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return <CountdownSubscriptions subscribedEvents={subscribedEvents} goToEditMode={goToEditMode} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CountdownClock() {
|
||||||
|
const { getLocalizedString } = useTranslation();
|
||||||
|
const { clock } = useClock();
|
||||||
|
|
||||||
|
// gather timer data
|
||||||
|
const formattedClock = formatTime(clock);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CountdownSubscriptions
|
<div className='clock-container'>
|
||||||
subscribedEvents={subscribedEvents}
|
<div className='label'>{getLocalizedString('common.time_now')}</div>
|
||||||
selectedId={selectedId}
|
<SuperscriptTime time={formattedClock} className='time' />
|
||||||
time={time}
|
</div>
|
||||||
goToEditMode={goToEditMode}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,13 @@ import { EntryId, OntimeEvent } from 'ontime-types';
|
|||||||
import Button from '../../common/components/buttons/Button';
|
import Button from '../../common/components/buttons/Button';
|
||||||
import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivity';
|
import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivity';
|
||||||
import useFollowComponent from '../../common/hooks/useFollowComponent';
|
import useFollowComponent from '../../common/hooks/useFollowComponent';
|
||||||
import { useCurrentDay, useRuntimeOffset } from '../../common/hooks/useSocket';
|
import {
|
||||||
import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
|
useCountdownSocket,
|
||||||
|
useCurrentDay,
|
||||||
|
usePlayback,
|
||||||
|
useRuntimeOffset,
|
||||||
|
useSelectedEventId,
|
||||||
|
} from '../../common/hooks/useSocket';
|
||||||
import { getOffsetState } from '../../common/utils/offset';
|
import { getOffsetState } from '../../common/utils/offset';
|
||||||
import { cx } from '../../common/utils/styleUtils';
|
import { cx } from '../../common/utils/styleUtils';
|
||||||
import { throttle } from '../../common/utils/throttle';
|
import { throttle } from '../../common/utils/throttle';
|
||||||
@@ -22,18 +27,13 @@ import './Countdown.scss';
|
|||||||
|
|
||||||
interface CountdownSubscriptionsProps {
|
interface CountdownSubscriptionsProps {
|
||||||
subscribedEvents: OntimeEvent[];
|
subscribedEvents: OntimeEvent[];
|
||||||
selectedId: EntryId | null;
|
|
||||||
time: ViewExtendedTimer;
|
|
||||||
goToEditMode: () => void;
|
goToEditMode: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CountdownSubscriptions({
|
export default function CountdownSubscriptions({ subscribedEvents, goToEditMode }: CountdownSubscriptionsProps) {
|
||||||
time,
|
|
||||||
subscribedEvents,
|
|
||||||
selectedId,
|
|
||||||
goToEditMode,
|
|
||||||
}: CountdownSubscriptionsProps) {
|
|
||||||
const { secondarySource, showExpected } = useCountdownOptions();
|
const { secondarySource, showExpected } = useCountdownOptions();
|
||||||
|
const { playback } = usePlayback();
|
||||||
|
const { selectedEventId } = useSelectedEventId();
|
||||||
const showFab = useFadeOutOnInactivity(true);
|
const showFab = useFadeOutOnInactivity(true);
|
||||||
|
|
||||||
const timeoutId = useRef<NodeJS.Timeout | null>(null);
|
const timeoutId = useRef<NodeJS.Timeout | null>(null);
|
||||||
@@ -49,16 +49,16 @@ export default function CountdownSubscriptions({
|
|||||||
|
|
||||||
// reset scroll if nothing is selected
|
// reset scroll if nothing is selected
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedId) {
|
if (!selectedEventId) {
|
||||||
if (!lockAutoScroll) {
|
if (!lockAutoScroll) {
|
||||||
scrollRef.current?.scrollTo(0, 0);
|
scrollRef.current?.scrollTo(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [selectedId, lockAutoScroll, scrollRef]);
|
}, [selectedEventId, lockAutoScroll, scrollRef]);
|
||||||
|
|
||||||
// scroll to component if user clicks the Follow button
|
// scroll to component if user clicks the Follow button
|
||||||
const handleOffset = () => {
|
const handleOffset = () => {
|
||||||
if (selectedId) {
|
if (selectedEventId) {
|
||||||
scrollToComponent();
|
scrollToComponent();
|
||||||
}
|
}
|
||||||
setLockAutoScroll(false);
|
setLockAutoScroll(false);
|
||||||
@@ -91,7 +91,7 @@ export default function CountdownSubscriptions({
|
|||||||
<div className='list-container' onWheel={handleScroll} onTouchMove={handleScroll} ref={scrollRef}>
|
<div className='list-container' onWheel={handleScroll} onTouchMove={handleScroll} ref={scrollRef}>
|
||||||
{subscribedEvents.map((event) => {
|
{subscribedEvents.map((event) => {
|
||||||
const secondaryData = getPropertyValue(event, secondarySource);
|
const secondaryData = getPropertyValue(event, secondarySource);
|
||||||
const isLive = getIsLive(event.id, selectedId, time.playback);
|
const isLive = getIsLive(event.id, selectedEventId, playback);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={event.id} ref={isLive ? selectedRef : undefined} className={cx(['sub', isLive && 'sub--live'])}>
|
<div key={event.id} ref={isLive ? selectedRef : undefined} className={cx(['sub', isLive && 'sub--live'])}>
|
||||||
@@ -107,7 +107,7 @@ export default function CountdownSubscriptions({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<SubscriptionStatus key={event.id} event={event} selectedId={selectedId} time={time} />
|
<SubscriptionStatus key={event.id} event={event} selectedEventId={selectedEventId} />
|
||||||
<div className={cx(['sub__title', !event.title && 'subdued'])}>{sanitiseTitle(event.title)}</div>
|
<div className={cx(['sub__title', !event.title && 'subdued'])}>{sanitiseTitle(event.title)}</div>
|
||||||
{secondaryData && <div className='sub__secondary'>{secondaryData}</div>}
|
{secondaryData && <div className='sub__secondary'>{secondaryData}</div>}
|
||||||
</div>
|
</div>
|
||||||
@@ -152,22 +152,24 @@ function ExpectedSchedule(props: ExpectedScheduleProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface SubscriptionStatusProps {
|
interface SubscriptionStatusProps {
|
||||||
time: ViewExtendedTimer;
|
|
||||||
event: OntimeEvent;
|
event: OntimeEvent;
|
||||||
selectedId: EntryId | null;
|
selectedEventId: EntryId | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SubscriptionStatus({ time, event, selectedId }: SubscriptionStatusProps) {
|
function SubscriptionStatus({ event, selectedEventId }: SubscriptionStatusProps) {
|
||||||
const { getLocalizedString } = useTranslation();
|
const { getLocalizedString } = useTranslation();
|
||||||
const { currentDay } = useCurrentDay();
|
const { currentDay } = useCurrentDay();
|
||||||
const { offset } = useRuntimeOffset();
|
const { offset } = useRuntimeOffset();
|
||||||
const { showExpected } = useCountdownOptions();
|
const { showExpected } = useCountdownOptions();
|
||||||
|
const { playback, current, clock } = useCountdownSocket();
|
||||||
|
|
||||||
// TODO: use reporter values as in the event block chip
|
// TODO: use reporter values as in the event block chip
|
||||||
const { status, timer } = getSubscriptionDisplayData(
|
const { status, timer } = getSubscriptionDisplayData(
|
||||||
time,
|
current,
|
||||||
|
playback,
|
||||||
|
clock,
|
||||||
event,
|
event,
|
||||||
selectedId,
|
selectedEventId,
|
||||||
offset,
|
offset,
|
||||||
currentDay,
|
currentDay,
|
||||||
getLocalizedString('common.minutes'),
|
getLocalizedString('common.minutes'),
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { EntryId, OntimeEvent, Playback, TimerType } from 'ontime-types';
|
import { EntryId, MaybeNumber, OntimeEvent, Playback, TimerType } from 'ontime-types';
|
||||||
import { dayInMs } from 'ontime-utils';
|
import { dayInMs } from 'ontime-utils';
|
||||||
|
|
||||||
import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
|
|
||||||
import { getFormattedTimer } from '../../features/viewers/common/viewUtils';
|
import { getFormattedTimer } from '../../features/viewers/common/viewUtils';
|
||||||
import type { TranslationKey } from '../../translation/TranslationProvider';
|
import type { TranslationKey } from '../../translation/TranslationProvider';
|
||||||
|
|
||||||
@@ -46,7 +45,9 @@ export const timerProgress: TimerMessage = {
|
|||||||
* TODO: get timer data granularly
|
* TODO: get timer data granularly
|
||||||
*/
|
*/
|
||||||
export function getSubscriptionDisplayData(
|
export function getSubscriptionDisplayData(
|
||||||
time: ViewExtendedTimer,
|
current: MaybeNumber,
|
||||||
|
playback: Playback,
|
||||||
|
clock: number,
|
||||||
subscribedEvent: OntimeEvent,
|
subscribedEvent: OntimeEvent,
|
||||||
selectedId: EntryId | null,
|
selectedId: EntryId | null,
|
||||||
offset: number,
|
offset: number,
|
||||||
@@ -58,7 +59,7 @@ export function getSubscriptionDisplayData(
|
|||||||
|
|
||||||
if (selectedId === subscribedEvent.id) {
|
if (selectedId === subscribedEvent.id) {
|
||||||
// 1. An event that is loaded but not running is {'due': <countdown | overtime>}
|
// 1. An event that is loaded but not running is {'due': <countdown | overtime>}
|
||||||
if (time.playback === Playback.Armed) {
|
if (playback === Playback.Armed) {
|
||||||
// if we are following the event, but it is not running, we show the scheduled start
|
// if we are following the event, but it is not running, we show the scheduled start
|
||||||
return {
|
return {
|
||||||
status: 'due',
|
status: 'due',
|
||||||
@@ -74,7 +75,7 @@ export function getSubscriptionDisplayData(
|
|||||||
// 2. An event with a time-to-start lower than 0 is {'due': <countdown | scheduledStart>}, show the running timer
|
// 2. An event with a time-to-start lower than 0 is {'due': <countdown | scheduledStart>}, show the running timer
|
||||||
return {
|
return {
|
||||||
status: 'live',
|
status: 'live',
|
||||||
timer: getFormattedTimer(time.current, TimerType.CountDown, minutesString, subscriptionTimerDisplayOptions),
|
timer: getFormattedTimer(current, TimerType.CountDown, minutesString, subscriptionTimerDisplayOptions),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ export function getSubscriptionDisplayData(
|
|||||||
return {
|
return {
|
||||||
status: 'future',
|
status: 'future',
|
||||||
timer: getFormattedTimer(
|
timer: getFormattedTimer(
|
||||||
subscribedEvent.timeStart + dayOffset - time.clock - offsetAndDelay,
|
subscribedEvent.timeStart + dayOffset - clock - offsetAndDelay,
|
||||||
TimerType.CountDown,
|
TimerType.CountDown,
|
||||||
minutesString,
|
minutesString,
|
||||||
subscriptionTimerDisplayOptions,
|
subscriptionTimerDisplayOptions,
|
||||||
@@ -113,11 +114,11 @@ export function getSubscriptionDisplayData(
|
|||||||
|
|
||||||
// 5. if event is in future, we count to the scheduled start
|
// 5. if event is in future, we count to the scheduled start
|
||||||
// TODO: get time until
|
// TODO: get time until
|
||||||
if (time.clock < subscribedEvent.timeStart) {
|
if (clock < subscribedEvent.timeStart) {
|
||||||
return {
|
return {
|
||||||
status: 'future',
|
status: 'future',
|
||||||
timer: getFormattedTimer(
|
timer: getFormattedTimer(
|
||||||
subscribedEvent.timeStart - time.clock - offsetAndDelay,
|
subscribedEvent.timeStart - clock - offsetAndDelay,
|
||||||
TimerType.CountDown,
|
TimerType.CountDown,
|
||||||
minutesString,
|
minutesString,
|
||||||
subscriptionTimerDisplayOptions,
|
subscriptionTimerDisplayOptions,
|
||||||
@@ -127,7 +128,7 @@ export function getSubscriptionDisplayData(
|
|||||||
|
|
||||||
// 6. if event has ended, we show the scheduled end
|
// 6. if event has ended, we show the scheduled end
|
||||||
// TODO: get the time from the reporter
|
// TODO: get the time from the reporter
|
||||||
if (time.clock > subscribedEvent.timeEnd) {
|
if (clock > subscribedEvent.timeEnd) {
|
||||||
return {
|
return {
|
||||||
status: 'done',
|
status: 'done',
|
||||||
timer: getFormattedTimer(
|
timer: getFormattedTimer(
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { CustomFields, OntimeEntry, ProjectData, Settings } from 'ontime-types';
|
||||||
|
|
||||||
|
import useCustomFields from '../../common/hooks-query/useCustomFields';
|
||||||
|
import useProjectData from '../../common/hooks-query/useProjectData';
|
||||||
|
import { useFlatRundown } from '../../common/hooks-query/useRundown';
|
||||||
|
import useSettings from '../../common/hooks-query/useSettings';
|
||||||
|
import { useViewOptionsStore } from '../../common/stores/viewOptions';
|
||||||
|
import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils';
|
||||||
|
|
||||||
|
export interface CountdownData {
|
||||||
|
customFields: CustomFields;
|
||||||
|
events: OntimeEntry[];
|
||||||
|
projectData: ProjectData;
|
||||||
|
isMirrored: boolean;
|
||||||
|
settings: Settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCountdownData(): ViewData<CountdownData> {
|
||||||
|
// persisted app state
|
||||||
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
|
// HTTP API data
|
||||||
|
const { data: rundownData, status: rundownStatus } = useFlatRundown();
|
||||||
|
const { data: projectData, status: projectDataStatus } = useProjectData();
|
||||||
|
const { data: settings, status: settingsStatus } = useSettings();
|
||||||
|
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
customFields,
|
||||||
|
events: rundownData,
|
||||||
|
projectData,
|
||||||
|
isMirrored,
|
||||||
|
settings,
|
||||||
|
},
|
||||||
|
status: aggregateQueryStatus([rundownStatus, projectDataStatus, settingsStatus, customFieldsStatus]),
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user