From 0b033742d0f8750d398d48af7e25c4c3ed9c6bbc Mon Sep 17 00:00:00 2001 From: Life Date: Sat, 4 Apr 2026 18:45:19 +0200 Subject: [PATCH] Fix badge notification: single bubble, working Wear button Block NotificationDialogMessageEvent badge types to prevent duplicate bubbles. Wrap bubble content in stopPropagation div so button clicks don't close the notification before toggleBadge runs. Request badge data on mount so Wear works even if inventory was never opened. --- .../NotificationBadgeReceivedBubbleView.tsx | 68 ++++++++++++------- src/hooks/notification/useNotification.ts | 3 + 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx b/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx index 0969c8e..7b57db3 100644 --- a/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx +++ b/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx @@ -1,5 +1,6 @@ -import { FC } from 'react'; -import { LocalizeText, NotificationBubbleItem } from '../../../../api'; +import { RequestBadgesComposer } from '@nitrots/nitro-renderer'; +import { FC, useEffect } from 'react'; +import { LocalizeText, NotificationBubbleItem, SendMessageComposer } from '../../../../api'; import { Flex, LayoutNotificationBubbleView, LayoutNotificationBubbleViewProps, Text } from '../../../../common'; import { useInventoryBadges } from '../../../../hooks'; @@ -11,36 +12,55 @@ export interface NotificationBadgeReceivedBubbleViewProps extends LayoutNotifica export const NotificationBadgeReceivedBubbleView: FC = props => { const { item = null, onClose = null, ...rest } = props; - const { toggleBadge = null } = useInventoryBadges(); + const { badgeCodes = [], toggleBadge = null } = useInventoryBadges(); - const handleWear = () => + useEffect(() => { - if(item.linkUrl) toggleBadge(item.linkUrl); - onClose(); + if(badgeCodes.length === 0) SendMessageComposer(new RequestBadgesComposer()); + }, []); + + const handleWear = (event: React.MouseEvent) => + { + event.stopPropagation(); + + if(item.linkUrl) + { + toggleBadge(item.linkUrl); + } + + if(onClose) onClose(); + }; + + const handleDismiss = (event: React.MouseEvent) => + { + event.stopPropagation(); + if(onClose) onClose(); }; return ( - - - { item.iconUrl && } +
e.stopPropagation() }> + + + { item.iconUrl && } + + + { LocalizeText('notification.badge.received') } + { item.message } + - - { LocalizeText('notification.badge.received') } - { item.message } + + + + { LocalizeText('notifications.button.later') } + - - - - - { LocalizeText('notifications.button.later') } - - +
); }; diff --git a/src/hooks/notification/useNotification.ts b/src/hooks/notification/useNotification.ts index c13c499..007a61c 100644 --- a/src/hooks/notification/useNotification.ts +++ b/src/hooks/notification/useNotification.ts @@ -356,6 +356,9 @@ const useNotificationState = () => { const parser = event.getParser(); + // Skip badge notifications — handled by BadgeReceivedEvent with "Wear" button + if(parser.type === 'badge_received' || parser.type === 'badges' || parser.type.includes('badge')) return; + showNotification(parser.type, parser.parameters); });