mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
Add golden glow for new badges and badge received toast notification
New unseen badges pulse with a gold glow instead of a flat green background. When a badge is received, a bubble notification appears with the badge image, name, and a "Wear" button that opens inventory.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { NotificationBubbleItem, NotificationBubbleType } from '../../../../api';
|
import { NotificationBubbleItem, NotificationBubbleType } from '../../../../api';
|
||||||
|
import { NotificationBadgeReceivedBubbleView } from './NotificationBadgeReceivedBubbleView';
|
||||||
import { NotificationClubGiftBubbleView } from './NotificationClubGiftBubbleView';
|
import { NotificationClubGiftBubbleView } from './NotificationClubGiftBubbleView';
|
||||||
import { NotificationDefaultBubbleView } from './NotificationDefaultBubbleView';
|
import { NotificationDefaultBubbleView } from './NotificationDefaultBubbleView';
|
||||||
|
|
||||||
@@ -10,6 +11,8 @@ export const GetBubbleLayout = (item: NotificationBubbleItem, onClose: () => voi
|
|||||||
|
|
||||||
switch(item.notificationType)
|
switch(item.notificationType)
|
||||||
{
|
{
|
||||||
|
case NotificationBubbleType.BADGE_RECEIVED:
|
||||||
|
return <NotificationBadgeReceivedBubbleView key={ item.id } { ...props } />;
|
||||||
case NotificationBubbleType.CLUBGIFT:
|
case NotificationBubbleType.CLUBGIFT:
|
||||||
return <NotificationClubGiftBubbleView key={ item.id } { ...props } />;
|
return <NotificationClubGiftBubbleView key={ item.id } { ...props } />;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText, NotificationBubbleItem, OpenUrl } from '../../../../api';
|
||||||
|
import { Flex, LayoutNotificationBubbleView, LayoutNotificationBubbleViewProps, Text } from '../../../../common';
|
||||||
|
|
||||||
|
export interface NotificationBadgeReceivedBubbleViewProps extends LayoutNotificationBubbleViewProps
|
||||||
|
{
|
||||||
|
item: NotificationBubbleItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NotificationBadgeReceivedBubbleView: FC<NotificationBadgeReceivedBubbleViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { item = null, onClose = null, ...rest } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LayoutNotificationBubbleView className="flex-col" fadesOut={ false } onClose={ onClose } { ...rest }>
|
||||||
|
<Flex alignItems="center" gap={ 2 } className="mb-2">
|
||||||
|
<Flex center className="w-[50px] h-[50px] shrink-0">
|
||||||
|
{ item.iconUrl && <img alt="" className="no-select" src={ item.iconUrl } /> }
|
||||||
|
</Flex>
|
||||||
|
<Flex column gap={ 0 }>
|
||||||
|
<Text bold variant="white">{ LocalizeText('notification.badge.received') }</Text>
|
||||||
|
<Text variant="white" small>{ item.message }</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Flex alignItems="center" justifyContent="end" gap={ 2 }>
|
||||||
|
<button
|
||||||
|
className="btn btn-success w-full btn-sm"
|
||||||
|
type="button"
|
||||||
|
onClick={ () => { OpenUrl(item.linkUrl); onClose(); } }>
|
||||||
|
{ LocalizeText('inventory.badges.wearbadge') }
|
||||||
|
</button>
|
||||||
|
<span className="underline cursor-pointer text-nowrap" onClick={ onClose }>
|
||||||
|
{ LocalizeText('notifications.button.later') }
|
||||||
|
</span>
|
||||||
|
</Flex>
|
||||||
|
</LayoutNotificationBubbleView>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, ConnectionErrorEvent, GetLocalizationManager, GetRoomEngine, GetSessionDataManager, HabboBroadcastMessageEvent, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelWillCloseInMinutesEvent, InfoFeedEnableMessageEvent, MaintenanceStatusMessageEvent, ModeratorCautionEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetLevelNotificationEvent, PetReceivedMessageEvent, RespectReceivedEvent, RoomEnterEffect, RoomEnterEvent, SimpleAlertMessageEvent, UserBannedMessageEvent, Vector3d, WiredRewardResultMessageEvent } from '@nitrots/nitro-renderer';
|
import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, BadgeReceivedEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, ConnectionErrorEvent, GetLocalizationManager, GetRoomEngine, GetSessionDataManager, HabboBroadcastMessageEvent, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelWillCloseInMinutesEvent, InfoFeedEnableMessageEvent, MaintenanceStatusMessageEvent, ModeratorCautionEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetLevelNotificationEvent, PetReceivedMessageEvent, RespectReceivedEvent, RoomEnterEffect, RoomEnterEvent, SimpleAlertMessageEvent, UserBannedMessageEvent, Vector3d, WiredRewardResultMessageEvent } from '@nitrots/nitro-renderer';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useBetween } from 'use-between';
|
import { useBetween } from 'use-between';
|
||||||
import { GetConfigurationValue, LocalizeBadgeName, LocalizeText, NotificationAlertItem, NotificationAlertType, NotificationBubbleItem, NotificationBubbleType, NotificationConfirmItem, PlaySound, ProductImageUtility, TradingNotificationType } from '../../api';
|
import { GetConfigurationValue, LocalizeBadgeName, LocalizeText, NotificationAlertItem, NotificationAlertType, NotificationBubbleItem, NotificationBubbleType, NotificationConfirmItem, PlaySound, ProductImageUtility, TradingNotificationType } from '../../api';
|
||||||
@@ -217,6 +217,15 @@ const useNotificationState = () =>
|
|||||||
showSingleBubble((text1 + ' ' + badgeName), NotificationBubbleType.ACHIEVEMENT, badgeImage, internalLink);
|
showSingleBubble((text1 + ' ' + badgeName), NotificationBubbleType.ACHIEVEMENT, badgeImage, internalLink);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useMessageEvent<BadgeReceivedEvent>(BadgeReceivedEvent, event =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
const badgeName = LocalizeBadgeName(parser.badgeCode);
|
||||||
|
const badgeImage = GetSessionDataManager().getBadgeUrl(parser.badgeCode);
|
||||||
|
|
||||||
|
showSingleBubble(badgeName, NotificationBubbleType.BADGE_RECEIVED, badgeImage, 'inventory/toggle');
|
||||||
|
});
|
||||||
|
|
||||||
useMessageEvent<ClubGiftNotificationEvent>(ClubGiftNotificationEvent, event =>
|
useMessageEvent<ClubGiftNotificationEvent>(ClubGiftNotificationEvent, event =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ const InfiniteGridItem = forwardRef<HTMLDivElement, {
|
|||||||
: (itemColor ? 'border-card-grid-item-border' : 'border-card-grid-item-border bg-card-grid-item'),
|
: (itemColor ? 'border-card-grid-item-border' : 'border-card-grid-item-border bg-card-grid-item'),
|
||||||
(itemUniqueSoldout || (itemUniqueNumber > 0)) && 'unique-item',
|
(itemUniqueSoldout || (itemUniqueNumber > 0)) && 'unique-item',
|
||||||
itemUniqueSoldout && 'sold-out',
|
itemUniqueSoldout && 'sold-out',
|
||||||
itemUnseen && ' bg-green-500 bg-opacity-40',
|
itemUnseen && ' animate-pulse-glow-gold border-yellow-400/60',
|
||||||
className
|
className
|
||||||
) }
|
) }
|
||||||
style={ styleNames(
|
style={ styleNames(
|
||||||
|
|||||||
+7
-1
@@ -115,11 +115,16 @@ module.exports = {
|
|||||||
'0%': { transform: 'scale(1.15)' },
|
'0%': { transform: 'scale(1.15)' },
|
||||||
'100%': { transform: 'scale(1)' },
|
'100%': { transform: 'scale(1)' },
|
||||||
},
|
},
|
||||||
|
pulseGlowGold: {
|
||||||
|
'0%, 100%': { boxShadow: '0 0 6px rgba(255,193,7,0.4)' },
|
||||||
|
'50%': { boxShadow: '0 0 14px rgba(255,193,7,0.7)' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
'pulse-glow': 'pulseGlow 1.2s ease-in-out infinite',
|
'pulse-glow': 'pulseGlow 1.2s ease-in-out infinite',
|
||||||
'pulse-glow-red': 'pulseGlowRed 1.2s ease-in-out infinite',
|
'pulse-glow-red': 'pulseGlowRed 1.2s ease-in-out infinite',
|
||||||
'drop-settle': 'dropSettle 0.3s ease-out',
|
'drop-settle': 'dropSettle 0.3s ease-out',
|
||||||
|
'pulse-glow-gold': 'pulseGlowGold 1.5s ease-in-out infinite',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -166,7 +171,8 @@ module.exports = {
|
|||||||
'items-end',
|
'items-end',
|
||||||
'animate-pulse-glow',
|
'animate-pulse-glow',
|
||||||
'animate-pulse-glow-red',
|
'animate-pulse-glow-red',
|
||||||
'animate-drop-settle'
|
'animate-drop-settle',
|
||||||
|
'animate-pulse-glow-gold'
|
||||||
],
|
],
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
variants: {
|
variants: {
|
||||||
|
|||||||
Reference in New Issue
Block a user