From c65a7387fa4fd9a1c2d6e6225352ed0386cbfb9b Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:40:05 +0100 Subject: [PATCH] fix: remove spurious reconnect sound on deploy/laptop wake, fix federated typing/asset display --- packages/web/public/sounds/reconnect.mp3 | Bin 22334 -> 0 bytes .../src/components/voice/SoundController.tsx | 32 +----------------- packages/web/src/hooks/useWebSocket.ts | 18 +++++++--- packages/web/src/utils/assetUrls.ts | 17 +++++++++- 4 files changed, 31 insertions(+), 36 deletions(-) delete mode 100644 packages/web/public/sounds/reconnect.mp3 diff --git a/packages/web/public/sounds/reconnect.mp3 b/packages/web/public/sounds/reconnect.mp3 deleted file mode 100644 index 2ab7491d068613bb8a136ec748f01c00f09aa0f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22334 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 s.user); - const [isWsConnected, setIsWsConnected] = useState(false); - - // Poll home WS connection status without managing lifecycle - useEffect(() => { - const interval = setInterval(() => { - setIsWsConnected(getHomeWsConnected()); - }, 500); - return () => clearInterval(interval); - }, []); // Refs to track previous states const isInitialMount = useRef(true); - const prevIsWsConnected = useRef(false); - const wsDisconnectedAt = useRef(0); const prevIsMuted = useRef(useVoiceStore.getState().isMuted); const prevIsDeafened = useRef(useVoiceStore.getState().isDeafened); const prevIsCameraOn = useRef(useVoiceStore.getState().isCameraOn); @@ -33,28 +21,10 @@ export function SoundController() { const incomingCallLoop = useRef(null); const outgoingCallLoop = useRef(null); - // WebSocket Reconnect Sound — suppress during active voice and brief blips (<3s) - useEffect(() => { - if (isInitialMount.current) return; - if (!isWsConnected && prevIsWsConnected.current) { - // Record when we lost connection - wsDisconnectedAt.current = Date.now(); - } - if (isWsConnected && !prevIsWsConnected.current) { - const isInActiveVoice = useVoiceStore.getState().isLiveKitConnected; - const downtime = wsDisconnectedAt.current > 0 ? Date.now() - wsDisconnectedAt.current : Infinity; - if (!isInActiveVoice && downtime > 3000) { - audioManager.playSound('reconnect'); - } - } - prevIsWsConnected.current = isWsConnected; - }, [isWsConnected, audioManager]); - useEffect(() => { // Set initial mount flag to false after first run const timer = setTimeout(() => { isInitialMount.current = false; - prevIsWsConnected.current = isWsConnected; }, 1000); // 1. Listen to Voice State Changes diff --git a/packages/web/src/hooks/useWebSocket.ts b/packages/web/src/hooks/useWebSocket.ts index 85453bfc..4b21d9c7 100644 --- a/packages/web/src/hooks/useWebSocket.ts +++ b/packages/web/src/hooks/useWebSocket.ts @@ -223,9 +223,14 @@ function handleEvent(origin: string, event: ServerEvent): void { removeMessage(event.messageId, event.channelId); break; - case 'typing': - setTyping(event.channelId, event.userId, event.username); + case 'typing': { + let typingUsername = event.username as string; + if (!isHome && typingUsername && !typingUsername.includes('@')) { + try { typingUsername = `${typingUsername}@${new URL(origin).host}`; } catch {} + } + setTyping(event.channelId, event.userId, typingUsername); break; + } case 'presence_update': updateMemberPresence(event.userId, event.status); @@ -300,9 +305,14 @@ function handleEvent(origin: string, event: ServerEvent): void { removeMessage(event.messageId, event.dmChannelId); break; - case 'dm_typing': - setTyping(event.dmChannelId, event.userId, event.username); + case 'dm_typing': { + let dmTypingUsername = event.username as string; + if (!isHome && dmTypingUsername && !dmTypingUsername.includes('@')) { + try { dmTypingUsername = `${dmTypingUsername}@${new URL(origin).host}`; } catch {} + } + setTyping(event.dmChannelId, event.userId, dmTypingUsername); break; + } // ─── Reactions (all origins) ──────────────────────────────────────────── diff --git a/packages/web/src/utils/assetUrls.ts b/packages/web/src/utils/assetUrls.ts index 456c3fc8..8e2a2d7d 100644 --- a/packages/web/src/utils/assetUrls.ts +++ b/packages/web/src/utils/assetUrls.ts @@ -15,9 +15,24 @@ export function resolveAssetUrl(filename: string | null | undefined, origin: str * Mutates in-place for efficiency (called on arrays of members/messages). */ export function normalizeUserAssets(user: T, origin: string): T { - if (origin && user.avatar) { + if (!origin) return user; + if (user.avatar) { user.avatar = resolveAssetUrl(user.avatar, origin) ?? user.avatar; } + // Qualify users local to the remote instance with their origin domain. + // These users have no homeInstance (they're native there), so the client + // can't distinguish them from its own local users without this step. + const u = user as Record; + if (typeof u.username === 'string' && typeof u.id === 'string' && !u.homeInstance) { + try { + const host = new URL(origin).host; + u.homeInstance = host; + if (!u.homeUserId) u.homeUserId = u.id; + if (!(u.username as string).includes('@')) { + u.username = `${u.username}@${host}`; + } + } catch {} + } return user; }