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:
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
2
web/dist/index.html
vendored
|
|
@ -5,7 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Gaming Hub</title>
|
<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>" />
|
<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">
|
<link rel="stylesheet" crossorigin href="/assets/index-DKX7sma7.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ export default function App() {
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then((list: PluginInfo[]) => {
|
.then((list: PluginInfo[]) => {
|
||||||
setPlugins(list);
|
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 saved = localStorage.getItem('hub_activeTab');
|
||||||
const valid = list.some(p => p.name === saved);
|
const valid = list.some(p => p.name === saved);
|
||||||
if (list.length > 0 && !valid) setActiveTab(list[0].name);
|
if (list.length > 0 && !valid) setActiveTab(list[0].name);
|
||||||
|
|
|
||||||
|
|
@ -441,28 +441,31 @@ export default function StreamingTab({ data }: { data: any }) {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// ── Auto-join from URL ?viewStream=... ──
|
// ── Auto-join from URL ?viewStream=... ──
|
||||||
|
const pendingViewStreamRef = useRef<string | null>(null);
|
||||||
|
|
||||||
|
// On mount: grab the streamId from URL and clear it
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const streamId = params.get('viewStream');
|
const streamId = params.get('viewStream');
|
||||||
if (!streamId) return;
|
if (streamId) {
|
||||||
// Clean up URL
|
pendingViewStreamRef.current = streamId;
|
||||||
const url = new URL(location.href);
|
const url = new URL(location.href);
|
||||||
url.searchParams.delete('viewStream');
|
url.searchParams.delete('viewStream');
|
||||||
window.history.replaceState({}, '', url.toString());
|
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);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 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 ──
|
// ── Helpers for 3-dot menu ──
|
||||||
const buildStreamLink = useCallback((streamId: string) => {
|
const buildStreamLink = useCallback((streamId: string) => {
|
||||||
const url = new URL(location.href);
|
const url = new URL(location.href);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue