From f65547870e58e48836ed779dba292295c99b3888 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Wed, 13 May 2026 11:10:52 +0200 Subject: [PATCH] show user name --- api/src/routes/device-socket.ts | 23 +++++++++++++++++++---- dev-proxy/index.ts | 4 ++-- device-state/src/lib.rs | 32 +++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/api/src/routes/device-socket.ts b/api/src/routes/device-socket.ts index b4dfb93..1d2cbe9 100644 --- a/api/src/routes/device-socket.ts +++ b/api/src/routes/device-socket.ts @@ -17,7 +17,7 @@ type DeviceSocketMessage = type DeviceProxyEvent = | PartySocketEvent | { type: "device_connect_required" } - | { type: "device_connected" }; + | { type: "device_connected"; username: string }; type DeviceQuizResponsePayload = { QuizResponse: number; @@ -125,12 +125,24 @@ async function syncDeviceConnectionStatus(deviceId: string) { return; } - console.log("[device-socket] device claimed", deviceId, device.userId); + const userRecord = await db.query.user.findFirst({ + where: { id: device.userId }, + }); + const username = userRecord?.name ?? device.userId; + console.log( + "[device-socket] device claimed", + deviceId, + device.userId, + username, + ); await db .update(deviceConnection) .set({ lastSeen: new Date() }) .where(eq(deviceConnection.id, deviceId)); - sendDeviceEvent(deviceId, { type: "device_connected" }); + sendDeviceEvent(deviceId, { + type: "device_connected", + username, + }); } export async function claimDeviceForUser(deviceId: string, userId: string) { @@ -296,7 +308,10 @@ export const deviceClaimApp = new Elysia() "/:deviceId/connect", async ({ user, params }) => { await claimDeviceForUser(params.deviceId, user.id); - sendDeviceEvent(params.deviceId, { type: "device_connected" }); + sendDeviceEvent(params.deviceId, { + type: "device_connected", + username: user.name, + }); return { ok: true, deviceId: params.deviceId, userId: user.id }; }, { auth: true }, diff --git a/dev-proxy/index.ts b/dev-proxy/index.ts index 9ed2f0c..3402c5e 100644 --- a/dev-proxy/index.ts +++ b/dev-proxy/index.ts @@ -66,7 +66,7 @@ type ErrorEvent = { type DeviceLifecycleEvent = | { type: "device_connect_required" } - | { type: "device_connected" }; + | { type: "device_connected"; username: string }; type PartySocketEvent = | PartyStatusEvent @@ -262,7 +262,7 @@ function handleApiMessage(e: MessageEvent) { if (event.type === "device_connected") { console.log("Writing waiting-for-party", message.deviceId); - writeProxyOutput(socket, "WaitingForParty"); + writeProxyOutput(socket, { WaitingForParty: event.username }); return; } diff --git a/device-state/src/lib.rs b/device-state/src/lib.rs index 2ad276d..0b5f5f3 100644 --- a/device-state/src/lib.rs +++ b/device-state/src/lib.rs @@ -48,7 +48,7 @@ pub struct QuestionDataNet<'a> { #[derive(Deserialize)] pub enum ProxyOutput<'a> { ConnectPrompt(&'a str), - WaitingForParty, + WaitingForParty(&'a str), Question(QuestionDataNet<'a>), Results, Error(&'a str), @@ -87,6 +87,7 @@ impl WheelData { pub struct DeviceState { view: ViewState, device_id: Option>, + connected_user_name: Option>, question: Option, wheel: WheelData, last_index: usize, @@ -98,6 +99,7 @@ impl DeviceState { Self { view: ViewState::Loading, device_id: None, + connected_user_name: None, question: None, wheel: WheelData::empty(), last_index: 0, @@ -107,6 +109,7 @@ impl DeviceState { pub fn reset(&mut self) { self.view = ViewState::Loading; + self.connected_user_name = None; self.question = None; self.wheel = WheelData::empty(); self.last_index = 0; @@ -114,6 +117,7 @@ impl DeviceState { } pub fn reconnecting(&mut self) { + self.connected_user_name = None; self.question = None; self.wheel = WheelData::empty(); self.view = ViewState::Reconnecting; @@ -144,7 +148,14 @@ impl DeviceState { self.question = None; self.view = ViewState::ConnectPrompt; } - ProxyOutput::WaitingForParty => { + ProxyOutput::WaitingForParty(user_name) => { + let mut owned_user_name = OwnedStr::new(); + for char in user_name.chars() { + if owned_user_name.try_push(char).is_err() { + break; + } + } + self.connected_user_name = Some(owned_user_name); self.question = None; self.view = ViewState::WaitingForParty; } @@ -215,9 +226,16 @@ impl DeviceState { } if self.view == ViewState::WaitingForParty { + let user_name = self.connected_user_name.as_ref()?; + let mut display_name: OwnedStr<16> = OwnedStr::new(); + for char in user_name.as_str().chars() { + if display_name.try_push(char).is_err() { + break; + } + } return Some(( - OwnedStr::from_str("Connected").unwrap(), - OwnedStr::from_str("Waiting party").unwrap(), + display_name, + OwnedStr::from_str("Awaiting party").unwrap(), )); } @@ -409,15 +427,15 @@ mod tests { #[test] fn parses_and_renders_waiting_for_party() { - let data = parse_proxy_output(r#""WaitingForParty""#).unwrap(); + let data = parse_proxy_output(r#"{"WaitingForParty":"User"}"#).unwrap(); let mut state = DeviceState::new(); state.apply_proxy_output(data); assert_eq!(state.view_state(), ViewState::WaitingForParty); let (line1, line2) = state.render_lines().unwrap(); - assert_eq!(line1.as_str(), "Connected"); - assert_eq!(line2.as_str(), "Waiting party"); + assert_eq!(line1.as_str(), "User"); + assert_eq!(line2.as_str(), "Awaiting party"); } #[test]