Skip to content

Commit d4f6797

Browse files
committed
feat: share grid layout preference across all live view modes
Replace per-view localStorage keys (lightnvr-webrtc-cols/rows and lightnvr-hls-cols/rows) with a single shared key pair: lightnvr-live-cols / lightnvr-live-rows Both WebRTCView and LiveView (HLS/MSE) now: - Read from the shared key first, then fall back to their old per-view key (migration path for existing user preferences) - Write only to the shared key on every layout change - Remove their old per-view keys on write so future reads don't fall back to stale values Result: changing the grid layout on any live view page (WebRTC, HLS, or MSE) is immediately reflected when switching to any of the other views.
1 parent e40b9a3 commit d4f6797

2 files changed

Lines changed: 38 additions & 16 deletions

File tree

web/js/components/preact/LiveView.jsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,26 @@ export function LiveView({isWebRTCDisabled}) {
8383
return urlParams.get('mode') === 'mse';
8484
});
8585

86-
// Initialize cols/rows from URL params, localStorage, or legacy layout key.
86+
// Initialize cols/rows from URL params, shared localStorage key, or legacy per-view keys.
87+
// All live views (WebRTC / HLS / MSE) share 'lightnvr-live-cols' / 'lightnvr-live-rows'
88+
// so a layout change on one page carries over to the others.
8789
// autoGrid stays true when no preference exists — streams-load effect will
8890
// auto-size the grid to fit the available camera count.
8991
const [autoGrid, setAutoGrid] = useState(() => {
9092
const p = new URLSearchParams(window.location.search);
91-
return p.get('cols') === null && localStorage.getItem('lightnvr-hls-cols') === null
93+
return p.get('cols') === null
94+
&& localStorage.getItem('lightnvr-live-cols') === null
95+
&& localStorage.getItem('lightnvr-hls-cols') === null
9296
&& localStorage.getItem('lightnvr-hls-layout') === null;
9397
});
9498
const [cols, setCols] = useState(() => {
9599
const urlParams = new URLSearchParams(window.location.search);
96100
const cp = urlParams.get('cols');
97101
if (cp) return Math.max(1, Math.min(9, parseInt(cp, 10) || 2));
98-
const stored = localStorage.getItem('lightnvr-hls-cols');
99-
if (stored) return Math.max(1, Math.min(9, parseInt(stored, 10) || 2));
102+
const shared = localStorage.getItem('lightnvr-live-cols');
103+
if (shared) return Math.max(1, Math.min(9, parseInt(shared, 10) || 2));
104+
const legacy = localStorage.getItem('lightnvr-hls-cols');
105+
if (legacy) return Math.max(1, Math.min(9, parseInt(legacy, 10) || 2));
100106
const oldLayout = localStorage.getItem('lightnvr-hls-layout');
101107
if (oldLayout) return legacyLayoutToColsRowsHLS(oldLayout)[0];
102108
return 2; // placeholder until autoGrid resolves
@@ -105,8 +111,10 @@ export function LiveView({isWebRTCDisabled}) {
105111
const urlParams = new URLSearchParams(window.location.search);
106112
const rp = urlParams.get('rows');
107113
if (rp) return Math.max(1, Math.min(9, parseInt(rp, 10) || 2));
108-
const stored = localStorage.getItem('lightnvr-hls-rows');
109-
if (stored) return Math.max(1, Math.min(9, parseInt(stored, 10) || 2));
114+
const shared = localStorage.getItem('lightnvr-live-rows');
115+
if (shared) return Math.max(1, Math.min(9, parseInt(shared, 10) || 2));
116+
const legacy = localStorage.getItem('lightnvr-hls-rows');
117+
if (legacy) return Math.max(1, Math.min(9, parseInt(legacy, 10) || 2));
110118
const oldLayout = localStorage.getItem('lightnvr-hls-layout');
111119
if (oldLayout) return legacyLayoutToColsRowsHLS(oldLayout)[1];
112120
return 2; // placeholder until autoGrid resolves
@@ -331,8 +339,11 @@ export function LiveView({isWebRTCDisabled}) {
331339
// Persist to storage
332340
if (currentPage > 0) sessionStorage.setItem('hls_current_page', (currentPage + 1).toString());
333341
else sessionStorage.removeItem('hls_current_page');
334-
localStorage.setItem('lightnvr-hls-cols', String(cols));
335-
localStorage.setItem('lightnvr-hls-rows', String(rows));
342+
localStorage.setItem('lightnvr-live-cols', String(cols));
343+
localStorage.setItem('lightnvr-live-rows', String(rows));
344+
// Clean up old per-view keys so reads don't fall back to stale values
345+
localStorage.removeItem('lightnvr-hls-cols');
346+
localStorage.removeItem('lightnvr-hls-rows');
336347
localStorage.removeItem('lightnvr-hls-layout');
337348
if (isSingleStream && selectedStream) sessionStorage.setItem('hls_selected_stream', selectedStream);
338349
else sessionStorage.removeItem('hls_selected_stream');

web/js/components/preact/WebRTCView.jsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,26 @@ export function WebRTCView() {
7777
// State for go2rtc availability (to show MSE View button)
7878
const [go2rtcAvailable, setGo2rtcAvailable] = useState(false);
7979

80-
// Initialize cols/rows from URL params, localStorage, or legacy layout key.
80+
// Initialize cols/rows from URL params, shared localStorage key, or legacy per-view keys.
81+
// All live views (WebRTC / HLS / MSE) share 'lightnvr-live-cols' / 'lightnvr-live-rows'
82+
// so a layout change on one page carries over to the others.
8183
// autoGrid stays true when no preference exists — streams-load effect will
8284
// auto-size the grid to fit the available camera count.
8385
const [autoGrid, setAutoGrid] = useState(() => {
8486
const p = new URLSearchParams(window.location.search);
85-
return p.get('cols') === null && localStorage.getItem('lightnvr-webrtc-cols') === null
87+
return p.get('cols') === null
88+
&& localStorage.getItem('lightnvr-live-cols') === null
89+
&& localStorage.getItem('lightnvr-webrtc-cols') === null
8690
&& localStorage.getItem('lightnvr-webrtc-layout') === null;
8791
});
8892
const [cols, setCols] = useState(() => {
8993
const urlParams = new URLSearchParams(window.location.search);
9094
const cp = urlParams.get('cols');
9195
if (cp) return Math.max(1, Math.min(9, parseInt(cp, 10) || 2));
92-
const stored = localStorage.getItem('lightnvr-webrtc-cols');
93-
if (stored) return Math.max(1, Math.min(9, parseInt(stored, 10) || 2));
96+
const shared = localStorage.getItem('lightnvr-live-cols');
97+
if (shared) return Math.max(1, Math.min(9, parseInt(shared, 10) || 2));
98+
const legacy = localStorage.getItem('lightnvr-webrtc-cols');
99+
if (legacy) return Math.max(1, Math.min(9, parseInt(legacy, 10) || 2));
94100
const oldLayout = localStorage.getItem('lightnvr-webrtc-layout');
95101
if (oldLayout) return legacyLayoutToColsRowsWebRTC(oldLayout)[0];
96102
return 2; // placeholder until autoGrid resolves
@@ -99,8 +105,10 @@ export function WebRTCView() {
99105
const urlParams = new URLSearchParams(window.location.search);
100106
const rp = urlParams.get('rows');
101107
if (rp) return Math.max(1, Math.min(9, parseInt(rp, 10) || 2));
102-
const stored = localStorage.getItem('lightnvr-webrtc-rows');
103-
if (stored) return Math.max(1, Math.min(9, parseInt(stored, 10) || 2));
108+
const shared = localStorage.getItem('lightnvr-live-rows');
109+
if (shared) return Math.max(1, Math.min(9, parseInt(shared, 10) || 2));
110+
const legacy = localStorage.getItem('lightnvr-webrtc-rows');
111+
if (legacy) return Math.max(1, Math.min(9, parseInt(legacy, 10) || 2));
104112
const oldLayout = localStorage.getItem('lightnvr-webrtc-layout');
105113
if (oldLayout) return legacyLayoutToColsRowsWebRTC(oldLayout)[1];
106114
return 2; // placeholder until autoGrid resolves
@@ -262,8 +270,11 @@ export function WebRTCView() {
262270
// Persist to storage
263271
if (currentPage > 0) sessionStorage.setItem('webrtc_current_page', (currentPage + 1).toString());
264272
else sessionStorage.removeItem('webrtc_current_page');
265-
localStorage.setItem('lightnvr-webrtc-cols', String(cols));
266-
localStorage.setItem('lightnvr-webrtc-rows', String(rows));
273+
localStorage.setItem('lightnvr-live-cols', String(cols));
274+
localStorage.setItem('lightnvr-live-rows', String(rows));
275+
// Clean up old per-view keys so reads don't fall back to stale values
276+
localStorage.removeItem('lightnvr-webrtc-cols');
277+
localStorage.removeItem('lightnvr-webrtc-rows');
267278
localStorage.removeItem('lightnvr-webrtc-layout');
268279
if (isSingleStream && selectedStream) sessionStorage.setItem('webrtc_selected_stream', selectedStream);
269280
else sessionStorage.removeItem('webrtc_selected_stream');

0 commit comments

Comments
 (0)