diff --git a/frontend/src/routes/admin.tsx b/frontend/src/routes/admin.tsx index 7dc7e36..aac7b4e 100644 --- a/frontend/src/routes/admin.tsx +++ b/frontend/src/routes/admin.tsx @@ -179,10 +179,6 @@ function QRPanel({ } >
- - Waiting for {result.voterName} to scan the QR code… - - {/* QR code — white background ensures readability regardless of theme */}
( null, ); - // Ref so the SSE closure always reads the current qrInfo without re-subscribing. - const qrInfoRef = useRef(qrInfo); const [loadError, setLoadError] = useState(null); - useEffect(() => { - qrInfoRef.current = qrInfo; - }, [qrInfo]); - const reloadVoters = useCallback(async () => { try { const list = await fetchVoterList(); @@ -1050,13 +1040,9 @@ function Admin() { withCredentials: true, }); es.onmessage = (e) => { - const raw = (e.data as string).replace(/^"|"$/g, ""); - if (raw === "Ready") { - const name = qrInfoRef.current?.voterName ?? null; - setQrInfo(null); - setJoinedVoterName(name); - reloadVoters(); - } + const name = e.data as string; + setJoinedVoterName(name); + reloadVoters(); }; es.onerror = () => console.warn("invite-watch SSE disconnected"); return () => es.close(); @@ -1283,7 +1269,7 @@ function Admin() {
- {joinedVoterName && !qrInfo && ( + {joinedVoterName && ( , fn(bool) -> Option>>>; + Sse>, fn(Option) -> Option>>>; async fn route(request: Self::Request) -> Result { let InviteWatchRequest { @@ -36,12 +36,8 @@ impl APIHandler for InviteWatch { state: State(state), } = request; - let upon_event = |new_state| { - if new_state { - Some(Ok::(Event::default().data("Ready"))) - } else { - Some(Ok::(Event::default().data("Wait"))) - } + let upon_event = |new_state: Option| { + new_state.map(|name| Ok::(Event::default().data(name))) }; let meeting = state.get_meeting(auth.muuid).await?; diff --git a/rustsystem-server/src/api/host/start_invite.rs b/rustsystem-server/src/api/host/start_invite.rs index 441192d..dbc3901 100644 --- a/rustsystem-server/src/api/host/start_invite.rs +++ b/rustsystem-server/src/api/host/start_invite.rs @@ -33,8 +33,7 @@ impl APIHandler for StartInvite { state: State(state), } = request; - let meeting = state.get_meeting(auth.muuid).await?; - meeting.invite_auth.write().await.set_state(true); + state.get_meeting(auth.muuid).await?; info!(muuid = %auth.muuid, "Invite watch opened"); diff --git a/rustsystem-server/src/api/login.rs b/rustsystem-server/src/api/login.rs index 0edbaca..b5effae 100644 --- a/rustsystem-server/src/api/login.rs +++ b/rustsystem-server/src/api/login.rs @@ -60,8 +60,8 @@ impl APIHandler for Login { voter.name.clone() }; // voters write guard released - // Signal the invite watcher. - meeting.invite_auth.write().await.set_state(true); + // Signal the invite watcher with the voter's name. + meeting.invite_auth.write().await.notify_login(voter_name.clone()); // Validate optional admin credentials. let is_host = if let Some(admin_cred) = body.admin_cred { diff --git a/rustsystem-server/src/invite_auth.rs b/rustsystem-server/src/invite_auth.rs index 86a5c36..e1fb62f 100644 --- a/rustsystem-server/src/invite_auth.rs +++ b/rustsystem-server/src/invite_auth.rs @@ -2,22 +2,22 @@ use tokio::sync::watch::{Receiver, Sender}; use tracing::error; pub struct InviteAuthority { - state_tx: Sender, + state_tx: Sender>, } impl InviteAuthority { pub fn new() -> Self { Self { - state_tx: Sender::new(false), + state_tx: Sender::new(None), } } - pub fn set_state(&mut self, new_state: bool) { - if let Err(e) = self.state_tx.send(new_state) { + pub fn notify_login(&mut self, voter_name: String) { + if let Err(e) = self.state_tx.send(Some(voter_name)) { error!("{e}"); } } - pub fn new_watcher(&self) -> Receiver { + pub fn new_watcher(&self) -> Receiver> { self.state_tx.subscribe() } }