refactor: memoise paramseditor

This commit is contained in:
Carlos Valente
2025-06-17 21:00:13 +02:00
committed by Carlos Valente
parent 5c86914cda
commit 36062458fe
7 changed files with 27 additions and 14 deletions
@@ -1,4 +1,4 @@
import { FormEvent, useEffect } from 'react'; import { FormEvent, memo, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { import {
Button, Button,
@@ -25,8 +25,9 @@ interface EditFormDrawerProps {
viewOptions: ViewOption[]; viewOptions: ViewOption[];
} }
// TODO: this is a good candidate for memoisation, but needs the paramFields to be stable export default memo(ViewParamsEditor);
export default function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) {
function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) {
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const { data: viewSettings } = useViewSettings(); const { data: viewSettings } = useViewSettings();
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { isOntimeEvent, OntimeEvent, SupportedEntry } from 'ontime-types'; import { isOntimeEvent, OntimeEvent, SupportedEntry } from 'ontime-types';
import { getFirstEventNormal, getLastEventNormal } from 'ontime-utils'; import { getFirstEventNormal, getLastEventNormal } from 'ontime-utils';
@@ -107,6 +107,10 @@ export default function Operator() {
const missingData = !data || !customFields || !projectData; const missingData = !data || !customFields || !projectData;
const isLoading = status === 'pending' || customFieldStatus === 'pending' || projectDataStatus === 'pending'; const isLoading = status === 'pending' || customFieldStatus === 'pending' || projectDataStatus === 'pending';
// gather option data
const defaultFormat = getDefaultFormat(settings?.timeFormat);
const operatorOptions = useMemo(() => getOperatorOptions(customFields, defaultFormat), [customFields, defaultFormat]);
if (missingData || isLoading) { if (missingData || isLoading) {
return <EmptyPage text='Loading...' />; return <EmptyPage text='Loading...' />;
} }
@@ -121,8 +125,6 @@ export default function Operator() {
const main = searchParams.get('main') as keyof TitleFields | null; const main = searchParams.get('main') as keyof TitleFields | null;
const secondary = searchParams.get('secondary'); const secondary = searchParams.get('secondary');
const defaultFormat = getDefaultFormat(settings?.timeFormat);
const operatorOptions = getOperatorOptions(customFields, defaultFormat);
let isPast = Boolean(featureData.selectedEventId); let isPast = Boolean(featureData.selectedEventId);
const hidePast = isStringBoolean(searchParams.get('hidepast')); const hidePast = isStringBoolean(searchParams.get('hidepast'));
@@ -1,3 +1,4 @@
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { ProjectData, Settings } from 'ontime-types'; import { ProjectData, Settings } from 'ontime-types';
@@ -112,7 +113,7 @@ export default function Clock(props: ClockProps) {
const clean = clock.replace('/:/g', ''); const clean = clock.replace('/:/g', '');
const defaultFormat = getDefaultFormat(settings?.timeFormat); const defaultFormat = getDefaultFormat(settings?.timeFormat);
const clockOptions = getClockOptions(defaultFormat); const clockOptions = useMemo(() => getClockOptions(defaultFormat), [defaultFormat]);
return ( return (
<div <div
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { CustomFields, OntimeEvent, ViewSettings } from 'ontime-types'; import { CustomFields, OntimeEvent, ViewSettings } from 'ontime-types';
import { isPlaybackActive, MILLIS_PER_SECOND } from 'ontime-utils'; import { isPlaybackActive, MILLIS_PER_SECOND } from 'ontime-utils';
@@ -95,9 +95,12 @@ export default function LowerThird(props: LowerProps) {
const textDuration = playState ? `${options.transitionIn * 0.5}s` : `${options.transitionOut * 0.5}s`; const textDuration = playState ? `${options.transitionIn * 0.5}s` : `${options.transitionOut * 0.5}s`;
const textDelay = playState ? `${options.delay + options.transitionIn * 0.5}s` : '0s'; const textDelay = playState ? `${options.delay + options.transitionIn * 0.5}s` : '0s';
// gather option data
const lowerThirdOptions = useMemo(() => getLowerThirdOptions(customFields), [customFields]);
return ( return (
<div className='lower-third' style={{ backgroundColor: `#${options.key}` }}> <div className='lower-third' style={{ backgroundColor: `#${options.key}` }}>
<ViewParamsEditor viewOptions={getLowerThirdOptions(customFields)} /> <ViewParamsEditor viewOptions={lowerThirdOptions} />
<div <div
className={`container ${playState ? 'container--in' : 'container--out'}`} className={`container ${playState ? 'container--in' : 'container--out'}`}
style={{ style={{
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import QRCode from 'react-qr-code'; import QRCode from 'react-qr-code';
import { useViewportSize } from '@mantine/hooks'; import { useViewportSize } from '@mantine/hooks';
import { CustomFields, OntimeEvent, ProjectData, Runtime, Settings } from 'ontime-types'; import { CustomFields, OntimeEvent, ProjectData, Runtime, Settings } from 'ontime-types';
@@ -105,7 +105,10 @@ export default function Backstage(props: BackstageProps) {
// gather option data // gather option data
const defaultFormat = getDefaultFormat(settings?.timeFormat); const defaultFormat = getDefaultFormat(settings?.timeFormat);
const backstageOptions = getBackstageOptions(defaultFormat, customFields); const backstageOptions = useMemo(
() => getBackstageOptions(defaultFormat, customFields),
[defaultFormat, customFields],
);
return ( return (
<div className={`backstage ${isMirrored ? 'mirror' : ''}`} data-testid='backstage-view'> <div className={`backstage ${isMirrored ? 'mirror' : ''}`} data-testid='backstage-view'>
@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useMemo, useState } from 'react';
import { IoAdd } from 'react-icons/io5'; import { IoAdd } from 'react-icons/io5';
import { import {
CustomFields, CustomFields,
@@ -63,7 +63,10 @@ export default function Countdown({
// gather option data // gather option data
const defaultFormat = getDefaultFormat(settings?.timeFormat); const defaultFormat = getDefaultFormat(settings?.timeFormat);
const countdownOptions = getCountdownOptions(defaultFormat, customFields, subscriptions); const countdownOptions = useMemo(
() => getCountdownOptions(defaultFormat, customFields, subscriptions),
[defaultFormat, customFields, subscriptions],
);
return ( return (
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'> <div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
@@ -45,7 +45,7 @@ export default function TimelinePage(props: TimelinePageProps) {
// populate options // populate options
const defaultFormat = getDefaultFormat(settings?.timeFormat); const defaultFormat = getDefaultFormat(settings?.timeFormat);
const progressOptions = getTimelineOptions(defaultFormat); const progressOptions = useMemo(() => getTimelineOptions(defaultFormat), [defaultFormat]);
const titleNow = now?.title ?? '-'; const titleNow = now?.title ?? '-';
const dueText = getLocalizedString('timeline.due').toUpperCase(); const dueText = getLocalizedString('timeline.due').toUpperCase();