From eb5b7d55a43c18cadc74491e4effd98224471758 Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Thu, 2 Jul 2026 09:39:15 -0400 Subject: [PATCH] fix: TYPING_START events now carry user_id and username The backend was broadcasting TYPING_START with only channel_id. Frontend required user_id + username to show who is typing. Added Username to Client struct, fetched on WS connect via JOIN. Typing events now enriched with sender identity before broadcast. --- internal/gateway/client.go | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/internal/gateway/client.go b/internal/gateway/client.go index 3f71cbc..23c20a9 100644 --- a/internal/gateway/client.go +++ b/internal/gateway/client.go @@ -102,10 +102,11 @@ func extractHostname(s string) string { // Client is a middleman between the websocket connection and the hub. type Client struct { - Hub *Hub - Conn *websocket.Conn - UserID string - send chan []byte + Hub *Hub + Conn *websocket.Conn + UserID string + Username string + send chan []byte } // readPump pumps messages from the websocket connection to the hub. @@ -140,7 +141,19 @@ func (c *Client) readPump() { c.Hub.RecordActivity(c.UserID) switch event.Type { - case EventTypingStart, EventPresenceUpdate: + case EventTypingStart: + // Enrich with sender info so receivers know who is typing + var data map[string]interface{} + if raw, ok := event.Data.(json.RawMessage); ok { + json.Unmarshal(raw, &data) + } + if data == nil { + data = make(map[string]interface{}) + } + data["user_id"] = c.UserID + data["username"] = c.Username + c.Hub.BroadcastEvent(Event{Type: event.Type, Data: data}) + case EventPresenceUpdate: c.Hub.BroadcastEvent(event) case EventVoiceWhisper: // Forward voice whispers only to the target user, not broadcast @@ -247,11 +260,11 @@ func ServeWS(db *sql.DB, hub *Hub, logger *slog.Logger, w http.ResponseWriter, r token = auth.Token } - var userID string + var userID, username string err = db.QueryRowContext(context.Background(), - `SELECT user_id FROM sessions WHERE token = $1 AND expires_at > NOW()`, + `SELECT u.id, u.username FROM sessions s JOIN users u ON u.id = s.user_id WHERE s.token = $1 AND s.expires_at > NOW()`, token, - ).Scan(&userID) + ).Scan(&userID, &username) if err != nil { logger.Warn("ws auth: invalid session", "error", err) conn.WriteMessage(websocket.TextMessage, []byte(`{"error":"invalid session"}`)) @@ -263,10 +276,11 @@ func ServeWS(db *sql.DB, hub *Hub, logger *slog.Logger, w http.ResponseWriter, r conn.WriteMessage(websocket.TextMessage, []byte(`{"type":"ready"}`)) client := &Client{ - Hub: hub, - Conn: conn, - UserID: userID, - send: make(chan []byte, 256), + Hub: hub, + Conn: conn, + UserID: userID, + Username: username, + send: make(chan []byte, 256), } hub.Register(client)