diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-03 19:17:04 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-03 19:17:04 +0300 |
| commit | 30c2b0fe8232cc748ab2bded6ab4d76febe32425 (patch) | |
| tree | 985578b326a1ff8fe7af395bf08471857376b8fc /web/css | |
| parent | 687b86cdeef2192272f0945ddd496322a9113f9e (diff) | |
fix(admin): fix rescan goroutine lifecycle and race on shared ScanProgress
- Protect adminService scan state (cancel func + progress pointer) with sync.Mutex.
- Allocate fresh ScanProgress per trigger and pass it to the scanner,
eliminating races on the previously shared progress struct.
- Cancel previous scan context before starting a new one.
- Add tests for cancellation, fresh progress per scan, concurrent triggers,
and empty progress when never started.
- Fix race-prone tests by polling Running==true before waiting for completion.
Diffstat (limited to 'web/css')
| -rw-r--r-- | web/css/lightbox.css | 79 | ||||
| -rw-r--r-- | web/css/player.css | 21 |
2 files changed, 100 insertions, 0 deletions
diff --git a/web/css/lightbox.css b/web/css/lightbox.css new file mode 100644 index 0000000..83bf946 --- /dev/null +++ b/web/css/lightbox.css @@ -0,0 +1,79 @@ +.lightbox-overlay { + position: fixed; + inset: 0; + z-index: 80; + background: var(--bg-overlay); + display: none; + place-items: center; +} +.lightbox-overlay.open { + display: grid; +} + +.lightbox-stage { + width: 90vw; + height: 85vh; + display: grid; + place-items: center; + overflow: hidden; +} +#lightbox-image { + max-width: 100%; + max-height: 100%; + object-fit: contain; + transition: transform 0.15s ease; + user-select: none; + cursor: zoom-in; +} + +.lightbox-nav { + position: absolute; + top: 50%; + transform: translateY(-50%); + background: var(--bg-surface); + border: 1px solid var(--border); + font-size: 2rem; + padding: 0.5rem 1rem; + cursor: pointer; +} +.lightbox-prev { + left: 1rem; +} +.lightbox-next { + right: 1rem; +} +.lightbox-close { + position: absolute; + top: 1rem; + right: 1rem; + background: var(--bg-surface); + border: 1px solid var(--border); + cursor: pointer; +} + +.lightbox-toolbar { + position: absolute; + bottom: 1rem; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 0.5rem; + align-items: center; + background: var(--bg-surface); + padding: 0.5rem 1rem; + border-radius: var(--radius-lg); + border: 1px solid var(--border); +} +.lightbox-meta { + font-size: 0.875rem; + color: var(--text-secondary); + margin-left: 0.5rem; + white-space: nowrap; +} +.lightbox-counter { + font-size: 0.875rem; + color: var(--text-secondary); + margin-left: 0.5rem; + white-space: nowrap; + font-variant-numeric: tabular-nums; +} diff --git a/web/css/player.css b/web/css/player.css index c6070f9..0f468f9 100644 --- a/web/css/player.css +++ b/web/css/player.css @@ -137,6 +137,27 @@ background: var(--player-stage-bg); } +/* Image viewer inside player */ +.player .media-image { + width: 100%; + height: 100%; + object-fit: contain; + display: block; + transition: transform 0.15s ease; + user-select: none; +} +.player .media-image.hidden { + display: none; +} + +/* Show/hide controls per media type */ +.player.has-image .video-only { + display: none !important; +} +.player:not(.has-image) .image-only { + display: none !important; +} + /* Overlay controls */ .player .controls { flex: 0 0 auto; |
