Merge pull request 'Style/adjust receiver page' (#42) from style/adjust-receiver-page into main
Deploy Next.js via Docker / deploy (push) Successful in 1m11s
Deploy Next.js via Docker / deploy (push) Successful in 1m11s
Reviewed-on: #42
This commit was merged in pull request #42.
This commit is contained in:
+111
-16
@@ -3,11 +3,65 @@
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function SenderPage() {
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
|
||||
const [songID, setSongID] = useState("");
|
||||
const [songbook, setSongbook] = useState("");
|
||||
const [number, setNumber] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
|
||||
// --- Screen Wake Lock API Integration ---
|
||||
useEffect(() => {
|
||||
let wakeLock: WakeLockSentinel | null = null;
|
||||
|
||||
const requestWakeLock = async () => {
|
||||
try {
|
||||
if ("wakeLock" in navigator) {
|
||||
wakeLock = await navigator.wakeLock.request("screen");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Wake Lock Fehler:", err);
|
||||
}
|
||||
};
|
||||
|
||||
requestWakeLock();
|
||||
|
||||
// Erneutes Anfordern, falls der Tab/die App gewechselt wurde
|
||||
const handleVisibilityChange = () => {
|
||||
if (document.visibilityState === "visible") {
|
||||
requestWakeLock();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
if (wakeLock) {
|
||||
wakeLock.release();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// --- Fullscreen Steuerung ---
|
||||
const toggleFullscreen = () => {
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement
|
||||
.requestFullscreen()
|
||||
.then(() => {
|
||||
setIsFullscreen(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Vollbild fehlgeschlagen:", err);
|
||||
});
|
||||
} else {
|
||||
document.exitFullscreen().then(() => {
|
||||
setIsFullscreen(false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// --- Daten abrufen ---
|
||||
const getID = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/stream/currentID");
|
||||
@@ -28,22 +82,63 @@ export default function SenderPage() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-screen flex-col items-center justify-between bg-black text-white font-sans select-none overflow-hidden">
|
||||
<div className="w-full text-center py-2">
|
||||
<span className="text-[7rem] md:text-[11rem] font-black uppercase block leading-none">
|
||||
{songbook}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 flex items-center justify-center w-full">
|
||||
<h1 className="text-[14rem] md:text-[20rem] font-black leading-none tracking-tighter text-white">
|
||||
{number}
|
||||
</h1>
|
||||
</div>
|
||||
<div className="w-full text-center pb-2 px-4">
|
||||
<p className="text-3xl md:text-6xl font-medium text-neutral-400 truncate">
|
||||
{title}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={`absolute top-0 left-0 z-50 flex h-screen w-screen flex-col items-center justify-between bg-black text-white select-none overflow-hidden p-2`}
|
||||
>
|
||||
{/* 1. Liederbuch */}
|
||||
<header className="w-full flex-[1.5] flex items-center justify-center overflow-hidden py-1">
|
||||
<svg viewBox="0 0 1000 200" className="w-full h-full max-h-full">
|
||||
<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
dominantBaseline="central"
|
||||
textAnchor="middle"
|
||||
className="fill-amber-300 font-black uppercase"
|
||||
fontSize="220"
|
||||
>
|
||||
{songbook}
|
||||
</text>
|
||||
</svg>
|
||||
</header>
|
||||
|
||||
{/* 2. Nummer */}
|
||||
<main className="w-full flex-[5] flex items-center justify-center overflow-hidden py-1">
|
||||
<svg viewBox="0 0 1000 500" className="w-full h-full max-h-full">
|
||||
<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
dominantBaseline="central"
|
||||
textAnchor="middle"
|
||||
className="fill-white font-black"
|
||||
fontSize="520"
|
||||
>
|
||||
{number}
|
||||
</text>
|
||||
</svg>
|
||||
</main>
|
||||
|
||||
{/* 3. Titel */}
|
||||
<footer className="w-full flex-[1] flex items-center justify-center overflow-hidden py-1">
|
||||
<svg viewBox="0 0 1000 120" className="w-full h-full max-h-full">
|
||||
<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
dominantBaseline="central"
|
||||
textAnchor="middle"
|
||||
className="fill-zinc-200 font-semibold"
|
||||
fontSize="90"
|
||||
>
|
||||
{title}
|
||||
</text>
|
||||
</svg>
|
||||
</footer>
|
||||
|
||||
<button
|
||||
onClick={toggleFullscreen}
|
||||
className="fixed top-4 right-4 z-50 bg-neutral-800 hover:bg-neutral-700 text-white px-4 py-2 rounded-lg opacity-40 hover:opacity-100 transition-opacity"
|
||||
>
|
||||
{isFullscreen ? "Vollbild beenden" : "Vollbild starten"}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user