/** * ConnectDialog — name + role picker to join a session */ import { Component, createSignal, onMount, Show } from "solid-js"; import { connectStream, hydrateFromServer, useJournalStream, setMyName, setMyRole, setSessionId, } from "../stores/journalStream"; export const ConnectDialog: Component = () => { const stream = useJournalStream(); const [playerName, setPlayerName] = createSignal(stream.myName); const [role, setRole] = createSignal<"gm" | "player" | "observer">( stream.myRole, ); const [connecting, setConnecting] = createSignal(false); const [error, setError] = createSignal(null); const [autoJoined, setAutoJoined] = createSignal(false); // Auto-join when URL has both session and player params onMount(() => { const params = new URL(window.location.href).searchParams; if ( params.has("session") && params.has("player") && params.has("autojoin") ) { setPlayerName(params.get("player") || ""); setRole("player"); setAutoJoined(true); handleConnect(); } }); const handleConnect = async () => { const name = playerName().trim() || stream.myName; if (!name) return; // In dev, the MQTT broker lives on the CLI server (port 3000), not the // rsbuild dev server. In production, the CLI serves everything itself. const brokerUrl = process.env.NODE_ENV === "development" ? `ws://localhost:3000` : `ws://${window.location.host}`; setConnecting(true); setError(null); try { setMyName(name); setMyRole(role()); const sessionId = stream.sessionId || "default"; setSessionId(sessionId); await hydrateFromServer(sessionId); await connectStream(sessionId, brokerUrl); } catch (e) { const msg = e instanceof Error ? e.message : "Connection failed"; setError(msg); } finally { setConnecting(false); } }; return ( {connecting() ? "正在加入会话…" : "已加入!"}

} >

请输入你的名字和角色来加入会话。
连接到 {window.location.host}

setPlayerName(e.currentTarget.value)} onKeyDown={(e) => e.key === "Enter" && handleConnect()} placeholder="你的名字" class="w-full border border-gray-300 rounded px-3 py-1.5 text-sm" autofocus /> {/* Role selector */}
{(["gm", "player", "observer"] as const).map((r) => ( ))}

{error()}

); };