From 6526b32d4c89e555b35cd1b7a6a97d5e67e5f5cd Mon Sep 17 00:00:00 2001 From: Matteo Gheza Date: Sun, 17 Dec 2023 20:59:05 +0100 Subject: [PATCH 01/10] Add italian client translation (#655) * Add Italian client translation --- .../src/translation/TranslationProvider.tsx | 2 ++ apps/client/src/translation/languages/it.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 apps/client/src/translation/languages/it.ts diff --git a/apps/client/src/translation/TranslationProvider.tsx b/apps/client/src/translation/TranslationProvider.tsx index 8f8bb580e..610cbb2c4 100644 --- a/apps/client/src/translation/TranslationProvider.tsx +++ b/apps/client/src/translation/TranslationProvider.tsx @@ -6,6 +6,7 @@ import { langDe } from './languages/de'; import { langEn } from './languages/en'; import { langEs } from './languages/es'; import { langFr } from './languages/fr'; +import { langIt } from './languages/it'; import { langNo } from './languages/no'; import { langPt } from './languages/pt'; import { langSv } from './languages/sv'; @@ -14,6 +15,7 @@ const translationsList = { en: langEn, es: langEs, fr: langFr, + it: langIt, de: langDe, no: langNo, pt: langPt, diff --git a/apps/client/src/translation/languages/it.ts b/apps/client/src/translation/languages/it.ts new file mode 100644 index 000000000..263080ea8 --- /dev/null +++ b/apps/client/src/translation/languages/it.ts @@ -0,0 +1,19 @@ +import { TranslationObject } from './en'; + +export const langIt: TranslationObject = { + 'common.end_time': 'Ora di Fine', + 'common.expected_finish': 'Fine Prevista', + 'common.now': 'Adesso', + 'common.next': 'Prossimo', + 'common.public_message': 'Messaggio pubblico', + 'common.start_time': 'Ora di Inizio', + 'common.stage_timer': 'Orologio Palco', + 'common.started_at': 'Iniziato Alle', + 'common.time_now': 'Ora attuale', + 'countdown.ended': 'Evento finito alle', + 'countdown.running': 'Evento in corso', + 'countdown.select_event': 'Seleziona un evento da seguire', + 'countdown.to_start': 'Tempo alla partenza', + 'countdown.waiting': 'In attesa dell\'inizio dell\'evento', + 'countdown.overtime': 'in ritardo', +}; From 7d33019f532029f096b921c7184bb9d0d70f13a1 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:07:30 +0100 Subject: [PATCH 02/10] refactor: prevent accidental edit in operator view (#659) * refactor: prevent accidental edit in operator view --- .../src/common/components/view-params-editor/constants.ts | 7 +++++++ apps/client/src/features/operator/Operator.tsx | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/client/src/common/components/view-params-editor/constants.ts b/apps/client/src/common/components/view-params-editor/constants.ts index 64443ad67..ec1805e75 100644 --- a/apps/client/src/common/components/view-params-editor/constants.ts +++ b/apps/client/src/common/components/view-params-editor/constants.ts @@ -380,5 +380,12 @@ export const getOperatorOptions = (userFields: UserFields, timeFormat: TimeForma user9: userFields.user9 || 'user9', }, }, + { + id: 'shouldEdit', + title: 'Edit user field', + description: 'Allows editing an events user field by long pressing on it. Needs a selected highlighted field', + type: 'boolean', + defaultValue: false, + }, ]; }; diff --git a/apps/client/src/features/operator/Operator.tsx b/apps/client/src/features/operator/Operator.tsx index c00b2d6db..c5ac43ace 100644 --- a/apps/client/src/features/operator/Operator.tsx +++ b/apps/client/src/features/operator/Operator.tsx @@ -123,7 +123,10 @@ export default function Operator() { } // get fields which the user subscribed to + const shouldEdit = searchParams.get('shouldEdit'); const subscribe = searchParams.get('subscribe') as keyof UserFields | null; + const canEdit = shouldEdit && subscribe; + const main = searchParams.get('main') as keyof TitleFields | null; const secondary = searchParams.get('secondary') as keyof TitleFields | null; const subscribedAlias = subscribe ? userFields[subscribe] : ''; @@ -152,7 +155,7 @@ export default function Operator() { lastId={lastEvent?.id} /> - {subscribe && ( + {canEdit && (
Press and hold to edit user field
@@ -193,7 +196,7 @@ export default function Operator() { showSeconds={showSeconds} isPast={isPast} selectedRef={isSelected ? selectedRef : undefined} - onLongPress={subscribe ? handleEdit : () => undefined} + onLongPress={canEdit ? handleEdit : () => undefined} /> ); } From 3173fb57fc0eee62bc6d163221ec4c2fa004f471 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:07:48 +0100 Subject: [PATCH 03/10] chore: add italian to languages (#656) --- apps/client/src/features/modals/settings-modal/AppSettings.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/client/src/features/modals/settings-modal/AppSettings.tsx b/apps/client/src/features/modals/settings-modal/AppSettings.tsx index 2a697cd8c..6c774bf34 100644 --- a/apps/client/src/features/modals/settings-modal/AppSettings.tsx +++ b/apps/client/src/features/modals/settings-modal/AppSettings.tsx @@ -119,6 +119,7 @@ export default function AppSettingsModal() { + From 33575c551ae081cab27eee2d7aeeacb4410430fe Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:03:25 +0100 Subject: [PATCH 04/10] refactor: improve typing on transform (#626) * refactor: improve typing on transform * chore: use placeholder for data errors --- apps/client/src/common/hooks-query/useOscSettings.ts | 11 +++++------ .../modals/integration-modal/osc/OscSettings.tsx | 3 --- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/apps/client/src/common/hooks-query/useOscSettings.ts b/apps/client/src/common/hooks-query/useOscSettings.ts index 09e84f0da..703a64edf 100644 --- a/apps/client/src/common/hooks-query/useOscSettings.ts +++ b/apps/client/src/common/hooks-query/useOscSettings.ts @@ -1,7 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -//@ts-nocheck -- working on it import { useMutation, useQuery } from '@tanstack/react-query'; -import { OSCSettings } from 'ontime-types'; import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { OSC_SETTINGS } from '../api/apiConstants'; @@ -13,7 +10,10 @@ import { ontimeQueryClient } from '../queryClient'; export default function useOscSettings() { const { data, status, isFetching, isError, refetch } = useQuery({ queryKey: OSC_SETTINGS, - queryFn: getOSC, + queryFn: async () => { + const oscData = await getOSC(); + return { ...oscData, portIn: String(oscData.portIn), portOut: String(oscData.portOut) }; + }, placeholderData: oscPlaceholderSettings, retry: 5, retryDelay: (attempt: number) => attempt * 2500, @@ -21,8 +21,7 @@ export default function useOscSettings() { networkMode: 'always', }); - // we need to jump through some hoops because of the type op port - return { data: data! as unknown as OSCSettings, status, isFetching, isError, refetch }; + return { data: data ?? oscPlaceholderSettings, status, isFetching, isError, refetch }; } export function useOscSettingsMutation() { diff --git a/apps/client/src/features/modals/integration-modal/osc/OscSettings.tsx b/apps/client/src/features/modals/integration-modal/osc/OscSettings.tsx index f454a3e77..220b77b31 100644 --- a/apps/client/src/features/modals/integration-modal/osc/OscSettings.tsx +++ b/apps/client/src/features/modals/integration-modal/osc/OscSettings.tsx @@ -1,5 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -//@ts-nocheck -- working on it import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; import { FormControl, Input, Switch } from '@chakra-ui/react'; @@ -59,7 +57,6 @@ export default function OscSettings() { }; const resetForm = () => { - // @ts-expect-error -- we know the types dont match reset(data); }; From 8afffb987051b738e667dd7e154e6fe399de1e1a Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Fri, 22 Dec 2023 21:05:23 +0100 Subject: [PATCH 05/10] style: fix missing overrides (#666) * style: fix missing overrides * style: fix recover idle colour --- apps/client/src/features/viewers/studio/StudioClock.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/client/src/features/viewers/studio/StudioClock.scss b/apps/client/src/features/viewers/studio/StudioClock.scss index cfb997e49..23bcdc55c 100644 --- a/apps/client/src/features/viewers/studio/StudioClock.scss +++ b/apps/client/src/features/viewers/studio/StudioClock.scss @@ -13,7 +13,7 @@ $half-hours: min(1.5vh, 10px); $size-min: min(2.5vh, 18px); $half-min: min(1.25vh, 9px); $red-active: #c53030; -$red-idle: #000000; +$red-idle: #300000; $cyan-active: #0ff; $cyan-idle: #0aa; @@ -109,7 +109,8 @@ $cyan-idle: #0aa; line-height: 1em; &--overtime { - color: darken($red-active, 10%); + color: var(--studio-active, $red-active); + filter: brightness(0.9); } } @@ -133,7 +134,7 @@ $cyan-idle: #0aa; color: var(--studio-active, $red-active); &--idle { - color: var(--studio-idle, $red-active); + color: var(--studio-idle, $red-idle); } } From 09f2874784e1e5e5bbbacce445a08e16e95ecae2 Mon Sep 17 00:00:00 2001 From: Fabian Posenau <19673098+kellhogs@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:18:05 +0100 Subject: [PATCH 06/10] Fix Visual bug on rundown (#678) * fix: bug with draw order on past rundown items --------- Co-authored-by: Fabian Posenau --- .../rundown/event-block/EventBlock.module.scss | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/client/src/features/rundown/event-block/EventBlock.module.scss b/apps/client/src/features/rundown/event-block/EventBlock.module.scss index 7365f74fd..50686409c 100644 --- a/apps/client/src/features/rundown/event-block/EventBlock.module.scss +++ b/apps/client/src/features/rundown/event-block/EventBlock.module.scss @@ -53,8 +53,18 @@ $skip-opacity: 0.1; outline: 1px solid $block-cursor-color; } + /* we stop the eventActions from having opacity to fix issue with dropdown drawing order */ &.past:not(.skip) { - opacity: 0.6; + .delayNote, + .statusElements, + .eventTitle, + .eventNote, + .eventTimers, + .eventStatus, + .playbackActions, + .binder { + opacity: 0.4; + } } &.skip { From f3e2944c558e2a7d90be534b0984fc7f4388faae Mon Sep 17 00:00:00 2001 From: Fabian Posenau <19673098+kellhogs@users.noreply.github.com> Date: Fri, 29 Dec 2023 22:25:41 +0100 Subject: [PATCH 07/10] fix docker compose ontime version (#680) Co-authored-by: Fabian Posenau --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9cd538113..f77e741d6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: ontime: container_name: ontime - image: getontime/ontime:beta_v2 + image: getontime/ontime:latest ports: - "4001:4001/tcp" - "8888:8888/udp" From 40bede200cf7011ea3c5d0fb053e76377c276722 Mon Sep 17 00:00:00 2001 From: Fabian Posenau <19673098+kellhogs@users.noreply.github.com> Date: Sat, 30 Dec 2023 10:04:42 +0100 Subject: [PATCH 08/10] nightly builds hopefully (#681) Co-authored-by: Fabian Posenau --- .github/workflows/build_docker_v2.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_docker_v2.yml b/.github/workflows/build_docker_v2.yml index 838992a66..14628d18a 100644 --- a/.github/workflows/build_docker_v2.yml +++ b/.github/workflows/build_docker_v2.yml @@ -44,7 +44,8 @@ jobs: - name: Docker Setup Buildx uses: docker/setup-buildx-action@v2.5.0 - - name: Build and push Docker images + - name: Build and push stable release + if: github.event.release.prerelease == false uses: docker/build-push-action@v4.0.0 with: context: . @@ -54,3 +55,14 @@ jobs: push: true tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:latest + - name: Build and push pre-release + if: github.event.release.prerelease == true + uses: docker/build-push-action@v4.0.0 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 + # Push is a shorthand for --output=type=registry + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:nightly + From 1a8b35a5ea1731f7fe4c7bfa04e6f60bac719606 Mon Sep 17 00:00:00 2001 From: Alex Christoffer Rasmussen Date: Fri, 5 Jan 2024 21:04:16 +0100 Subject: [PATCH 09/10] feat: show overlap (#633) * feat: show spacing or overlap --- .../components/input/time-input/TimeInput.tsx | 34 ++++---------- apps/client/src/common/utils/timesManager.ts | 43 ----------------- .../composite/EventEditorTimes.tsx | 16 +------ apps/client/src/features/rundown/Rundown.tsx | 3 ++ .../src/features/rundown/RundownEntry.tsx | 19 ++++++-- .../event-block/EventBlock.module.scss | 47 +++++++++++++++---- .../rundown/event-block/EventBlock.tsx | 3 ++ .../rundown/event-block/EventBlockInner.tsx | 45 +++++++++++++++++- .../composite/EventBlockTimers.tsx | 26 +--------- 9 files changed, 115 insertions(+), 121 deletions(-) diff --git a/apps/client/src/common/components/input/time-input/TimeInput.tsx b/apps/client/src/common/components/input/time-input/TimeInput.tsx index d584b8f02..84f1575b0 100644 --- a/apps/client/src/common/components/input/time-input/TimeInput.tsx +++ b/apps/client/src/common/components/input/time-input/TimeInput.tsx @@ -17,9 +17,8 @@ interface TimeInputProps { time?: number; delay?: number; placeholder: string; - validationHandler: (entry: TimeEntryField, val: number) => boolean; previousEnd?: number; - warning?: string; + tooltip?: string; } function ButtonInitial(name: TimeEntryField) { @@ -29,25 +28,15 @@ function ButtonInitial(name: TimeEntryField) { return ''; } -function ButtonTooltip(name: TimeEntryField, warning?: string) { - if (name === 'timeStart') return `Start${warning ? `: ${warning}` : ''}`; - if (name === 'timeEnd') return `End${warning ? `: ${warning}` : ''}`; - if (name === 'durationOverride') return `Duration${warning ? `: ${warning}` : ''}`; +function ButtonTooltip(name: TimeEntryField, tooltip?: string) { + if (name === 'timeStart') return `Start${tooltip ? `: ${tooltip}` : ''}`; + if (name === 'timeEnd') return `End${tooltip ? `: ${tooltip}` : ''}`; + if (name === 'durationOverride') return `Duration${tooltip ? `: ${tooltip}` : ''}`; return ''; } export default function TimeInput(props: TimeInputProps) { - const { - id, - name, - submitHandler, - time = 0, - delay = 0, - placeholder, - validationHandler, - previousEnd = 0, - warning, - } = props; + const { id, name, submitHandler, time = 0, delay = 0, placeholder, previousEnd = 0 } = props; const { emitError } = useEmitLog(); const inputRef = useRef(null); const [value, setValue] = useState(''); @@ -103,15 +92,12 @@ export default function TimeInput(props: TimeInputProps) { // check if time is different from before if (newValMillis === time) return false; - // validate with parent - if (!validationHandler(name, newValMillis)) return false; - // update entry submitHandler(name, newValMillis); return true; }, - [name, previousEnd, submitHandler, time, validationHandler], + [name, previousEnd, submitHandler, time], ); /** @@ -171,11 +157,11 @@ export default function TimeInput(props: TimeInputProps) { const isDelayed = delay !== 0; const inputClasses = cx([style.timeInput, isDelayed ? style.delayed : null]); - const buttonClasses = cx([style.inputButton, isDelayed ? style.delayed : null, warning ? style.warn : null]); + const buttonClasses = cx([style.inputButton, isDelayed ? style.delayed : null]); const TooltipLabel = useMemo(() => { - return ButtonTooltip(name, warning); - }, [name, warning]); + return ButtonTooltip(name, ''); + }, [name]); const ButtonText = useMemo(() => { return ButtonInitial(name); diff --git a/apps/client/src/common/utils/timesManager.ts b/apps/client/src/common/utils/timesManager.ts index 4c17af915..6cb51b5ee 100644 --- a/apps/client/src/common/utils/timesManager.ts +++ b/apps/client/src/common/utils/timesManager.ts @@ -1,44 +1 @@ export type TimeEntryField = 'timeStart' | 'timeEnd' | 'durationOverride'; - -/** - * @description Checks which field the value relates to - */ -export const handleTimeEntry = ( - field: TimeEntryField, - val: number, - timeStart: number, - timeEnd: number, -): { start: number; end: number; durationOverride: boolean } => { - let start = timeStart; - let end = timeEnd; - let durationOverride = false; - - if (field === 'timeStart') { - start = val; - } else if (field === 'timeEnd') { - end = val; - } else { - durationOverride = field === 'durationOverride'; - } - return { start, end, durationOverride }; -}; - -/** - * @description Validates time entry - */ -export const validateEntry = ( - field: TimeEntryField, - value: number, - timeStart: number, - timeEnd: number, -): { value: boolean; warnings: { start?: string; end?: string; duration?: string } } => { - const validate = { value: true, warnings: { start: '', end: '', duration: '' } }; - - const { start, end } = handleTimeEntry(field, value, timeStart, timeEnd); - - if (end < start) { - validate.warnings.start = 'Start time later than end time'; - } - - return validate; -}; diff --git a/apps/client/src/features/event-editor/composite/EventEditorTimes.tsx b/apps/client/src/features/event-editor/composite/EventEditorTimes.tsx index b3e634f00..fdb612e94 100644 --- a/apps/client/src/features/event-editor/composite/EventEditorTimes.tsx +++ b/apps/client/src/features/event-editor/composite/EventEditorTimes.tsx @@ -1,4 +1,4 @@ -import { memo, useState } from 'react'; +import { memo } from 'react'; import { Select, Switch } from '@chakra-ui/react'; import { EndAction, OntimeEvent, TimerType } from 'ontime-types'; import { calculateDuration, millisToString } from 'ontime-utils'; @@ -7,7 +7,6 @@ import TimeInput from '../../../common/components/input/time-input/TimeInput'; import { useEventAction } from '../../../common/hooks/useEventAction'; import { millisToDelayString } from '../../../common/utils/dateConfig'; import { cx } from '../../../common/utils/styleUtils'; -import { TimeEntryField, validateEntry } from '../../../common/utils/timesManager'; import style from '../EventEditor.module.scss'; @@ -29,13 +28,6 @@ const EventEditorTimes = (props: EventEditorTimesProps) => { const { eventId, timeStart, timeEnd, duration, delay, isPublic, endAction, timerType } = props; const { updateEvent } = useEventAction(); - const [warning, setWarnings] = useState({ start: '', end: '', duration: '' }); - - const timerValidationHandler = (entry: TimeEntryField, val: number) => { - const valid = validateEntry(entry, val, timeStart, timeEnd); - setWarnings((prev) => ({ ...prev, ...valid.warnings })); - return valid.value; - }; const handleSubmit = (field: TimeActions, value: number | string | boolean) => { const newEventData: Partial = { id: eventId }; @@ -87,11 +79,9 @@ const EventEditorTimes = (props: EventEditorTimesProps) => { id='timeStart' name='timeStart' submitHandler={handleSubmit} - validationHandler={timerValidationHandler} time={timeStart} delay={delay} placeholder='Start' - warning={warning.start} />