Skip to content

Commit

Permalink
Merge branch 'release51' into test/release51-pgw
Browse files Browse the repository at this point in the history
  • Loading branch information
nytamin committed Feb 12, 2025
2 parents 4a3efd9 + 608dd27 commit 72f2bb3
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 5 deletions.
25 changes: 25 additions & 0 deletions packages/documentation/docs/for-developers/url-query-parameters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
sidebar_label: URL Query Parameters
sidebar_position: 10
---

# URL Query Parameters
Appending query parameter(s) to the URL will allow you to modify the behaviour of the GUI, as well as control the [Access Levels](../user-guide/features/access-levels.md).

| Query Parameter | Description |
| :---------------------------------- | :------------------------------------------------------------------------ |
| `admin=1` | Gives the GUI the same access as the combination of [Configuration Mode](../user-guide/features/access-levels.md#Configuration-Mode) and [Studio Mode](../user-guide/features/access-levels.md#Studio-Mode) as well as having access to a set of [Testing Mode](../user-guide/features/access-levels.md#Testing-Mode) tools and a Manual Control section on the Rundown page. _Default value is `0`._ |
| `studio=1` | [Studio Mode](../user-guide/features/access-levels.md#Studio-Mode) gives the GUI full control of the studio and all information associated to it. This includes allowing actions like activating and deactivating rundowns, taking parts, adlibbing, etcetera. _Default value is `0`._ |
| `buckets=0,1,...` | The buckets can be specified as base-0 indices of the buckets as seen by the user. This means that `?buckets=1` will display the second bucket as seen by the user when not filtering the buckets. This allows the user to decide which bucket is displayed on a secondary attached screen simply by reordering the buckets on their main view. |
| `develop=1` | Enables the browser's default right-click menu to appear. It will also reveal the _Manual Control_ section on the Rundown page. _Default value is `0`._ |
| `display=layout,buckets,inspector` | A comma-separated list of features to be displayed in the shelf. Available values are: `layout` \(for displaying the Rundown Layout\), `buckets` \(for displaying the Buckets\) and `inspector` \(for displaying the Inspector\). |
| `help=1` | Enables some tooltips that might be useful to new users. _Default value is `0`._ |
| `ignore_piece_content_status=1` | Removes the "zebra" marking on VT pieces that have a "missing" status. _Default value is `0`._ |
| `reportNotificationsId=anyId,...` | Sets an ID for an individual client GUI system, to be used for reporting Notifications shown to the user. The Notifications' contents, tagged with this ID, will be sent back to the Sofie Core's log. _Default value is `0`, which disables the feature._ |
| `shelffollowsonair=1` | _Default value is `0`._ |
| `show_hidden_source_layers=1` | _Default value is `0`._ |
| `speak=1` | Experimental feature that starts playing an audible countdown 10 seconds before each planned _Take_. _Default value is `0`._ |
| `vibrate=1` | Experimental feature that triggers the vibration API in the web browser 3 seconds before each planned _Take_. _Default value is `0`._ |
| `zoom=1,...` | Sets the scaling of the entire GUI. _The unit is a percentage where `100` is the default scaling._ |


10 changes: 7 additions & 3 deletions packages/documentation/docs/user-guide/features/access-levels.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ The access level is persisted in browser's Local Storage. To disable, visit`?the
| **Settings** | No | Yes | No | Yes |


### Basic mode
### Basic Mode

Without enabling any additional modes in Sofie, the browser will have minimal access to the system. It will be able to view a rundown but, will not have the ability to manipulate it. This includes activating, deactivating, or resetting the rundown as well as taking the next part, adlib, etc.

### Studio mode
### Studio Mode

Studio Mode gives the current browser full control of the studio and all information associated to it. This includes allowing actions like activating and deactivating rundowns, taking parts, adlibbing, etc. This mode is accessed by adding a `?studio=1` to the end of the URL.

### Configuration mode
### Configuration Mode

Configuration mode gives the user full control over the Settings pages and allows full access to the system including the ability to modify _Blueprints_, _Studios_, or _Show Styles_, creating and restoring _Snapshots_, as well as modifying attached devices.

Expand All @@ -44,3 +44,7 @@ Enables the page Test Tools, which contains various tools useful for testing the
### Developer Mode

This mode will enable the browsers default right click menu to appear and can be accessed by adding `?develop=1` to the URL. It will also reveal the Manual Control section on the Rundown page.

### See Also

[URL Query Parameters](../../for-developers/url-query-parameters.md)
78 changes: 76 additions & 2 deletions packages/job-worker/src/playout/timeline/multi-gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TimelineObjRundown } from '@sofie-automation/corelib/dist/dataModel/Tim
import { normalizeArray } from '@sofie-automation/corelib/dist/lib'
import { PieceTimelineMetadata } from './pieceGroup'
import { StudioPlayoutModelBase } from '../../studio/model/StudioPlayoutModel'
import { logger } from '../../logging'
import { JobContext } from '../../jobs'
import { getCurrentTime } from '../../lib'
import { PlayoutModel } from '../model/PlayoutModel'
Expand Down Expand Up @@ -46,7 +47,7 @@ export function deNowifyMultiGatewayTimeline(
playoutModel.nextPartInstance
)

deNowifyCurrentPieces(
const { objectsNotDeNowified } = deNowifyCurrentPieces(
targetNowTime,
timingContext,
currentPartInstance,
Expand All @@ -55,6 +56,9 @@ export function deNowifyMultiGatewayTimeline(
)

updatePlannedTimingsForPieceInstances(playoutModel, currentPartInstance, partGroupTimings, timelineObjsMap)

// Because updatePlannedTimingsForPieceInstances changes start times of infinites, we can now run deNowifyInfinites()
deNowifyInfinites(targetNowTime, objectsNotDeNowified, timelineObjsMap)
}

/**
Expand Down Expand Up @@ -142,16 +146,83 @@ function updatePartInstancePlannedTimes(
}
}

/**
* Replace the `now` time in any timeline objects in freshly-placed infinites.
*
* This is effectively only needed when a new item has been placed on the timeline just now and changes made by
* `updatePlannedTimingsForPieceInstances` haven't been taken into account when generating the timeline. On the next
* regeneration, items will already use the timestamps persited by `updatePlannedTimingsForPieceInstances` and will not
* be included in `infiniteObjs`.
*/
function deNowifyInfinites(
targetNowTime: number,
/** A list of objects that need to be updated */
infiniteObjs: TimelineObjRundown[],
timelineObjsMap: Record<string, TimelineObjRundown>
) {
/**
* Recursively look up the absolute starttime of a timeline object
* taking into account its parent's times.
* Note: This only supports timeline objects that have absolute enable.start times.
*/
const getStartTime = (obj: TimelineObjRundown): number | undefined => {
if (Array.isArray(obj.enable)) return undefined

const myStartTime = typeof obj.enable.start === 'number' ? obj.enable.start : undefined

if (!obj.inGroup) return myStartTime

if (myStartTime === undefined) return undefined

const parentObject = timelineObjsMap[obj.inGroup]
if (!parentObject) return undefined

const parentStartTime = getStartTime(parentObject)
if (parentStartTime === undefined) return undefined

return parentStartTime + myStartTime
}

for (const obj of infiniteObjs) {
if (Array.isArray(obj.enable) || obj.enable.start !== 'now') continue

if (!obj.inGroup) {
obj.enable = { start: targetNowTime }
continue
}

const parentObject = timelineObjsMap[obj.inGroup]
if (!parentObject) {
logger.error(`deNowifyInfinites: Parent obj "${obj.inGroup}" not found of object "${obj.id}"`)
continue
}

const parentStartTime = getStartTime(parentObject)
if (parentStartTime === undefined) {
logger.error(
`deNowifyInfinites: Unable to derive an absolute start time of parent "${obj.inGroup}" for object "${obj.id}"`
)
continue
}

obj.enable = { start: targetNowTime - parentStartTime }
logger.silly(
`deNowifyInfinites: Setting "${obj.id}" enable.start = ${obj.enable.start}, ${targetNowTime} ${parentStartTime} parentObject: "${parentObject.id}"`
)
}
}
/**
* Replace the `now` time in any Pieces on the timeline from the current Part with concrete start times
* @returns a list of object that couldn't be updated at this time.
*/
function deNowifyCurrentPieces(
targetNowTime: number,
timingContext: RundownTimelineTimingContext,
currentPartInstance: PlayoutPartInstanceModel,
currentPartGroupStartTime: number,
timelineObjsMap: Record<string, TimelineObjRundown>
) {
): { objectsNotDeNowified: TimelineObjRundown[] } {
const objectsNotDeNowified: TimelineObjRundown[] = []
// The relative time for 'now' to be resolved to, inside of the part group
const nowInPart = targetNowTime - currentPartGroupStartTime

Expand All @@ -176,6 +247,8 @@ function deNowifyCurrentPieces(
obj.enable = { start: nowInPart }
} else if (!obj.inGroup) {
obj.enable = { start: targetNowTime }
} else {
objectsNotDeNowified.push(obj)
}
}
}
Expand Down Expand Up @@ -203,6 +276,7 @@ function deNowifyCurrentPieces(
}
}
}
return { objectsNotDeNowified }
}

function updatePlannedTimingsForPieceInstances(
Expand Down

0 comments on commit 72f2bb3

Please sign in to comment.