Commit Graph

1182 Commits

Author SHA1 Message Date
Claude af46d6d759 refactor(finder): drop the pointer movement guard
The guard skipped a pointer move whose coordinates matched the previous
one, on the reasoning that the list scrolling under a still cursor would
otherwise pull the selection away from the keyboard.

Measuring it does not support that. With a list of nineteen results in a
viewport too short to hold them, and the cursor parked on a row, neither
arrowing through the results nor scrolling the wheel delivers a single
pointer move to any row, and the selection lands exactly where the
keyboard left it. Removing the guard reproduces both results unchanged,
and hovering still selects.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-19 05:00:11 +00:00
Claude 3cc0875e9c refactor(buttons): add a button which carries a pressed state
Toggles were spelled out at each site as a variant picked from state,
which left the accessible state optional: of the twelve places that do
this, six style themselves as pressed without ever saying so, including
the blackout and message visibility controls.

ToggleButton ties the two together so a toggle cannot look active
without announcing it. Adopted in the finder and the log, which were
already pairing the two by hand. The remaining sites in message and
client control still need migrating, and the emphasis on the submit
button in the link form is deliberately not a toggle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-19 04:31:56 +00:00
Claude 4fa24ae9bd refactor(finder): build filters from the shared button
The log panel already presents filters as a "Filter by" label followed by
a row of buttons which carry their state in the primary variant. The
finder had grown its own markup and styles for the same idea, so it now
uses the same component and the bespoke styles go.

Unlike the log the accessible name stays the field label rather than
changing with the state, since aria-pressed already carries that and a
name which moves is harder to target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-19 04:23:23 +00:00
Claude 90ae00c88e fix(finder): colour the index badge with the shared helper
The badge painted the entry colour straight into the background and left
the text colour fixed, so a light entry colour rendered an unreadable
number. Every other place that tints an element by entry colour goes
through getAccessibleColour, which picks the text colour to match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-19 04:19:47 +00:00
Claude bb221685ea refactor(finder): flatten the result type and trim the tests
The three-variant result union differed only in whether an entry had a
cue, an event index and a parent, and the UI narrowed it with runtime
property checks anyway, so the discrimination bought nothing while
costing three near-identical branches to build a result. One flat type
removes those branches and the checks around them.

Skipping non-searchable entries asked whether an entry was a group or a
milestone, then asked again when building the result. It now asks once
whether it is a delay, which is what the guard actually meant.

The search functions move out of the memo closure to the module, where
they are ordinary pure functions.

Whether to show the matched field compared against its display label, so
a custom field labelled "Title" would have had its match hidden. It now
compares the field key.

Drops the review document, which had served its purpose, and reduces the
finder tests to a single one covering the path a user takes: open from a
focused field, find an entry by its note, scope with a badge, and reveal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-18 18:59:29 +00:00
Claude 2fc072a9d3 feat(finder): make filters a toggle and flag hidden results
The filter badges wrote a keyword prefix into the search box, which put
syntax in front of the user for something the badge already expresses.
They are now toggles: the input holds only what is being searched for,
the active badge is highlighted, and pressing it again returns to
searching every field. Typing a keyword still works and lights up the
badge it refers to, so the documented syntax is not lost.

The result list said nothing when it had more matches than it rendered.
It now ends with a count of what is hidden, since the footer total is
easy to miss while scanning results.

Also stops the search shortcut toggling the dialog. Toggling on a key
that mounts and unmounts the dialog is unreliable, and browsers treat a
repeated find shortcut as "focus the search again". It now opens, and
selects the existing query when the finder is already up, leaving
Escape to close.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-18 16:54:10 +00:00
Claude a779f96f69 feat(finder): search all text fields and add filter badges
Searching only matched titles, so an event was unreachable by its cue,
its note, or any custom field value. Custom fields are how teams model
their own show data, which made the most valuable data the least
findable.

A bare query now matches cue, title, note and text custom fields across
events, groups and milestones, and each result names the field it
matched with an excerpt, so a hit in a note is legible. Widening the
scan is free: at 5000 entries a pass over every field measures the same
as the previous title-only pass, both far below the render cost.

The filter syntax was only discoverable through a line of footer text.
It is now a row of badges built from the fixed fields plus the project
custom fields, which scope the search while keeping whatever the user
already typed. The input becomes controlled, which removes the effect
that replayed the last search on rundown changes.

Raises the result cap and reports the total, since matching more fields
means more results than the previous cap could show.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-18 12:23:00 +00:00
Claude 671df541ef fix(finder): open from inputs and find milestones by cue
Two defects surfaced while reviewing the feature.

The search shortcut was dead while any input had focus. The hotkey hook
skips input elements by default, so the shortcut did nothing while
editing an entry title, which is exactly when a user reaches for it.
Opt out of that behaviour and drop the local handler that partially
worked around it, so a single binding both opens and closes.

Milestones were skipped by the cue search even though they carry a cue
and display it in the rundown, so filtering by cue could never find one.
They are already covered by the title search.

Adds e2e coverage for both, and fires the shortcut from a focused input
in the existing keyboard test so the first defect stays fixed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-18 11:55:14 +00:00
Claude cabfc592df fix(finder): correct result selection and dismissal
Track the highlighted result by entry ID rather than by list index.
The index was never reset when results changed, so a background
refetch that shrank the list left it pointing past the end and
selecting threw on an undefined entry. Resolving by ID falls back to
the first result instead, and keeps the user's position across
rundown edits.

Submit the entry belonging to the clicked row instead of whichever
row was highlighted. The two only agreed because a mousemove usually
precedes a click, so touch input navigated to the wrong entry.

Ignore pointer moves that do not change the cursor position: scrolling
the list under a stationary pointer fires a move event which pulled
the selection away from the keyboard cursor. Keep the highlighted row
scrolled into view while navigating.

Close the finder on the search shortcut. Mantine ignores hotkeys while
an input is focused, so the global toggle could not close the modal
once the user was typing. The global Escape handler is dropped: the
dialog already dismisses on Escape, and registering it document wide
conflicts with inline field editing.

Drop the bounds check in the index search, which compared an event
ordinal against the count of all entries. The loop below it already
returns no results when no event carries that index.

Add e2e coverage for clicking a result, picking one with the keyboard,
and closing with the shortcut. This needs the finder rows and the
rundown event row to expose test ids and selection state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
2026-08-17 14:52:49 +00:00
Carlos Valente c6eccec30e refactor(settings): show new app indicator 2026-08-09 16:48:20 +02:00
Carlos Valente 5220c2c374 fix(settings): prevent loader overflow 2026-08-09 16:48:20 +02:00
Alex Christoffer Rasmussen a006331fea Group duration context menu utils (#1748) 2026-08-09 16:45:47 +02:00
Carlos Valente ac0ef06459 bump version to 4.12.0 2026-08-09 10:44:13 +02:00
Carlos Valente fb559ed9da refactor(progress bar): reset when event changes 2026-08-05 15:30:22 +02:00
Carlos Valente 24be49ef66 refactor(settings): polish settings UI 2026-08-02 13:44:28 +02:00
Carlos Valente f0c284b708 refactor(link): add row presentation variant 2026-08-02 13:44:28 +02:00
Carlos Valente 9e42f18299 feat(settings): add searchable navigation 2026-08-02 13:44:28 +02:00
Carlos Valente bdd815678b refactor(ui): extend link and modal variants 2026-08-02 13:44:28 +02:00
Carlos Valente 12fc76b8ff refactor(op): simplify UI elements 2026-08-02 12:55:49 +02:00
Carlos Valente 8ed0a1689e refactor(op): clarify settings text 2026-08-02 12:55:49 +02:00
Carlos Valente ba18b8dba7 refactor(ui): rundown title UI polish 2026-08-02 12:55:49 +02:00
Carlos Valente 608247157b refactor(rundown): cap rundown names to 64 characters 2026-08-02 12:55:49 +02:00
Carlos Valente 514b6c3a02 refactor(navigation): custom params indicators only for current view 2026-08-02 12:55:49 +02:00
Carlos Valente 2050735014 refactor(ui): title alignment is logo aware 2026-08-02 12:55:49 +02:00
Carlos Valente 76b1341432 refactor(logo): upload on submit form 2026-08-02 10:39:58 +02:00
Carlos Valente c7422fc7c7 refactor(logo): improve flow for managing logo 2026-08-02 10:39:58 +02:00
Carlos Valente 94d54529ee refactor(views): consistent loading and empty states 2026-08-01 16:25:14 +02:00
Carlos Valente f7535651f6 refactor(info): improve UI consistency and polish 2026-08-01 14:41:39 +02:00
Carlos Valente 5cf36f049a refactor(modal): allow wider modals 2026-07-25 14:28:45 +02:00
Carlos Valente c6248b0c72 refactor(import): improve preview UI 2026-07-25 14:28:45 +02:00
Alex Christoffer Rasmussen 2a890cf2b3 fix: issue where a countToEnd would lead to incorrect expected times (#2149)
* 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
2026-07-25 11:22:24 +02:00
Carlos Valente a8c611911d refactor(rundown): new entries are appended to rundown 2026-07-22 07:17:39 +02:00
Carlos Valente 8363f06a5c chore(rundown): improve documentation of insert logic 2026-07-22 07:17:39 +02:00
Carlos Valente 347c748dd9 feat(rundown): add shortcut to jump to current element 2026-07-18 17:03:02 +02:00
Carlos Valente 0c5e87b7e7 fix(ui): prevent warning indicator from overflowing container 2026-07-18 16:52:36 +02:00
Carlos Valente 64082ceac0 refactor(rundown): improve visibility of count to end 2026-07-18 16:45:55 +02:00
Carlos Valente f598e8dab1 refactor(time control): improve handling of overtime and count to end 2026-07-18 16:45:55 +02:00
Carlos Valente 0c84a3ff9e fix: delays account for midnight 2026-07-18 16:45:55 +02:00
Carlos Valente c8760b5e9c bump version to 4.11.0 2026-07-18 15:24:25 +02:00
Claude 34360a5b8f feat(import): add merge strategy and new-rundown destination to spreadsheet import
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
2026-07-17 22:26:19 +02:00
Claude 5e6debcce0 fix(views): center timer digits with flexbox for embedded browser compatibility
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
2026-07-17 20:59:49 +02:00
Carlos Valente c191786e50 refactor(navigation): clear params from editor drawer 2026-07-17 15:50:42 +02:00
Carlos Valente 6911e37c18 refactor(automation): improve automation UX 2026-07-17 10:53:45 +02:00
Claude 86b2132cdc feat(automation): expose group title and allow setting secondary text
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
2026-07-17 10:53:45 +02:00
Carlos Valente daa032e92c ux(finder): add navigation shortcuts 2026-07-14 12:04:44 +02:00
Carlos Valente ae65ec97d6 fix(shortcut): correct shortcut to delete 2026-07-14 12:04:44 +02:00
Carlos Valente e7e4302100 refactor(shortcuts): improve readability of info element 2026-07-14 12:04:44 +02:00
Carlos Valente 7e7d35980a refactor(op): improve status recognition 2026-07-14 11:58:59 +02:00
Carlos Valente 5001dda284 feat(op): add group visual relation 2026-07-14 11:58:59 +02:00
Carlos Valente a75d35bdc0 refactor(op): improve delay indicator styles 2026-07-14 11:58:59 +02:00