From ce4588bcc19de8a6d421ab8fc3dc6a2ece887fee Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 26 Sep 2026 12:52:45 -0400 Subject: [PATCH] feat: put the monitor name, dvr controls and replay status on one row These three blocks stacked under the event video and each took a full line. Wrap them in a new #eventControls flex row: monitor name left, transport buttons centred, replay status right, wrapping onto separate lines when the viewport is too narrow. The span#rate was never closed, so #progress, #currentTime, #zoom and #fps were nested inside it. Close it, otherwise the whole status line lays out as a single flex item. The three children are flex containers themselves so their contents centre vertically while the boxes stay stretched to the row height. scaleToFit() measures the bottom edge of #replayStatus to decide how tall the video can be, and stretching keeps that edge at the bottom of the row, so auto scaling is unchanged. The new rules are scoped under #eventControls, which outranks the duplicated single-id rules in the classic and dark event.css. Co-Authored-By: Claude Opus 5 (1M context) --- web/skins/classic/css/base/views/event.css | 37 +++++++++ web/skins/classic/views/event.php | 95 +++++++++++----------- 2 files changed, 86 insertions(+), 46 deletions(-) diff --git a/web/skins/classic/css/base/views/event.css b/web/skins/classic/css/base/views/event.css index 961e7d9ab..1994fd019 100644 --- a/web/skins/classic/css/base/views/event.css +++ b/web/skins/classic/css/base/views/event.css @@ -146,6 +146,43 @@ height: 100%; grid-area: 1/1; } +/* The monitor name, the DVR transport buttons and the replay status share one + row under the video. #replayStatus stays the last child because scaleToFit() + measures its bottom edge to size the video. */ +#eventControls { + display: flex; + flex-wrap: wrap; + align-items: stretch; + justify-content: space-between; + column-gap: 0.5rem; +} + +#eventControls > .monitorStatus, +#eventControls > #dvrControls, +#eventControls > #replayStatus { + display: flex; + flex-wrap: wrap; + align-items: center; + margin: 3px 0 2px; + clear: none; +} + +#eventControls > .monitorStatus { + flex: 1 1 auto; + min-width: 0; + justify-content: flex-start; +} + +#eventControls > #dvrControls { + flex: 0 0 auto; + justify-content: center; +} + +#eventControls > #replayStatus { + flex: 1 1 auto; + justify-content: flex-end; +} + #monitorStatus { width: 100%; margin-top: 3px; diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index 5ae8c4241..190a4873c 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -491,56 +491,59 @@ if (defined('AUDIO_MOTION_ENABLED') && AUDIO_MOTION_ENABLED) echo ' ' . PHP_EOL; ?> -
- Name()) . " (". translate('ID'). "=" . $monitor->Id() . ")"; ?> - -
-

- - - - - - - - - - -

-
- : Replay - : +
+
+ Name()) . " (". translate('ID'). "=" . $monitor->Id() . ")"; ?> + +
+

+ + + + + + + + + + +

+
+ : Replay + : 'rateValue')); + #rates are defined in skins/classic/includes/config.php + echo htmlSelect('rate', $rates, intval($rate), array('id'=>'rateValue')); ?> - - : - : 1x + + + : + : 1x - : + : -
+
+