Groups can now opt into a shared timer, so stage outputs show how much time
the whole block has left instead of only the running event.
The value is derived in the client from the running event timer plus the
content still scheduled after it, which makes the group behave as if it were
a single event containing all its children. Keeping it relative to the event
timer (rather than recalculating from the clock) means pause, added time,
overtime, roll and midnight rollovers are all inherited, and moving between
events inside a group cannot introduce a discontinuity.
The remainder aggregation mirrors the server side group duration calculation:
non playable entries are skipped and gaps are accounted for.
Warning and danger thresholds belong to the event and carry no meaning against
a group duration, so they are suppressed while the group timer is showing.
Overtime is kept, but only once the group itself has run out of time.
- add OntimeGroup.useGroupTimer, defaulting to false
- show the group timer in the timer view and the PiP timer
- indicate the override in the timer view, PiP, group header and timer preview
- add a switch to the group editor
The PiP window mounts its own react root, which had no query client and could
therefore not read the rundown. It is now wrapped in a provider, which also
means its view settings are no longer frozen at the moment the window opened.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kniqs443KUNCRABwVJwT7K
* fix: issue where a count-to-end would lead to incorrect expected times
* fix: include add time in overtime when countToEnd
* fix: ui and server use same calculation for expected end
The server serves html/timer-legacy.html and html/login.html from disk
at runtime, relative to the bundled server. The Docker image copies
these files but the electron packaging did not, so the view 404ed in
all desktop distributions.
Additionally, AppImages mount at /tmp/.mount_*, a hidden directory.
Express sendFile refuses paths containing dot-segments by default
(returns 404 without touching disk), so the view failed on Linux even
with the file packaged. Allow dotfiles for this route; the request
path is fixed so no user input is affected.
The Stage Timer and PiP Timer views relied on `align-content: center` to
vertically center the timer digits inside `.timer-container`, which is a
plain block element. Aligning children of a block container via
`align-content` only works in Chromium 123+ (Firefox 125+, Safari 17.4+).
Embedded browsers such as vMix Browser Input (CEF V115) and other older
CEF/Chromium-based production tools ignore the property, so the digits
fall back to the top of the container while every other element renders
correctly.
Make `.timer-container` a real flex column and center with
`justify-content: center`, which is universally supported and matches the
centering approach used elsewhere in the codebase. The removed
`justify-self`/`align-self` were no-ops on a full-width flex item.
Fixes#2126
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T6ENZ3r6JXZb1fpYw2oNY
Surface {{groupNow.*}} template variables (title, note, colour, times,
custom fields) in the automation template autocomplete so events inside a
group can reference their group. The runtime store already carries
groupNow, so substitution and filters worked already; this makes it
discoverable.
Extend the message-secondary action with an optional text field so an
automation can set the secondary message content, not just its source.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LZYPZVdZLWowU7DyzGkWyy
Confirmed empirically that it now suppresses nothing under TS 7.0.2:
compiling tsconfig.dts.json directly with this flag set to "6.0",
"7.0", or removed entirely all produce identical (clean) output. It
was a leftover suppression the previous tsdown mode never actually
needed once nothing in the config triggers a deprecation warning.
TypeScript 7 ships as a native Go binary and drastically trims the
package's public JS API surface (no more `main`, and `exports['.']`
now only resolves to lib/version.cjs) since the programmatic compiler
API isn't stable again until 7.1. This broke apps/resolver's tsdown
build, which used rolldown-plugin-dts' tsc-program mode (import ts
from 'typescript'; ts.createProgram(...)) for declaration generation.
Fix by switching that build to isolatedDeclarations, which lets
rolldown-plugin-dts generate .d.ts via its oxc-based path instead of
the TS compiler API entirely. That surfaced two isolatedDeclarations
violations in ontime-types (array/Object.keys initializers lacking
explicit annotations), fixed with explicit `string[]` types matching
their existing inferred type. Also bumped tsdown to pick up its latest
rolldown-plugin-dts, and disabled allowJs in tsconfig.dts.json since
it's incompatible with isolatedDeclarations.
Full workspace typecheck, lint, build, and test suite (1186 tests)
pass under TypeScript 7.0.2.
* feat: create the first event from the cuesheet
* chore: cleanup css
* test: cuesheet beckground edit from empty state
* feat: only show +event button when user is in edit mode and have full write perms