Skip to content

Commit 2e66b26

Browse files
matteiusclaude
andcommitted
fix(ui): recordings table overflow, playback modal fit, streams 4-col on 2xl
- Recordings table: add min-w-0 to .recordings-content so the flex child allows overflow-x-auto on the table wrapper instead of pushing past its parent and clipping the Actions column. - Playback modal: restructure so the video is a flex-1 child that absorbs available space while the playback-position label and PLAYBACK CONTROLS stay at natural height. Modal now always fits within 95vh with no internal scrollbar on desktop. - Streams grid: swap auto-fill,minmax(360px,1fr) for explicit breakpoints (1/2/3/4 cols) so ultra-wide displays step up to 4 columns at the 2xl breakpoint instead of stopping at 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 081ec83 commit 2e66b26

3 files changed

Lines changed: 35 additions & 38 deletions

File tree

web/js/components/preact/RecordingsView.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ export function RecordingsView() {
939939
/>
940940
)}
941941

942-
<div class="recordings-content flex-1">
942+
<div class="recordings-content flex-1 min-w-0">
943943
<ActiveFilters
944944
activeFiltersDisplay={activeFiltersDisplay}
945945
removeFilter={removeFilter}

web/js/components/preact/StreamsView.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,14 +1452,13 @@ export function StreamsView() {
14521452
))}
14531453
</div>
14541454

1455-
{/* Responsive card grid.
1456-
`auto-fill` + `minmax(360px, 1fr)` is load-bearing — it
1457-
lets cards reflow naturally at every viewport from 375 px
1458-
up to 1920+ without forcing horizontal scroll (PRD §5.5 /
1455+
{/* Responsive card grid — explicit breakpoints so the grid
1456+
caps at 4 columns on ultra-wide (≥1536 px) displays while
1457+
still reflowing down to 1 column at ≤640 px (PRD §5.5 /
14591458
#399). */}
14601459
<div
14611460
id="streams-grid"
1462-
className="grid grid-cols-[repeat(auto-fill,minmax(360px,1fr))] gap-4"
1461+
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4"
14631462
role="list"
14641463
aria-label={t('nav.streams')}
14651464
>

web/js/components/preact/UI.jsx

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ export function VideoModal({ isOpen, onClose, videoUrl, title, downloadUrl }) {
842842
className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50"
843843
onClick={handleBackgroundClick}
844844
>
845-
<div className={`modal-content bg-card text-card-foreground rounded-lg shadow-xl max-w-4xl max-h-[90vh] flex flex-col transform transition-all duration-300 ease-out scale-95 opacity-0 w-full md:w-[90%]`}>
845+
<div className={`modal-content bg-card text-card-foreground rounded-lg shadow-xl max-w-4xl max-h-[95vh] h-[95vh] flex flex-col overflow-hidden transform transition-all duration-300 ease-out scale-95 opacity-0 w-full md:w-[90%]`}>
846846
<div className="flex justify-between items-center p-3 border-b border-border flex-shrink-0">
847847
<h3 id="video-preview-title" className="text-lg font-semibold text-gray-900 dark:text-white truncate mr-2">
848848
{title || 'Video'}
@@ -855,40 +855,38 @@ export function VideoModal({ isOpen, onClose, videoUrl, title, downloadUrl }) {
855855
</button>
856856
</div>
857857

858-
<div className="flex-1 min-h-0 overflow-y-auto">
859-
<div className="p-3">
860-
<div className="relative flex justify-center">
861-
<div
862-
ref={videoContainerRef}
863-
data-testid="recording-video-container"
864-
className={isFullscreen ? 'relative w-screen h-screen bg-black' : 'relative inline-block max-w-full w-full max-h-[50vh] bg-black overflow-hidden'}
858+
<div className="flex-1 min-h-0 flex flex-col overflow-hidden">
859+
<div className="flex-1 min-h-0 p-3 flex justify-center items-center">
860+
<div
861+
ref={videoContainerRef}
862+
data-testid="recording-video-container"
863+
className={isFullscreen ? 'relative w-screen h-screen bg-black' : 'relative inline-block max-w-full max-h-full h-full bg-black overflow-hidden'}
864+
>
865+
<video
866+
ref={videoRef}
867+
className={isFullscreen ? 'w-full h-full object-contain' : 'w-full h-full max-w-full max-h-full object-contain'}
868+
controls
869+
controlsList="nofullscreen"
870+
key={videoUrl} /* Add key to force re-render when URL changes */
871+
onError={(e) => {
872+
console.error('Video error:', e);
873+
showStatusMessage('Error loading video. Please try again.', 'error');
874+
}}
875+
onLoadStart={() => console.log('Video load started')}
876+
onLoadedData={() => console.log('Video data loaded')}
865877
>
866-
<video
867-
ref={videoRef}
868-
className={isFullscreen ? 'w-full h-full object-contain' : 'w-full h-auto max-w-full max-h-[50vh] object-contain'}
869-
controls
870-
controlsList="nofullscreen"
871-
key={videoUrl} /* Add key to force re-render when URL changes */
872-
onError={(e) => {
873-
console.error('Video error:', e);
874-
showStatusMessage('Error loading video. Please try again.', 'error');
875-
}}
876-
onLoadStart={() => console.log('Video load started')}
877-
onLoadedData={() => console.log('Video data loaded')}
878-
>
879-
{/* Use source element instead of src attribute for better control */}
880-
{videoUrl && <source src={videoUrl} type="video/mp4" />}
881-
</video>
882-
<canvas
883-
ref={canvasRef}
884-
className="absolute top-0 left-0 w-full h-full pointer-events-none"
885-
style={{ display: 'none', zIndex: 2 }}
886-
/>
887-
</div>
878+
{/* Use source element instead of src attribute for better control */}
879+
{videoUrl && <source src={videoUrl} type="video/mp4" />}
880+
</video>
881+
<canvas
882+
ref={canvasRef}
883+
className="absolute top-0 left-0 w-full h-full pointer-events-none"
884+
style={{ display: 'none', zIndex: 2 }}
885+
/>
888886
</div>
889887
</div>
890888

891-
<div className="px-3 pb-1">
889+
<div className="px-3 pb-1 flex-shrink-0">
892890
<div
893891
id="recording-playback-position"
894892
data-testid="recording-playback-position"
@@ -898,7 +896,7 @@ export function VideoModal({ isOpen, onClose, videoUrl, title, downloadUrl }) {
898896
</div>
899897
</div>
900898

901-
<div id="recordings-controls" className="mx-3 mb-3 p-3 border border-green-500 rounded-lg bg-card text-card-foreground shadow-md relative z-10">
899+
<div id="recordings-controls" className="mx-3 mb-3 p-3 border border-green-500 rounded-lg bg-card text-card-foreground shadow-md relative z-10 flex-shrink-0 overflow-y-auto">
902900
<h3 className="text-base font-bold text-center mb-2 text-foreground">
903901
PLAYBACK CONTROLS
904902
</h3>

0 commit comments

Comments
 (0)