We were remembering the aspect ratio and reserving the full width of the
column, which over-reserves for an image smaller than the column: the row
would settle to a smaller size once the image was shown.
We now remember the size of the image and express the reservation in CSS
as min(100%, width), which is what the image itself resolves to at any
column width. Column sizes are applied as CSS variables and do not
re-render the cells, so the reservation follows a resize on its own.
Also groups the tests around the behaviour they describe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKXcDrZoQXbJpaXiLi1aff
A path to a local file resolves on the machine running ontime, but not
for the clients we serve the cuesheet to, so we no longer accept it.
Validation now parses the value as a URL and checks the protocol, which
also rejects malformed values that the previous prefix check let through.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKXcDrZoQXbJpaXiLi1aff
A value which is not a link was discarded on blur without any feedback:
the text stayed in the field, so it looked like it had been saved. We now
mark the field and say what is expected. Paths served by ontime itself
(eg. /user/slide.png) are now accepted, they were rejected before.
An image which cannot be loaded showed a broken icon with no explanation.
This is what a dropbox share link does, since it serves an html page
rather than the image, so it is worth naming the problem.
We also reserve the space of an image while it is loading, using the
aspect ratio of the last time we saw it. Rows are unmounted while out of
view, so without it the row collapses and grows again on the way back,
shifting the table under the user.
Smaller items in the same cell: the lazy loading attribute only added a
gate before the request (the row is only mounted when it is already close
to the viewport), the image had no alt text, and two expressions could
never run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKXcDrZoQXbJpaXiLi1aff
Search every text field with optional filters, keep result selection stable, and expose clearer match context and counts. Cover query parsing, matching, mixed-entry indexing, and the reveal flow.
* 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.