summaryrefslogtreecommitdiff
path: root/web/css
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-03 19:17:04 +0300
committerPaul Buetow <paul@buetow.org>2026-05-03 19:17:04 +0300
commit30c2b0fe8232cc748ab2bded6ab4d76febe32425 (patch)
tree985578b326a1ff8fe7af395bf08471857376b8fc /web/css
parent687b86cdeef2192272f0945ddd496322a9113f9e (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.css79
-rw-r--r--web/css/player.css21
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;