babycam/app/templates/live.html

215 lines
5.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Babycam Live</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
background: #000;
overflow: hidden;
}
#stream {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
#no-cam {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #444;
font-family: -apple-system, sans-serif;
gap: 0.5rem;
}
#no-cam span { font-size: 3rem; }
#no-cam p { font-size: 0.9rem; }
/* Overlay erscheint bei Tap/Hover */
#overlay {
position: absolute;
inset: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 30%, transparent 70%, rgba(0,0,0,0.5) 100%);
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
body.show-ui #overlay { opacity: 1; }
#top-bar {
position: absolute;
top: 0; left: 0; right: 0;
padding: 1rem 1.25rem;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
font-family: -apple-system, sans-serif;
}
#top-bar .title {
font-size: 1rem;
font-weight: 600;
display: flex;
align-items: center;
gap: 0.5rem;
}
#top-bar .dot {
width: 8px; height: 8px;
border-radius: 50%;
background: #f44336;
animation: pulse 1.5s infinite;
}
{% if status.cam_available %}
#top-bar .dot { background: #4caf50; animation: none; }
{% endif %}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
#bottom-bar {
position: absolute;
bottom: 0; left: 0; right: 0;
padding: 1rem 1.25rem;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
font-family: -apple-system, sans-serif;
font-size: 0.85rem;
}
#clock { font-size: 1.1rem; font-weight: 500; letter-spacing: 0.05em; }
.btn {
background: rgba(255,255,255,0.15);
backdrop-filter: blur(8px);
border: none;
color: #fff;
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.85rem;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.4rem;
}
.btn:hover { background: rgba(255,255,255,0.25); }
/* Fullscreen-Button */
#fs-btn {
position: absolute;
top: 1rem; right: 1.25rem;
pointer-events: all;
}
/* Alles außer fs-btn nur bei show-ui anzeigen */
#top-bar .title,
#bottom-bar {
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
body.show-ui #top-bar .title,
body.show-ui #bottom-bar {
opacity: 1;
pointer-events: all;
}
body.show-ui #fs-btn { opacity: 1; }
#fs-btn { opacity: 0; transition: opacity 0.3s; pointer-events: all; }
body.show-ui #fs-btn { opacity: 1; }
</style>
</head>
<body>
{% if status.cam_available %}
<img id="stream" src="/stream" alt="Babycam Live-Stream">
{% else %}
<div id="no-cam">
<span>📷</span>
<p>Kamera nicht verbunden</p>
</div>
{% endif %}
<div id="overlay"></div>
<div id="top-bar">
<div class="title">
<div class="dot"></div>
Babycam Live
</div>
<button class="btn" id="fs-btn" onclick="toggleFullscreen()">⛶ Vollbild</button>
</div>
<div id="bottom-bar">
<div id="clock"></div>
<a class="btn" href="/">⚙ Einstellungen</a>
</div>
<script>
// UI bei Tap/Klick kurz einblenden
let hideTimer;
function showUI() {
document.body.classList.add("show-ui");
clearTimeout(hideTimer);
hideTimer = setTimeout(() => document.body.classList.remove("show-ui"), 3000);
}
document.body.addEventListener("click", showUI);
document.body.addEventListener("touchstart", showUI, { passive: true });
// Uhr
function updateClock() {
const now = new Date();
const h = String(now.getHours()).padStart(2, "0");
const m = String(now.getMinutes()).padStart(2, "0");
const s = String(now.getSeconds()).padStart(2, "0");
document.getElementById("clock").textContent = `${h}:${m}:${s}`;
}
updateClock();
setInterval(updateClock, 1000);
// Fullscreen
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(() => {});
} else {
document.exitFullscreen();
}
}
document.addEventListener("fullscreenchange", () => {
const btn = document.getElementById("fs-btn");
btn.textContent = document.fullscreenElement ? "✕ Vollbild beenden" : "⛶ Vollbild";
});
// Auf Handy: Landscape empfehlen
if (screen.orientation && screen.orientation.lock) {
screen.orientation.lock("landscape").catch(() => {});
}
</script>
</body>
</html>