Fix: Watch Together Raum-Erstellung + Download-Button

- Server/Frontend Protokoll-Mismatch behoben (create_room, join_room, room_created, room_joined, playback_state)
- togglePlay sendet jetzt korrekt pause/resume statt toggle_play
- Download-Button: SPA-Fallback fuer /downloads/ verhindert, 404 statt Reload
- download-Attribut am Link hinzugefuegt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-07 02:48:43 +01:00
parent 73f247ada3
commit e748fc97e9
6 changed files with 74 additions and 61 deletions

File diff suppressed because one or more lines are too long

2
web/dist/index.html vendored
View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Gaming Hub</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎮</text></svg>" />
<script type="module" crossorigin src="/assets/index-ZMOZU_VE.js"></script>
<script type="module" crossorigin src="/assets/index-CgrjD6IO.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C2eno-Si.css">
</head>
<body>

View file

@ -134,6 +134,7 @@ export default function App() {
<a
className="hub-download-btn"
href="/downloads/GamingHub-Setup.exe"
download
title="Desktop App herunterladen"
>
{'\u2B07\uFE0F'}

View file

@ -263,35 +263,38 @@ export default function WatchTogetherTab({ data }: { data: any }) {
if (msg.rooms) setRooms(msg.rooms);
break;
case 'room_created':
case 'room_created': {
const r = msg.room;
setCurrentRoom({
id: msg.roomId,
name: msg.name,
hostId: msg.hostId,
members: msg.members || [],
currentVideo: null,
playing: false,
currentTime: 0,
queue: [],
id: r.id,
name: r.name,
hostId: r.hostId,
members: r.members || [],
currentVideo: r.currentVideo || null,
playing: r.playing || false,
currentTime: r.currentTime || 0,
queue: r.queue || [],
});
break;
}
case 'room_joined':
case 'room_joined': {
const r = msg.room;
setCurrentRoom({
id: msg.roomId,
name: msg.name,
hostId: msg.hostId,
members: msg.members || [],
currentVideo: msg.currentVideo || null,
playing: msg.playing || false,
currentTime: msg.currentTime || 0,
queue: msg.queue || [],
id: r.id,
name: r.name,
hostId: r.hostId,
members: r.members || [],
currentVideo: r.currentVideo || null,
playing: r.playing || false,
currentTime: r.currentTime || 0,
queue: r.queue || [],
});
// Load video if one is playing
if (msg.currentVideo?.url) {
setTimeout(() => loadVideo(msg.currentVideo.url), 100);
if (r.currentVideo?.url) {
setTimeout(() => loadVideo(r.currentVideo.url), 100);
}
break;
}
case 'playback_state': {
const room = currentRoomRef.current;
@ -402,8 +405,8 @@ export default function WatchTogetherTab({ data }: { data: any }) {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsSend({
type: 'create_room',
name: userName.trim(),
roomName: roomName.trim(),
name: roomName.trim(),
userName: userName.trim(),
password: roomPassword.trim() || undefined,
});
} else {
@ -423,7 +426,7 @@ export default function WatchTogetherTab({ data }: { data: any }) {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsSend({
type: 'join_room',
name: userName.trim(),
userName: userName.trim(),
roomId,
password: password?.trim() || undefined,
});
@ -458,7 +461,9 @@ export default function WatchTogetherTab({ data }: { data: any }) {
// ── Playback controls (host only) ──
const togglePlay = useCallback(() => {
wsSend({ type: 'toggle_play' });
const room = currentRoomRef.current;
if (!room) return;
wsSend({ type: room.playing ? 'pause' : 'resume' });
}, [wsSend]);
const skip = useCallback(() => {