Skip to content

Commit

Permalink
feat: add 'clear quickloop' option to top context menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 3, 2024
1 parent 680c3e0 commit 1939c61
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 14 deletions.
20 changes: 20 additions & 0 deletions meteor/server/api/userActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,26 @@ class ServerUserActionAPI
)
}

async clearQuickLoop(
userEvent: string,
eventTime: number,
playlistId: RundownPlaylistId
): Promise<ClientAPI.ClientResponse<void>> {
return ServerClientAPI.runUserActionInLogForPlaylistOnWorker(
this,
userEvent,
eventTime,
playlistId,
() => {
check(playlistId, String)
},
StudioJobs.ClearQuickLoopMarkers,
{
playlistId,
}
)
}

async executeUserChangeOperation(
userEvent: string,
eventTime: Time,
Expand Down
7 changes: 7 additions & 0 deletions packages/corelib/src/worker/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ export enum StudioJobs {
*/
SetQuickLoopMarker = 'setQuickLoopMarker',

/**
* Clear all QuickLoop markers
*/
ClearQuickLoopMarkers = 'clearQuickLoopMarkers',

/**
* Switch the route of the studio
* for use in ad.lib actions and other triggers
Expand Down Expand Up @@ -350,6 +355,7 @@ export interface SetQuickLoopMarkerProps extends RundownPlayoutPropsBase {
type: 'start' | 'end'
marker: QuickLoopMarker | null
}
export type ClearQuickLoopMarkersProps = RundownPlayoutPropsBase

export interface SwitchRouteSetProps {
routeSetId: string
Expand Down Expand Up @@ -409,6 +415,7 @@ export type StudioJobFunc = {
[StudioJobs.ActivateAdlibTesting]: (data: ActivateAdlibTestingProps) => void

[StudioJobs.SetQuickLoopMarker]: (data: SetQuickLoopMarkerProps) => void
[StudioJobs.ClearQuickLoopMarkers]: (data: ClearQuickLoopMarkersProps) => void

[StudioJobs.SwitchRouteSet]: (data: SwitchRouteSetProps) => void
}
Expand Down
61 changes: 48 additions & 13 deletions packages/job-worker/src/playout/quickLoopMarkers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { UserError, UserErrorMessage } from '@sofie-automation/corelib/dist/error'
import { SetQuickLoopMarkerProps } from '@sofie-automation/corelib/dist/worker/studio'
import { ClearQuickLoopMarkersProps, SetQuickLoopMarkerProps } from '@sofie-automation/corelib/dist/worker/studio'
import { JobContext } from '../jobs'
import { runJobWithPlayoutModel } from './lock'
import { updateTimeline } from './timeline/generate'
import { selectNextPart } from './selectNextPart'
import { setNextPart } from './setNext'
import { PlayoutModel } from './model/PlayoutModel'

export async function handleSetQuickLoopMarker(context: JobContext, data: SetQuickLoopMarkerProps): Promise<void> {
return runJobWithPlayoutModel(
Expand All @@ -17,24 +18,58 @@ export async function handleSetQuickLoopMarker(context: JobContext, data: SetQui
async (playoutModel) => {
const playlist = playoutModel.playlist
if (!playlist.activationId) throw new Error(`Playlist has no activationId!`)

const wasQuickLoopRunning = playoutModel.playlist.quickLoop?.running

playoutModel.setQuickLoopMarker(data.type, data.marker)

if (wasQuickLoopRunning) {
const nextPart = selectNextPart(
context,
playoutModel.playlist,
playoutModel.currentPartInstance?.partInstance ?? null,
playoutModel.nextPartInstance?.partInstance ?? null,
playoutModel.getAllOrderedSegments(),
playoutModel.getAllOrderedParts(),
{ ignoreUnplayable: true, ignoreQuickLoop: false }
)
if (nextPart?.part._id !== playoutModel.nextPartInstance?.partInstance.part._id) {
await setNextPart(context, playoutModel, nextPart, false)
}
await updateNextedPartAfterQuickLoopMarkerChange(context, playoutModel)
}
await updateTimeline(context, playoutModel)
}
)
}

export async function handleClearQuickLoopMarkers(
context: JobContext,
data: ClearQuickLoopMarkersProps
): Promise<void> {
return runJobWithPlayoutModel(
context,
data,
async (playoutModel) => {
const playlist = playoutModel.playlist
if (!playlist.activationId) throw UserError.create(UserErrorMessage.InactiveRundown)
},
async (playoutModel) => {
const playlist = playoutModel.playlist
if (!playlist.activationId) throw new Error(`Playlist has no activationId!`)

const wasQuickLoopRunning = playoutModel.playlist.quickLoop?.running

playoutModel.setQuickLoopMarker('start', null)
playoutModel.setQuickLoopMarker('end', null)

if (wasQuickLoopRunning) {
await updateNextedPartAfterQuickLoopMarkerChange(context, playoutModel)
}
await updateTimeline(context, playoutModel)
}
)
}

async function updateNextedPartAfterQuickLoopMarkerChange(context: JobContext, playoutModel: PlayoutModel) {
const nextPart = selectNextPart(
context,
playoutModel.playlist,
playoutModel.currentPartInstance?.partInstance ?? null,
playoutModel.nextPartInstance?.partInstance ?? null,
playoutModel.getAllOrderedSegments(),
playoutModel.getAllOrderedParts(),
{ ignoreUnplayable: true, ignoreQuickLoop: false }
)
if (nextPart?.part._id !== playoutModel.nextPartInstance?.partInstance.part._id) {
await setNextPart(context, playoutModel, nextPart, false)
}
}
3 changes: 2 additions & 1 deletion packages/job-worker/src/workers/studio/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
import { handleTimelineTriggerTime, handleOnPlayoutPlaybackChanged } from '../../playout/timings'
import { handleExecuteAdlibAction } from '../../playout/adlibAction'
import { handleTakeNextPart } from '../../playout/take'
import { handleSetQuickLoopMarker } from '../../playout/quickLoopMarkers'
import { handleClearQuickLoopMarkers, handleSetQuickLoopMarker } from '../../playout/quickLoopMarkers'
import { handleActivateAdlibTesting } from '../../playout/adlibTesting'
import { handleExecuteBucketAdLibOrAction } from '../../playout/bucketAdlibJobs'
import { handleSwitchRouteSet } from '../../studio/routeSet'
Expand Down Expand Up @@ -107,6 +107,7 @@ export const studioJobHandlers: StudioJobHandlers = {
[StudioJobs.ActivateAdlibTesting]: handleActivateAdlibTesting,

[StudioJobs.SetQuickLoopMarker]: handleSetQuickLoopMarker,
[StudioJobs.ClearQuickLoopMarkers]: handleClearQuickLoopMarkers,

[StudioJobs.SwitchRouteSet]: handleSwitchRouteSet,
}
6 changes: 6 additions & 0 deletions packages/meteor-lib/src/api/userActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ export interface NewUserActionAPI {
rundownPlaylistId: RundownPlaylistId,
marker: QuickLoopMarker | null
): Promise<ClientAPI.ClientResponse<void>>
clearQuickLoop(
userEvent: string,
eventTime: Time,
rundownPlaylistId: RundownPlaylistId
): Promise<ClientAPI.ClientResponse<void>>
}

export enum UserActionAPIMethods {
Expand Down Expand Up @@ -441,6 +446,7 @@ export enum UserActionAPIMethods {

'setQuickLoopStart' = 'userAction.setQuickLoopStart',
'setQuickLoopEnd' = 'userAction.setQuickLoopEnd',
'clearQuickLoop' = 'userAction.clearQuickLoop',
}

export interface ReloadRundownPlaylistResponse {
Expand Down
1 change: 1 addition & 0 deletions packages/meteor-lib/src/userAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ export enum UserAction {
CREATE_ADLIB_TESTING_RUNDOWN,
SET_QUICK_LOOP_START,
SET_QUICK_LOOP_END,
CLEAR_QUICK_LOOP,
}
4 changes: 4 additions & 0 deletions packages/webui/src/client/lib/RundownResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ export function isLoopDefined(playlist: DBRundownPlaylist | undefined): boolean
return playlist?.quickLoop?.start != null && playlist?.quickLoop?.end != null
}

export function isAnyLoopMarkerDefined(playlist: DBRundownPlaylist | undefined): boolean {
return playlist?.quickLoop?.start != null || playlist?.quickLoop?.end != null
}

export function isLoopRunning(playlist: DBRundownPlaylist | undefined): boolean {
return !!playlist?.quickLoop?.running
}
Expand Down
2 changes: 2 additions & 0 deletions packages/webui/src/client/lib/clientUserAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ function userActionToLabel(userAction: UserAction, t: i18next.TFunction) {
return t('Setting as QuickLoop Start')
case UserAction.SET_QUICK_LOOP_END:
return t('Setting as QuickLoop End')
case UserAction.CLEAR_QUICK_LOOP:
return t('Clear QuickLoop')
default:
assertNever(userAction)
}
Expand Down
19 changes: 19 additions & 0 deletions packages/webui/src/client/ui/RundownView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
import { isEntirePlaylistLooping, isLoopRunning } from '../lib/RundownResolver'
import { useRundownAndShowStyleIdsForPlaylist } from './util/useRundownAndShowStyleIdsForPlaylist'
import { RundownPlaylistClientUtil } from '../lib/rundownPlaylistUtil'
import * as RundownResolver from '../lib/RundownResolver'

import { MAGIC_TIME_SCALE_FACTOR } from './SegmentTimeline/Constants'

Expand Down Expand Up @@ -553,6 +554,15 @@ const RundownHeader = withTranslation()(
}
}

clearQuickLoop = (e: any) => {
const { t } = this.props
if (this.props.studioMode && this.props.playlist.activationId) {
doUserAction(t, e, UserAction.CLEAR_QUICK_LOOP, (e, ts) =>
MeteorCall.userAction.clearQuickLoop(e, ts, this.props.playlist._id)
)
}
}

holdUndo = (e: any) => {
const { t } = this.props
if (
Expand Down Expand Up @@ -1002,6 +1012,12 @@ const RundownHeader = withTranslation()(

render(): JSX.Element {
const { t } = this.props

const canClearQuickLoop =
!!this.props.studio.settings.enableQuickLoop &&
!RundownResolver.isLoopLocked(this.props.playlist) &&
RundownResolver.isAnyLoopMarkerDefined(this.props.playlist)

return (
<>
<Escape to="document">
Expand Down Expand Up @@ -1035,6 +1051,9 @@ const RundownHeader = withTranslation()(
{this.props.playlist.activationId ? (
<MenuItem onClick={(e) => this.hold(e)}>{t('Hold')}</MenuItem>
) : null}
{this.props.playlist.activationId && canClearQuickLoop ? (
<MenuItem onClick={(e) => this.clearQuickLoop(e)}>{t('Clear QuickLoop')}</MenuItem>
) : null}
{!(
this.props.playlist.activationId &&
!this.props.playlist.rehearsal &&
Expand Down

0 comments on commit 1939c61

Please sign in to comment.