Commit graph

12 commits

Author SHA1 Message Date
Daniel
e057a61c55 Fix: optional chaining für setStreaming (alte Electron App Kompatibilität)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:47:43 +01:00
Daniel
7bebb7db9a Fix: Stream-close-warning via IPC statt async executeJavaScript
- Renderer meldet Streaming-Status synchron per IPC
- main.js prueft Status synchron im close-Handler
- Kein async Race mehr, Dialog erscheint zuverlaessig
2026-03-07 14:14:51 +01:00
Daniel
4943bbf4a1 Streams oeffnen standardmaessig in neuem Fenster mit Passwortabfrage
Klick auf Stream-Tile oeffnet neues Fenster via ?viewStream= URL.
Passwort-Modal erscheint automatisch im neuen Fenster nach dem Laden.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:11:16 +01:00
Daniel
59ebfc91a9 Fix: Auto-Join via ?viewStream= URL-Parameter funktioniert jetzt
App.tsx wechselt automatisch zum Streaming-Tab wenn ?viewStream= in der URL steht.
StreamingTab nutzt ref-basierten Ansatz: Stream-ID wird beim Mount gespeichert,
Passwort-Modal oeffnet sich sobald die Stream-Liste vom Server geladen ist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:07:49 +01:00
Daniel
470bef62e4 Streaming: Stale-Stream Fix, Broadcast+View gleichzeitig, 3-Punkt-Menü
Server:
- Dual-Role: Client kann gleichzeitig broadcasten UND zuschauen
  (broadcastStreamId + viewingStreamId statt single role)
- POST /api/streaming/disconnect Beacon-Endpoint fuer
  zuverlaessigen Cleanup bei Page-Unload
- Heartbeat auf 5s reduziert (schnellere Erkennung)

Frontend:
- pagehide + sendBeacon: Streams werden sofort aufgeraeumt wenn
  Browser geschlossen/neugeladen wird
- ICE Routing: Broadcaster-Map wird zuerst geprueft, dann Viewer-PC
  → Broadcast + View im selben Tab moeglich
- 3-Punkt-Menü mit Stream-Details, "In neuem Fenster oeffnen" und
  "Link teilen" (Clipboard)
- Auto-Join via ?viewStream=... Query-Parameter (fuer geteilte Links)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:56:14 +01:00
Daniel
813e017036 Fix: Umlaut-Darstellung im Zurueck-Button korrigiert
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:45:47 +01:00
Daniel
3ef25fc10a Beforeunload-Warnung + Vollbild-Button fuer Viewer
- beforeunload Event verhindert versehentliches Verlassen/Reload
  waehrend Broadcasting oder Viewing aktiv ist
- Vollbild-Button im Viewer-Header (Fullscreen API)
- Fullscreen-State wird korrekt getrackt und Icon wechselt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:37:21 +01:00
Daniel
2ee36789b2 Stream auf 60 FPS + 8 Mbps Bitrate angehoben
- getDisplayMedia: frameRate ideal 60, 1920x1080
- WebRTC Sender: maxFramerate 60, maxBitrate 8 Mbps pro Viewer-PC

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:34:55 +01:00
Daniel
3f9b446f27 Fix: Schwarzes Bild bei Viewern - WebRTC Race Conditions behoben
- Doppelter Offer entfernt (onnegotiationneeded + explizit createOffer)
- ICE Candidate Queuing: Candidates werden gepuffert bis setRemoteDescription
  fertig ist, statt sie zu verwerfen
- Cleanup bei Re-Offer: vorherige PeerConnection wird sauber geschlossen
- Pending Candidates werden bei Disconnect/Leave aufgeraeumt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:16:09 +01:00
Daniel
4aed4e70ab fix(streaming): reliable disconnect + mandatory stream password
Disconnect:
- Server-side heartbeat ping/pong every 10s with 25s timeout
- Detects and cleans up dead connections (browser closed, network lost)
- ws.terminate() on heartbeat timeout triggers handleDisconnect

Password:
- Stream password is mandatory (server rejects start_broadcast without)
- Password stored server-side, never sent to clients
- Viewers must enter password via modal before joining
- Lock icon on tiles, WRONG_PASSWORD error shown in modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:00:48 +01:00
Daniel
dacfde4328 fix(streaming): resolve stale closure preventing remote WebRTC connections
The WebSocket onmessage handler captured isBroadcasting=false at creation
time. When ICE candidates arrived from remote viewers, the handler looked
up viewerPcRef instead of peerConnectionsRef, dropping all candidates.

Fix: use refs (isBroadcastingRef, viewingRef, handleWsMessageRef) so the
WS handler always reads current state. connectWs() now has [] deps and
delegates to handleWsMessageRef.current for every message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:51:09 +01:00
Daniel
29bcf67121 feat(streaming): add Screen Streaming plugin with WebRTC
New plugin: browser-based screen sharing via Chrome Screen Capture API.
Multi-stream grid layout (Rustdesk-style tiles) with live previews.

- Server: WebSocket signaling at /ws/streaming (SDP/ICE relay)
- Server: http.createServer for WebSocket attachment
- Frontend: StreamingTab with broadcaster/viewer modes
- Frontend: tile grid, fullscreen viewer, LIVE badges
- Supports multiple concurrent streams
- Peer-to-peer video via WebRTC (no video through server)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:39:49 +01:00