From ad1beccd3a97d753e6515f5cef5fb18c478d1037 Mon Sep 17 00:00:00 2001 From: Keith Smith Date: Fri, 14 Aug 2026 17:09:22 -0600 Subject: [PATCH] Fix profile save UX: close modal on success, refresh room members live Saving a display name previously gave no feedback and left the modal open, and an open room's message list/member panel kept showing the pre-edit profile until reload -- both fetch that data from a member list ChatShellPage only fetched once per room. Now the save closes the modal (clear confirmation it worked) and ChatShellPage re-fetches room members whenever the logged-in user's own display_name/avatar_filename changes, so the update appears immediately everywhere without a reload. --- frontend/src/components/ProfileModal.tsx | 2 +- frontend/src/pages/ChatShellPage.tsx | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/ProfileModal.tsx b/frontend/src/components/ProfileModal.tsx index 17ff922..fc867cf 100644 --- a/frontend/src/components/ProfileModal.tsx +++ b/frontend/src/components/ProfileModal.tsx @@ -28,9 +28,9 @@ export function ProfileModal({ onClose }: ProfileModalProps) { try { const updated = await updateProfile(displayName.trim() || null) updateUser(updated) + onClose() } catch (err) { setError(err instanceof ApiError ? err.message : String(err)) - } finally { setSavingName(false) } } diff --git a/frontend/src/pages/ChatShellPage.tsx b/frontend/src/pages/ChatShellPage.tsx index 3bde037..82d0375 100644 --- a/frontend/src/pages/ChatShellPage.tsx +++ b/frontend/src/pages/ChatShellPage.tsx @@ -11,6 +11,7 @@ import { OfflineBanner } from '../components/OfflineBanner' import { RoomInfoPanel } from '../components/RoomInfoPanel' import { Sidebar } from '../components/Sidebar' import { TopBar } from '../components/TopBar' +import { useAuth } from '../context/AuthContext' import { MOBILE_BREAKPOINT, useWindowWidth } from '../hooks/useWindowWidth' import type { MyRoomItem, RoomMember } from '../types' import './ChatShellPage.css' @@ -20,6 +21,7 @@ type ModalKind = 'new' | 'browse' | 'invites' | null export function ChatShellPage() { const { roomId } = useParams<{ roomId?: string }>() const navigate = useNavigate() + const { user } = useAuth() const width = useWindowWidth() const isMobile = width < MOBILE_BREAKPOINT @@ -65,7 +67,13 @@ export function ChatShellPage() { useEffect(() => { refreshMembers() - }, [refreshMembers]) + // Also re-run when the logged-in user's own profile changes (display + // name/avatar) -- refreshMembers() itself doesn't change identity when + // only roomId is the same, so without this the currently open room's + // member list (and anything resolving avatar/name from it, like + // MessageList) would keep showing the pre-edit profile until the room + // is reopened. + }, [refreshMembers, user?.display_name, user?.avatar_filename]) function goToRoom(id: string) { navigate(`/rooms/${id}`)