From 82185201750d2717a6c7dcd0c05e89f382fc780b Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Wed, 3 Apr 2024 01:18:38 +0200 Subject: [PATCH] Allow delays and durations to be set on groups Signed-off-by: Axel Boberg --- .../app/components/RundownGroupItem/index.jsx | 2 + .../app/components/RundownItem/index.jsx | 46 ++-------------- .../components/RundownItemProgress/index.jsx | 54 +++++++++++++++++++ .../components/RundownItemProgress/style.css | 29 ++++++++++ plugins/types/package.json | 28 +++++----- 5 files changed, 102 insertions(+), 57 deletions(-) create mode 100644 plugins/rundown/app/components/RundownItemProgress/index.jsx create mode 100644 plugins/rundown/app/components/RundownItemProgress/style.css diff --git a/plugins/rundown/app/components/RundownGroupItem/index.jsx b/plugins/rundown/app/components/RundownGroupItem/index.jsx index 23d01d8..c721385 100644 --- a/plugins/rundown/app/components/RundownGroupItem/index.jsx +++ b/plugins/rundown/app/components/RundownGroupItem/index.jsx @@ -5,6 +5,7 @@ import './style.css' import { SharedContext } from '../../sharedContext' +import { RundownItemProgress } from '../RundownItemProgress' import { RundownList } from '../RundownList' import { Icon } from '../Icon' @@ -127,6 +128,7 @@ export function RundownGroupItem ({ index, item }) {
{item?.data?.notes}
+
{ - if (item?.state !== 'playing' && item?.state !== 'scheduled') { - setProgress(0) - return - } - - let shouldLoop = true - - function loop () { - if (!shouldLoop) { - return - } - - let progress = 0 - - switch (item?.state) { - case 'playing': - progress = (Date.now() - item?.didStartPlayingAt) / item?.data?.duration - break - case 'scheduled': - progress = (item?.willStartPlayingAt - Date.now()) / (item?.willStartPlayingAt - item?.wasScheduledAt) - break - } - - if (Number.isNaN(progress) || (progress >= 1 && item?.state === 'playing')) { - setProgress(0) - return - } - - setProgress(Math.max(Math.min(progress, 1), 0)) - - window.requestAnimationFrame(loop) - } - loop() - - return () => { shouldLoop = false } - }, [item?.state, item?.didStartPlayingAt, item?.willStartPlayingAt]) - return (
@@ -188,10 +151,7 @@ export function RundownItem ({ index, item }) { }
- { - ['playing', 'scheduled'].includes(item?.state) && -
- } +
) } diff --git a/plugins/rundown/app/components/RundownItemProgress/index.jsx b/plugins/rundown/app/components/RundownItemProgress/index.jsx new file mode 100644 index 0000000..d57f7b1 --- /dev/null +++ b/plugins/rundown/app/components/RundownItemProgress/index.jsx @@ -0,0 +1,54 @@ +import React from 'react' + +import './style.css' + +export function RundownItemProgress ({ item }) { + const [progress, setProgress] = React.useState(0) + + React.useEffect(() => { + if (item?.state !== 'playing' && item?.state !== 'scheduled') { + setProgress(0) + return + } + + let shouldLoop = true + + function loop () { + if (!shouldLoop) { + return + } + + let progress = 0 + + switch (item?.state) { + case 'playing': + progress = (Date.now() - item?.didStartPlayingAt) / item?.data?.duration + break + case 'scheduled': + progress = (item?.willStartPlayingAt - Date.now()) / (item?.willStartPlayingAt - item?.wasScheduledAt) + break + } + + if (Number.isNaN(progress) || (progress >= 1 && item?.state === 'playing')) { + setProgress(0) + return + } + + setProgress(Math.max(Math.min(progress, 1), 0)) + + window.requestAnimationFrame(loop) + } + loop() + + return () => { shouldLoop = false } + }, [item?.state, item?.didStartPlayingAt, item?.willStartPlayingAt]) + + return ( +
+ { + ['playing', 'scheduled'].includes(item?.state) && +
+ } +
+ ) +} diff --git a/plugins/rundown/app/components/RundownItemProgress/style.css b/plugins/rundown/app/components/RundownItemProgress/style.css new file mode 100644 index 0000000..12e044f --- /dev/null +++ b/plugins/rundown/app/components/RundownItemProgress/style.css @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 Sveriges Television AB + * + * SPDX-License-Identifier: MIT + */ + +.RundownItemProgress { + position: absolute; + width: 100%; + height: 100%; + + left: 0; + top: 0; +} + +.RundownItemProgress-progress { + position: absolute; + width: 100%; + height: 100%; + + bottom: 0; + right: 0; + left: 0; + + transform-origin: left; + + opacity: 0.3; + z-index: -1; +} \ No newline at end of file diff --git a/plugins/types/package.json b/plugins/types/package.json index f48ccea..532e799 100644 --- a/plugins/types/package.json +++ b/plugins/types/package.json @@ -47,20 +47,6 @@ } } }, - { - "id": "bridge.types.group", - "name": "Group", - "inherits": "bridge.types.playable", - "properties": { - "playMode": { - "name": "Play mode", - "type": "enum", - "default": 0, - "enum": ["Trigger all children at once"], - "ui.group": "Timing" - } - } - }, { "id": "bridge.types.delayable", "inherits": "bridge.types.playable", @@ -93,6 +79,20 @@ } } }, + { + "id": "bridge.types.group", + "name": "Group", + "inherits": "bridge.types.media", + "properties": { + "playMode": { + "name": "Play mode", + "type": "enum", + "default": 0, + "enum": ["Trigger all children at once"], + "ui.group": "Timing" + } + } + }, { "id": "bridge.types.divider", "name": "Divider",