From 53463b83221c2dfdff86275d0d8eb2ead3d2f7d0 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 13 Jun 2026 16:20:59 +0200 Subject: [PATCH 1/3] fix(room): name bubbles cleared for the wrong user on USER_REMOVED The USER_REMOVED handler for a UNIT filtered name bubbles with `bubble.roomIndex === event.id`, which KEEPS only the leaving user's bubble and drops everyone else's (the two sibling filters on the next lines correctly use `!==`). When any user left view, all other floating name bubbles vanished while the departed user's lingered. Flip to `!==`. --- src/hooks/rooms/widgets/useAvatarInfoWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts index 189f34a..6ee6a6d 100644 --- a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts +++ b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts @@ -361,7 +361,7 @@ const useAvatarInfoWidgetState = () => { let index = nameBubbles.findIndex(bubble => (bubble.roomIndex === event.id)); - if(index > -1) setNameBubbles(prevValue => prevValue.filter(bubble => (bubble.roomIndex === event.id))); + if(index > -1) setNameBubbles(prevValue => prevValue.filter(bubble => (bubble.roomIndex !== event.id))); index = productBubbles.findIndex(bubble => (bubble.id === event.id)); From a2f8a4dd6109986ac295d7d4cdde2a604a8c9011 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 13 Jun 2026 16:20:59 +0200 Subject: [PATCH 2/3] =?UTF-8?q?fix(room):=20pet-fertilize=20chat=20bubble?= =?UTF-8?q?=20=E2=80=94=20bad=20localization=20key=20+=20wrong=20target=20?= =?UTF-8?q?user?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs in the pet rebreed/fertilize chat path: the localization key had a stray trailing semicolon (`'widget.chatbubble.petrefertilized;'`) so the lookup failed and the raw key rendered; and the target user was resolved via `newRoomObject = getRoomObject(event.extraParam)` but then read back by `roomObject.id` (the speaker), so `userName` was the speaker, not the target. Use `newRoomObject.id`. --- src/hooks/rooms/widgets/useChatWidget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/rooms/widgets/useChatWidget.ts b/src/hooks/rooms/widgets/useChatWidget.ts index ed0b9ed..2853f41 100644 --- a/src/hooks/rooms/widgets/useChatWidget.ts +++ b/src/hooks/rooms/widgets/useChatWidget.ts @@ -148,7 +148,7 @@ const useChatWidgetState = () => if(chatType === RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE) { - textKey = 'widget.chatbubble.petrefertilized;'; + textKey = 'widget.chatbubble.petrefertilized'; } else if(chatType === RoomSessionChatEvent.CHAT_TYPE_PET_SPEED_FERTILIZE) @@ -162,7 +162,7 @@ const useChatWidgetState = () => if(newRoomObject) { - const newUserData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); + const newUserData = roomSession.userDataManager.getUserDataByIndex(newRoomObject.id); if(newUserData) targetUserName = newUserData.name; } From 648cea698d5c5e74853cc9d059c906666e6ef41e Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 13 Jun 2026 16:20:59 +0200 Subject: [PATCH 3/3] fix(room): word-quiz countdown mutates Map value objects in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 1s tick did `value.secondsLeft--` on the VoteValue objects held by the previous state Map and returned the same Map reference when nothing expired — an in-place state mutation (breaks memoization / StrictMode double-invoke). Rebuild new value objects in a new Map each tick (and drop expired entries). --- src/hooks/rooms/widgets/useWordQuizWidget.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hooks/rooms/widgets/useWordQuizWidget.ts b/src/hooks/rooms/widgets/useWordQuizWidget.ts index bb48327..aef3cf6 100644 --- a/src/hooks/rooms/widgets/useWordQuizWidget.ts +++ b/src/hooks/rooms/widgets/useWordQuizWidget.ts @@ -112,19 +112,21 @@ const useWordQuizWidgetState = () => { setUserAnswers(prevValue => { - const keysToRemove: number[] = []; + if(prevValue.size === 0) return prevValue; - prevValue.forEach((value, key) => + // Build new value objects + a new Map — don't decrement + // secondsLeft on the objects still referenced by prevValue + // (in-place mutation breaks memoization / StrictMode replay). + const next = new Map(prevValue); + + next.forEach((value, key) => { - value.secondsLeft--; + const secondsLeft = value.secondsLeft - 1; - if(value.secondsLeft <= 0) keysToRemove.push(key); + if(secondsLeft <= 0) next.delete(key); + else next.set(key, { ...value, secondsLeft }); }); - if(keysToRemove.length === 0) return prevValue; - - const next = new Map(prevValue); - keysToRemove.forEach(key => next.delete(key)); return next; }); };