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>
This commit is contained in:
Daniel 2026-03-07 02:07:49 +01:00
parent 470bef62e4
commit 59ebfc91a9
4 changed files with 82 additions and 73 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-iGsoo-U1.js"></script>
<script type="module" crossorigin src="/assets/index-ypgJpUy0.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DKX7sma7.css">
</head>
<body>

View file

@ -40,6 +40,12 @@ export default function App() {
.then(r => r.json())
.then((list: PluginInfo[]) => {
setPlugins(list);
// If ?viewStream= is in URL, force switch to streaming tab
const urlParams = new URLSearchParams(location.search);
if (urlParams.has('viewStream') && list.some(p => p.name === 'streaming')) {
setActiveTab('streaming');
return;
}
const saved = localStorage.getItem('hub_activeTab');
const valid = list.some(p => p.name === saved);
if (list.length > 0 && !valid) setActiveTab(list[0].name);

View file

@ -441,28 +441,31 @@ export default function StreamingTab({ data }: { data: any }) {
}, []);
// ── Auto-join from URL ?viewStream=... ──
const pendingViewStreamRef = useRef<string | null>(null);
// On mount: grab the streamId from URL and clear it
useEffect(() => {
const params = new URLSearchParams(location.search);
const streamId = params.get('viewStream');
if (!streamId) return;
// Clean up URL
const url = new URL(location.href);
url.searchParams.delete('viewStream');
window.history.replaceState({}, '', url.toString());
// Wait for streams to load, then open join modal
const tryOpen = () => {
const s = streams.find(st => st.id === streamId);
if (s) { openJoinModal(s); return; }
// Retry a few times (stream list may not be loaded yet)
let tries = 0;
const iv = setInterval(() => {
tries++;
if (tries > 20) { clearInterval(iv); return; }
}, 500);
};
setTimeout(tryOpen, 500);
if (streamId) {
pendingViewStreamRef.current = streamId;
const url = new URL(location.href);
url.searchParams.delete('viewStream');
window.history.replaceState({}, '', url.toString());
}
}, []);
// When streams update, check if we have a pending auto-join
useEffect(() => {
const pending = pendingViewStreamRef.current;
if (!pending || streams.length === 0) return;
const s = streams.find(st => st.id === pending);
if (s) {
pendingViewStreamRef.current = null;
openJoinModal(s);
}
}, [streams, openJoinModal]);
// ── Helpers for 3-dot menu ──
const buildStreamLink = useCallback((streamId: string) => {
const url = new URL(location.href);