fix: clean focus popup — close button bar + fullscreen iframe
This commit is contained in:
parent
c2fb05a9ef
commit
66dd4c54b4
3 changed files with 14 additions and 76 deletions
|
|
@ -93,59 +93,18 @@ function renderLiveGrid() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Focus Overlay ──
|
// ── Focus Overlay ──
|
||||||
let focusIdx = -1;
|
|
||||||
function openFocus(cam) {
|
function openFocus(cam) {
|
||||||
focusIdx = cameras.indexOf(cam);
|
|
||||||
const overlay = document.getElementById('focus-overlay');
|
const overlay = document.getElementById('focus-overlay');
|
||||||
overlay.classList.remove('hidden');
|
overlay.classList.remove('hidden');
|
||||||
// Remove any previous iframe.
|
document.getElementById('focus-frame').src = `http://${location.hostname}:1984/stream.html?src=${cam.id}_sub`;
|
||||||
const oldFrame = overlay.querySelector('iframe.go2rtc');
|
|
||||||
if (oldFrame) oldFrame.remove();
|
|
||||||
// Embed go2rtc player in iframe — PWA-friendly, no new tab.
|
|
||||||
const iframe = document.createElement('iframe');
|
|
||||||
iframe.className = 'go2rtc';
|
|
||||||
iframe.allow = 'autoplay';
|
|
||||||
iframe.src = `http://${location.hostname}:1984/stream.html?src=${cam.id}_sub`;
|
|
||||||
document.getElementById('focus-video').style.display = 'none';
|
|
||||||
overlay.appendChild(iframe);
|
|
||||||
document.getElementById('focus-title').textContent = cam.name;
|
|
||||||
document.getElementById('focus-time').textContent = new Date().toLocaleTimeString() + ' live';
|
|
||||||
renderThumbs();
|
|
||||||
}
|
|
||||||
function updateFocus() {}
|
|
||||||
function updateFocus() {}
|
|
||||||
function renderThumbs() {
|
|
||||||
const strip = document.getElementById('focus-thumbs');
|
|
||||||
strip.innerHTML = '';
|
|
||||||
cameras.forEach((cam, i) => {
|
|
||||||
const thumb = document.createElement('div');
|
|
||||||
thumb.className = 'thumb' + (i === focusIdx ? ' active' : '');
|
|
||||||
thumb.textContent = cam.name;
|
|
||||||
thumb.title = cam.name;
|
|
||||||
thumb.addEventListener('click', () => { focusIdx = i; updateFocus(); renderThumbs(); });
|
|
||||||
strip.appendChild(thumb);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
document.getElementById('focus-close').addEventListener('click', () => {
|
document.getElementById('focus-close').addEventListener('click', () => {
|
||||||
const overlay = document.getElementById('focus-overlay');
|
document.getElementById('focus-overlay').classList.add('hidden');
|
||||||
overlay.classList.add('hidden');
|
document.getElementById('focus-frame').src = '';
|
||||||
const iframe = overlay.querySelector('iframe.go2rtc');
|
|
||||||
if (iframe) iframe.remove();
|
|
||||||
document.getElementById('focus-video').style.display = '';
|
|
||||||
});
|
|
||||||
document.getElementById('focus-prev').addEventListener('click', () => {
|
|
||||||
if (focusIdx > 0) { focusIdx--; openFocus(cameras[focusIdx]); }
|
|
||||||
});
|
|
||||||
document.getElementById('focus-next').addEventListener('click', () => {
|
|
||||||
if (focusIdx < cameras.length - 1) { focusIdx++; openFocus(cameras[focusIdx]); }
|
|
||||||
});
|
});
|
||||||
document.addEventListener('keydown', e => {
|
document.addEventListener('keydown', e => {
|
||||||
if (document.getElementById('focus-overlay').classList.contains('hidden')) return;
|
if (document.getElementById('focus-overlay').classList.contains('hidden')) return;
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') document.getElementById('focus-close').click();
|
||||||
document.getElementById('focus-close').click();
|
|
||||||
}
|
|
||||||
if (e.key === 'ArrowLeft' && focusIdx > 0) { focusIdx--; openFocus(cameras[focusIdx]); }
|
|
||||||
if (e.key === 'ArrowRight' && focusIdx < cameras.length - 1) { focusIdx++; openFocus(cameras[focusIdx]); }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── Playback ──
|
// ── Playback ──
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,10 @@
|
||||||
<section id="tab-live" class="tab-panel active">
|
<section id="tab-live" class="tab-panel active">
|
||||||
<div id="grid" class="grid-4x2"></div>
|
<div id="grid" class="grid-4x2"></div>
|
||||||
<div id="focus-overlay" class="focus-overlay hidden">
|
<div id="focus-overlay" class="focus-overlay hidden">
|
||||||
<div class="focus-toolbar">
|
<div class="focus-bar">
|
||||||
<button id="focus-prev">◀</button>
|
<button id="focus-close">✕ Close</button>
|
||||||
<span id="focus-title">Camera</span>
|
|
||||||
<span id="focus-time" class="focus-time">00:00 live</span>
|
|
||||||
<button id="focus-close">✕</button>
|
|
||||||
<button id="focus-next">▶</button>
|
|
||||||
</div>
|
</div>
|
||||||
<img id="focus-video" alt="Live stream">
|
<iframe id="focus-frame" class="focus-frame" allow="autoplay"></iframe>
|
||||||
<div id="focus-thumbs" class="thumb-strip"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,35 +91,19 @@ body {
|
||||||
background: #000; display: flex; flex-direction: column;
|
background: #000; display: flex; flex-direction: column;
|
||||||
}
|
}
|
||||||
.focus-overlay.hidden { display: none; }
|
.focus-overlay.hidden { display: none; }
|
||||||
.focus-toolbar {
|
.focus-bar {
|
||||||
display: flex; align-items: center; gap: 12px;
|
display: flex; justify-content: flex-end; align-items: center;
|
||||||
padding: 10px 20px; background: rgba(0,0,0,.8);
|
padding: 8px 16px; background: rgba(0,0,0,.85); z-index: 10;
|
||||||
position: absolute; top: 0; left: 0; right: 0; z-index: 10;
|
|
||||||
opacity: 0; transition: opacity .3s;
|
|
||||||
}
|
}
|
||||||
.focus-overlay:hover .focus-toolbar { opacity: 1; }
|
.focus-bar button {
|
||||||
.focus-toolbar button {
|
|
||||||
background: rgba(255,255,255,.15); border: none;
|
background: rgba(255,255,255,.15); border: none;
|
||||||
color: #fff; padding: 8px 14px; border-radius: 6px;
|
color: #fff; padding: 10px 24px; border-radius: 6px;
|
||||||
cursor: pointer; font-size: 16px;
|
cursor: pointer; font-size: 16px;
|
||||||
}
|
}
|
||||||
.focus-toolbar button:hover { background: rgba(255,255,255,.25); }
|
.focus-bar button:hover { background: rgba(255,255,255,.25); }
|
||||||
#focus-title { flex: 1; font-size: 16px; color: #fff; }
|
.focus-frame {
|
||||||
.focus-time { font-size: 13px; color: var(--text-muted); }
|
|
||||||
#focus-video { flex: 1; width: 100%; object-fit: contain; }
|
|
||||||
iframe.go2rtc {
|
|
||||||
flex: 1; width: 100%; border: none;
|
flex: 1; width: 100%; border: none;
|
||||||
position: absolute; inset: 48px 0 0 0;
|
|
||||||
}
|
}
|
||||||
.thumb-strip {
|
|
||||||
display: flex; gap: 4px; padding: 8px;
|
|
||||||
background: rgba(0,0,0,.8); overflow-x: auto;
|
|
||||||
}
|
|
||||||
.thumb-strip .thumb {
|
|
||||||
width: 120px; height: 68px; object-fit: cover;
|
|
||||||
border: 2px solid transparent; border-radius: 4px; cursor: pointer; opacity: .6;
|
|
||||||
}
|
|
||||||
.thumb-strip .thumb:hover, .thumb-strip .thumb.active { opacity: 1; border-color: var(--accent); }
|
|
||||||
|
|
||||||
/* ── Playback ── */
|
/* ── Playback ── */
|
||||||
.playback-controls {
|
.playback-controls {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue