Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rundown view, rundown header, and presenter view customization #551

Merged
merged 124 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
f9427d0
feat: Playlist/Rundown expectedEnd display in lobby / header
eol-account Jun 3, 2021
55cec52
feat: End time diff
eol-account Jun 4, 2021
f1a8f10
fix: End time diff
eol-account Jun 4, 2021
a6c0bc2
wip: Move rundown timing to lib and add tests
eol-account Jun 9, 2021
eedf521
feat: UI components for timing to next break
eol-account Jun 14, 2021
d6262b1
fix: Rebase fixes
eol-account Jun 15, 2021
2e8d116
Merge branch 'feat/rundown-view-layouts-R36' into feat/expectedEndTime
eol-account Jun 15, 2021
79bd189
feat: Settings for header customisations
eol-account Jun 15, 2021
44328e4
feat: Look ahead to find rundown marked as next break
eol-account Jun 15, 2021
8b537b3
fix: Blank timer labels
eol-account Jun 16, 2021
ffd1257
fix: Check for last break
eol-account Jun 16, 2021
c4d2e10
Merge branch 'feat/expectedEndTime' into feat/top-bar-dashboard
eol-account Jun 21, 2021
1e93b78
wip: Top bar dashboard
eol-account Jun 21, 2021
07d31e0
Merge branch 'feat/rundown-view-layouts-R36' into feat/expectedEndTime
eol-account Jun 21, 2021
cecaead
chore: Produce next break info inside rundownTimingProvider
eol-account Jun 21, 2021
2be25eb
Merge branch 'feat/expectedEndTime' into feat/rundown-header-dashboard
eol-account Jun 21, 2021
f4fd866
feat: Endwords, Playlist start / end timer panels
eol-account Jun 25, 2021
1e9324a
feat: Playlist/Rundown expectedEnd display in lobby / header
eol-account Jun 3, 2021
f8cc7b7
feat: End time diff
eol-account Jun 4, 2021
4b37435
fix: End time diff
eol-account Jun 4, 2021
7570822
wip: Move rundown timing to lib and add tests
eol-account Jun 9, 2021
f1ddbe5
feat: UI components for timing to next break
eol-account Jun 14, 2021
e094c56
fix: Rebase fixes
eol-account Jun 15, 2021
162384e
feat: Skeleton of rundown layout registry
eol-account Apr 19, 2021
9bdfe2f
chore: Move setting for filters to separate component for reuse
eol-account May 10, 2021
72295d1
feat: Describe rundown view and shelf layouts through manifests
eol-account May 12, 2021
5f9261a
feat: Apply rundown header / view layouts to rundown
eol-account May 12, 2021
4ca9592
fix: Post-rebase
eol-account May 12, 2021
437a730
feat: Scope layouts to their settings section
eol-account May 17, 2021
3c9aef2
feat: Select mini shelf layout in rundown view
eol-account May 17, 2021
2b504af
fix: Fixes after rebase
eol-account Jun 14, 2021
4d615f2
feat: Select rundown layout from lobby and use selected layouts as de…
eol-account Jun 15, 2021
8e14b26
fix: Lint errors
eol-account Jun 15, 2021
7b4a178
feat: Settings for header customisations
eol-account Jun 15, 2021
b6b0e87
feat: Look ahead to find rundown marked as next break
eol-account Jun 15, 2021
3374fd3
fix: Blank timer labels
eol-account Jun 16, 2021
f42235e
fix: Check for last break
eol-account Jun 16, 2021
68156cf
fix: Filter supported elements
eol-account Jun 21, 2021
26f72e8
chore: Produce next break info inside rundownTimingProvider
eol-account Jun 21, 2021
2f99240
chore: Rename rundown layout functions to camel case
eol-account Jun 29, 2021
ea9cb26
fix: Translate in getSettingsManifest
eol-account Jun 29, 2021
0d9b956
fix: Don't translate user defined strings
eol-account Jun 29, 2021
c79d69e
chore: Rename RundownCountdown to MarkerCountdownText
eol-account Jun 29, 2021
c65bc3f
chore: Remove references to miniShelf
eol-account Jun 29, 2021
b26d2d6
fix: Issues after rebase
eol-account Jun 29, 2021
8fb7a3d
chore: Remove unneeded member
eol-account Jun 29, 2021
dfcc127
chore: rename endIsBreak and add detail to comments
eol-account Jun 29, 2021
24393e8
fix: Clean up logic for finding next break
eol-account Jun 29, 2021
1b83c81
feat: Move next break props calculation to tracker
eol-account Jun 29, 2021
24ce5ed
feat: Segment count up and down panels
eol-account Jun 30, 2021
a986063
feat: Part count down panel
eol-account Jun 30, 2021
8ce015c
wip: Functionality-complete panels
eol-account Jul 1, 2021
9e716cc
feat: Styling of header components
eol-account Jul 2, 2021
6692a54
chore: Clean up inheritance structure
eol-account Jul 6, 2021
07659bf
fix: Over/under timer with only expected end
eol-account Jul 6, 2021
b9e4a07
fix: Expected end where start is defined
eol-account Jul 6, 2021
69effd6
fix: More explicit relationship between timing props
eol-account Jul 7, 2021
c63a52d
chore: Some lint fixes
eol-account Jul 7, 2021
9a11f18
fix: Rundown timing prop
eol-account Jul 7, 2021
ead54b1
fix: Rundown timing crash
eol-account Jul 8, 2021
305d0d2
fix: Various lint errors
eol-account Jul 8, 2021
8ce6d92
fix: Failing tests
eol-account Jul 8, 2021
1d55846
fix: Playout test snapshots
eol-account Jul 8, 2021
7a35261
fix: Circular import
eol-account Jul 8, 2021
bd762b5
fix: Import
eol-account Jul 9, 2021
050bfd3
Merge remote-tracking branch 'nrkno/release36' into feat/expectedEndTime
eol-account Jul 26, 2021
2656bf6
fix: Lint and failing tests
eol-account Jul 26, 2021
918e72a
fix: Import issues in tests
eol-account Jul 27, 2021
8840e9f
fix: More test snapshots
eol-account Jul 27, 2021
0fd65ff
Merge branch 'feat/expectedEndTime' into feat/rundown-header-dashboard
eol-account Jul 27, 2021
738ef26
feat: Require layers to have active pieces for live line counter
eol-account Jul 8, 2021
b1d3d06
feat: Break marker segment + hide rundown divider
eol-account Jul 9, 2021
e13a14c
feat: Only countdown to segment if certain sourcelayers are present
eol-account Jul 9, 2021
074f07a
fix: Rebase fixes
eol-account Jul 28, 2021
949fe11
feat: Break marker segment + hide rundown divider
eol-account Jul 9, 2021
ad44fd2
feat: add static segment duration option
ianshade Jul 27, 2021
f65cb0c
feat: Dashboard in clock view
eol-account Jul 29, 2021
33bea59
feat: Clock panels
eol-account Jul 30, 2021
f8b5443
chore: rename static- to fixed-
ianshade Aug 2, 2021
79d9fe6
Merge pull request #48 from olzzon/feat/rundown-view-static-segment-d…
Aug 2, 2021
d423eb0
feat: Part name panel, colored box elements
eol-account Aug 2, 2021
8f1093c
fix: Segment name panel next segment behaviour
eol-account Aug 3, 2021
5673f82
Merge branch 'feat/clock-view-customization' into feat/rundown-view-c…
eol-account Aug 3, 2021
2d26694
fix: Studio name panel title
eol-account Aug 3, 2021
bd6b1cf
fix: Better names for the required layer options
eol-account Aug 3, 2021
c0c4720
fix: Consistent label behavior between planned start/end
eol-account Aug 3, 2021
1310c23
Merge remote-tracking branch 'nrkno/release37' into feat/rundown-view…
eol-account Aug 17, 2021
1436cd0
feat: Custom classes for dashboard panels
eol-account Aug 31, 2021
255a71e
fix: Missing custom classes on panels
eol-account Sep 1, 2021
b295104
chore: Lint
eol-account Sep 1, 2021
fda8a54
fix: Show expected end timer
eol-account Sep 6, 2021
b4afbfe
feat: Allow hiding end words label
eol-account Sep 6, 2021
d724be2
fix: Timing displays
eol-account Sep 6, 2021
0716a92
feat: Add colored box dashboard component to header
eol-account Sep 6, 2021
493f1d8
chore: lint
nytamin Sep 16, 2021
817e7cf
chore: move StatusCode to blueprints-integration, so that it can be u…
nytamin Sep 16, 2021
fa55946
chore: refactor: rename and make indepentent: PeripheralDeviceStatus …
nytamin Sep 16, 2021
dac1cdb
feat: Add PackageContainerStatuses, used by Package Manager to report…
nytamin Sep 16, 2021
6f29254
chore: Clean up dashboard element styling
eol-account Sep 22, 2021
72c8847
chore: Remove exports from inner components
eol-account Sep 22, 2021
018fd9a
fix: Translate filtersTitle
eol-account Sep 22, 2021
9fc18bd
chore: Clean up dashboard panel interfaces
eol-account Sep 22, 2021
4eda795
chore: Remove unneeded font-family rule
eol-account Sep 22, 2021
286e45f
chore: Move scriptPreview into client lib
eol-account Sep 22, 2021
cbf2f52
chore: Remove tracked props from coloredBoxPanel
eol-account Sep 22, 2021
752c0f9
chore: Attempt to clean up filter editor
eol-account Sep 22, 2021
56ca119
chore: Attempt to clean up dashboard panel rendering
eol-account Sep 22, 2021
f35d71b
fix: Wrap break in withTiming
eol-account Sep 22, 2021
288d1c0
chore: Use getSourceLayerClassName instead of individual implementations
eol-account Sep 22, 2021
0b08858
fix: Prompter does not update when script is edited (#554)
jstarpl Sep 23, 2021
4ccbf6b
chore: add some info about memoizedIsolatedAutorun
jstarpl Sep 23, 2021
693a78e
chore: package-lock
jstarpl Sep 23, 2021
8b62c27
chore: refactor classes into functional components with react hooks
nytamin Sep 23, 2021
5bbfc3f
chore: refactor to improve css selectors
nytamin Sep 24, 2021
de73fd1
fix: add priority & prevStatusReasons into package workStatuses
nytamin Sep 24, 2021
1051824
chore: use initial parameter
nytamin Sep 24, 2021
45d2c07
chore: refactor packageManager userActions to use Promises
nytamin Sep 24, 2021
7d86479
chore: return void rather than any [publish]
nytamin Sep 24, 2021
b7c3ed5
Merge pull request #577 from nrkno/feat/package-containter-statuses
nytamin Sep 24, 2021
05a9eb2
fix: prevent default on F5 & Control+F5
jstarpl Sep 24, 2021
c725143
fix: PubSub.packageContainerPackageStatuses and PubSub.packageContain…
jstarpl Sep 24, 2021
1555b09
chore: add unit test for PubSub values
nytamin Sep 24, 2021
80b3602
Merge remote-tracking branch 'nrkno/release37' into feat/rundown-view…
eol-account Sep 27, 2021
3fa8c6a
Merge remote-tracking branch 'nrkno/release38' into feat/rundown-view…
eol-account Sep 27, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion meteor/client/lib/ReactMeteorData/ReactMeteorData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export function useTracker<T, K extends undefined | T = undefined>(
* @param {...any[]} args A list of arugments for the subscription. This is used for optimizing the subscription across
* renders so that it isn't torn down and created for every render.
*/
export function useSubscription(sub: PubSub, ...args: any[]) {
export function useSubscription(sub: PubSub, ...args: any[]): boolean {
const [ready, setReady] = useState<boolean>(false)

useEffect(() => {
Expand Down
39 changes: 32 additions & 7 deletions meteor/client/lib/reactiveData/reactiveDataHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ const isolatedAutorunsMem: {
}
} = {}

/**
* Create a reactive computation that will be run independently of the outer one. If the same function (using the same
* name and parameters) will be used again, this computation will only be computed once on invalidation and it's
* result will be memoized and reused on every other call.
*
* The function will be considered "same", if `functionName` and `params` match.
*
* If the `fnc` computation is invalidated, the outer computations will only be invalidated if the value returned from
* `fnc` fails a deep equality check (_.isEqual).
*
* @export
* @template T
* @param {T} fnc The computation function to be memoized and calculated separately from the outer one.
* @param {string} functionName The name of this computation function
* @param {...Parameters<T>} params Params `fnc` depends on from the outer scope. All parameters will be passed through to the function.
* @return {*} {ReturnType<T>}
*/
export function memoizedIsolatedAutorun<T extends (...args: any) => any>(
fnc: T,
functionName: string,
Expand Down Expand Up @@ -105,14 +122,22 @@ export function memoizedIsolatedAutorun<T extends (...args: any) => any>(
return result
}

export function slowDownReactivity<T extends (...args: any) => any>(
fnc: T,
delay: number,
...params: Parameters<T>
): ReturnType<T> {
/**
* Slow down the reactivity of the inner function `fnc` to the outer computation.
*
* This is essentially a `throttle` for reactivity. If the inner `fnc` computation is invalidated, it will wait `delay`
* time to invalidate the outer computation.
*
* @export
* @template T
* @param {T} fnc The wrapped computation
* @param {number} delay The amount of time to wait before invalidating the outer function
* @return {*} {ReturnType<T>}
*/
export function slowDownReactivity<T extends (...args: any) => any>(fnc: T, delay: number): ReturnType<T> {
// if the delay is <= 0, call straight away and register a direct dependency
if (delay <= 0) {
return fnc(...(params as any))
return fnc()
}

// if the delay is > 0, slow down the reactivity
Expand All @@ -125,7 +150,7 @@ export function slowDownReactivity<T extends (...args: any) => any>(
const parentComputation = Tracker.currentComputation
const computation = Tracker.nonreactive(() => {
const computation = Tracker.autorun(() => {
result = fnc(...(params as any))
result = fnc()
})
computation.onInvalidate(() => {
// if the parent hasn't been invalidated and there is no scheduled invalidation
Expand Down
131 changes: 131 additions & 0 deletions meteor/client/lib/rundownLayouts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import _ from 'underscore'
import { PartInstanceId } from '../../lib/collections/PartInstances'
import { PieceInstance, PieceInstances } from '../../lib/collections/PieceInstances'
import { RequiresActiveLayers } from '../../lib/collections/RundownLayouts'
import { RundownPlaylist } from '../../lib/collections/RundownPlaylists'
import { getCurrentTime } from '../../lib/lib'
import { invalidateAt } from './invalidatingTime'

/**
* If the conditions of the filter are met, activePieceInstance will include the first piece instance found that matches the filter, otherwise it will be undefined.
*/
export function getIsFilterActive(
playlist: RundownPlaylist,
panel: RequiresActiveLayers
): { active: boolean; activePieceInstance: PieceInstance | undefined } {
const unfinishedPieces = getUnfinishedPieceInstancesReactive(playlist, true)
let activePieceInstance: PieceInstance | undefined
const activeLayers = unfinishedPieces.map((p) => p.piece.sourceLayerId)
const containsEveryRequiredLayer = panel.requireAllAdditionalSourcelayers
? panel.additionalLayers?.length && panel.additionalLayers.every((s) => activeLayers.includes(s))
: false
const containsRequiredLayer = containsEveryRequiredLayer
? true
: panel.additionalLayers && panel.additionalLayers.length
? panel.additionalLayers.some((s) => activeLayers.includes(s))
: false

if (
(!panel.requireAllAdditionalSourcelayers || containsEveryRequiredLayer) &&
(!panel.additionalLayers?.length || containsRequiredLayer)
) {
activePieceInstance =
panel.requiredLayerIds && panel.requiredLayerIds.length
? _.flatten(Object.values(unfinishedPieces)).find((piece: PieceInstance) => {
return (
(panel.requiredLayerIds || []).indexOf(piece.piece.sourceLayerId) !== -1 &&
piece.partInstanceId === playlist.currentPartInstanceId
)
})
: undefined
}
return {
active:
activePieceInstance !== undefined || (!panel.requiredLayerIds?.length && !panel.additionalLayers?.length),
activePieceInstance,
}
}

export function getUnfinishedPieceInstancesReactive(playlist: RundownPlaylist, includeNonAdLibPieces: boolean) {
let prospectivePieces: PieceInstance[] = []
const now = getCurrentTime()
if (playlist.activationId && playlist.currentPartInstanceId) {
prospectivePieces = PieceInstances.find({
startedPlayback: {
$exists: true,
},
playlistActivationId: playlist.activationId,
$and: [
{
$or: [
{
stoppedPlayback: {
$eq: 0,
},
},
{
stoppedPlayback: {
$exists: false,
},
},
],
},
!includeNonAdLibPieces
? {
$or: [
{
adLibSourceId: {
$exists: true,
},
},
{
'piece.tags': {
$exists: true,
},
},
],
}
: {},
{
$or: [
{
userDuration: {
$exists: false,
},
},
{
'userDuration.end': {
$exists: false,
},
},
],
},
],
}).fetch()

let nearestEnd = Number.POSITIVE_INFINITY
prospectivePieces = prospectivePieces.filter((pieceInstance) => {
const piece = pieceInstance.piece
const end: number | undefined =
pieceInstance.userDuration && typeof pieceInstance.userDuration.end === 'number'
? pieceInstance.userDuration.end
: typeof piece.enable.duration === 'number'
? piece.enable.duration + pieceInstance.startedPlayback!
: undefined

if (end !== undefined) {
if (end > now) {
nearestEnd = nearestEnd > end ? end : nearestEnd
return true
} else {
return false
}
}
return true
})

if (Number.isFinite(nearestEnd)) invalidateAt(nearestEnd)
}

return prospectivePieces
}
8 changes: 8 additions & 0 deletions meteor/client/lib/triggers/TriggersHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,20 @@ export const TriggersHandler: React.FC<IProps> = function TriggersHandler(
ordered: 'modifiersFirst',
preventDefaultPartials: false,
})
localSorensen.bind(['F5', 'Control+F5'], preventDefault, {
global: true,
exclusive: true,
ordered: false,
preventDefaultPartials: false,
})
}
}

return () => {
localSorensen.unbind('Escape', poisonHotkeys)
localSorensen.unbind('Control+KeyF', preventDefault)
localSorensen.unbind('F5', preventDefault)
localSorensen.unbind('Control+F5', preventDefault)
}
}, [initialized]) // run once once Sorensen is initialized

Expand Down
32 changes: 32 additions & 0 deletions meteor/client/lib/ui/scriptPreview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const BREAK_SCRIPT_BREAKPOINT = 620
const SCRIPT_PART_LENGTH = 250

interface ScriptPreview {
startOfScript: string
endOfScript: string
breakScript: boolean
}

export function getScriptPreview(fullScript: string): ScriptPreview {
let startOfScript = fullScript
let cutLength = startOfScript.length
if (startOfScript.length > SCRIPT_PART_LENGTH) {
startOfScript = startOfScript.substring(0, startOfScript.substr(0, SCRIPT_PART_LENGTH).lastIndexOf(' '))
cutLength = startOfScript.length
}
let endOfScript = fullScript
if (endOfScript.length > SCRIPT_PART_LENGTH) {
endOfScript = endOfScript.substring(
endOfScript.indexOf(' ', Math.max(cutLength, endOfScript.length - SCRIPT_PART_LENGTH)),
endOfScript.length
)
}

const breakScript = fullScript.length > BREAK_SCRIPT_BREAKPOINT

return {
startOfScript,
endOfScript,
breakScript,
}
}
2 changes: 2 additions & 0 deletions meteor/client/lib/userAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ function userActionToLabel(userAction: UserAction, t: i18next.TFunction) {
return t('Aborting all Media Workflows')
case UserAction.PACKAGE_MANAGER_RESTART_WORK:
return t('Package Manager: Restart work')
case UserAction.PACKAGE_MANAGER_RESTART_PACKAGE_CONTAINER:
return t('Package Manager: Restart Package Container')
case UserAction.GENERATE_RESTART_TOKEN:
return t('Generating restart token')
case UserAction.RESTART_CORE:
Expand Down
5 changes: 5 additions & 0 deletions meteor/client/styles/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
margin-top: -0.5em;
}
}

.dashboard {
flex: 1 1;
position: unset;
}
}

.super-dark {
Expand Down