From 3a648663ece281b36447baa1460245da15b5264b Mon Sep 17 00:00:00 2001 From: duckietm Date: Tue, 14 Apr 2026 11:18:46 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Small=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room-tools/RoomToolsWidgetView.tsx | 84 ++++++++----------- src/components/toolbar/ToolbarItemView.tsx | 2 +- src/components/toolbar/ToolbarMeView.tsx | 46 +++++----- src/components/toolbar/ToolbarView.tsx | 79 +---------------- src/css/nitrocard/NitroCardView.css | 3 +- 5 files changed, 69 insertions(+), 145 deletions(-) diff --git a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx index f740853..5105cf5 100644 --- a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx +++ b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx @@ -6,7 +6,6 @@ import { GetConfigurationValue, LocalizeText, SendMessageComposer, SetLocalStora import { Text } from '../../../../common'; import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks'; import { getRegisteredPlugins, INitroPlugin, subscribePlugins } from '../../../plugins/NitroPluginApi'; -import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; export const RoomToolsWidgetView: FC<{}> = props => { const [areBubblesMuted, setAreBubblesMuted] = useState(false); @@ -16,7 +15,6 @@ export const RoomToolsWidgetView: FC<{}> = props => { const [roomTags, setRoomTags] = useState(null); const [isOpen, setIsOpen] = useState(false); const [isOpenHistory, setIsOpenHistory] = useState(false); - const [isCollapsed, setIsCollapsed] = useState(false); const [roomHistory, setRoomHistory] = useState<{ roomId: number, roomName: string }[]>([]); const [plugins, setPlugins] = useState([]); const { navigatorData = null } = useNavigator(); @@ -81,11 +79,10 @@ export const RoomToolsWidgetView: FC<{}> = props => { const onChangeRoomHistory = (roomId: number, roomName: string) => { let newStorage = JSON.parse(window.localStorage.getItem('nitro.room.history') || '[]'); + if (newStorage.some((room: { roomId: number }) => room.roomId === roomId)) return; - newStorage = newStorage.filter((room: { roomId: number }) => room.roomId !== roomId); - newStorage = [ ...newStorage, { roomId, roomName } ]; - - if (newStorage.length > 10) newStorage = newStorage.slice(-10); + if (newStorage.length >= 10) newStorage.shift(); + newStorage = [...newStorage, { roomId, roomName }]; setRoomHistory(newStorage); SetLocalStorage('nitro.room.history', newStorage); @@ -102,55 +99,48 @@ export const RoomToolsWidgetView: FC<{}> = props => { }); useEffect(() => { - if(roomName || roomOwner || (roomTags && roomTags.length)) setIsOpen(true); + setIsOpen(true); + const timeout = setTimeout(() => setIsOpen(false), 5000); + return () => clearTimeout(timeout); }, [roomName, roomOwner, roomTags]); - useEffect(() => { - if(!isCollapsed && (roomName || roomOwner || (roomTags && roomTags.length))) setIsOpen(true); - }, [ isCollapsed, roomName, roomOwner, roomTags ]); - useEffect(() => { setRoomHistory(JSON.parse(window.localStorage.getItem('nitro.room.history') || '[]')); }, []); - return ( -
-
- - - { !isCollapsed && - -
handleToolClick('settings')} /> -
handleToolClick('zoom')} /> -
handleToolClick('chat_history')} /> -
handleToolClick('hiddenbubbles')} /> + useEffect(() => { + const handleTabClose = () => { + window.localStorage.removeItem('nitro.room.history'); + }; + window.addEventListener('beforeunload', handleTabClose); + return () => window.removeEventListener('beforeunload', handleTabClose); + }, []); - {navigatorData.canRate && ( -
handleToolClick('like_room')} /> - )} -
handleToolClick('toggle_room_link')} /> -
handleToolClick('room_history')} /> - {plugins.map(plugin => ( -
plugin.onOpen()} - /> - ))} - } - + return ( +
+
+
handleToolClick('settings')} /> +
handleToolClick('zoom')} /> +
handleToolClick('chat_history')} /> +
handleToolClick('hiddenbubbles')} /> + + {navigatorData.canRate && ( +
handleToolClick('like_room')} /> + )} +
handleToolClick('toggle_room_link')} /> +
handleToolClick('room_history')} /> + {plugins.map(plugin => ( +
plugin.onOpen()} + /> + ))}
-
+
- {(!isCollapsed && (isOpen || !!roomName || !!roomOwner || !!(roomTags && roomTags.length))) && ( + {isOpen && (
@@ -171,7 +161,7 @@ export const RoomToolsWidgetView: FC<{}> = props => {
)} - {(!isCollapsed && isOpenHistory) && ( + {isOpenHistory && (
{roomHistory.map(history => ( diff --git a/src/components/toolbar/ToolbarItemView.tsx b/src/components/toolbar/ToolbarItemView.tsx index 8789403..3a0822a 100644 --- a/src/components/toolbar/ToolbarItemView.tsx +++ b/src/components/toolbar/ToolbarItemView.tsx @@ -11,7 +11,7 @@ export const ToolbarItemView = forwardRef>; }>> = props => { - const { useGuideTool = false, unseenAchievementCount = 0, children = null } = props; - const elementRef = useRef(null); + const { useGuideTool = false, unseenAchievementCount = 0, setMeExpanded = null, children = null, ...rest } = props; + const elementRef = useRef(); useEffect(() => { @@ -23,22 +22,29 @@ export const ToolbarMeView: FC + { + const onClick = (event: MouseEvent) => setMeExpanded(false); + + document.addEventListener('click', onClick); + + return () => document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick); + }, [ setMeExpanded ]); + return ( -
-
- { (GetConfigurationValue('guides.enabled') && useGuideTool) && - DispatchUiEvent(new GuideToolEvent(GuideToolEvent.TOGGLE_GUIDE_TOOL)) } title={ LocalizeText('guide.help.button.label') } /> } - CreateLinkEvent('achievements/toggle') } title={ LocalizeText('toolbar.icon.label.achievements') }> - { (unseenAchievementCount > 0) && - } - - GetUserProfile(GetSessionDataManager().userId) } title={ LocalizeText('toolbar.icon.label.memenu') } /> - CreateLinkEvent('navigator/search/myworld_view') } title={ LocalizeText('navigator.myworlds') } /> - CreateLinkEvent('avatar-editor/toggle') } title={ LocalizeText('widget.memenu.settings.avatar') } /> - CreateLinkEvent('user-settings/toggle') } title={ LocalizeText('widget.memenu.settings.title') } /> - CreateLinkEvent('groupforum/toggle') } title={ LocalizeText('toolbar.icon.label.forums') } /> - { children } + + { (GetConfigurationValue('guides.enabled') && useGuideTool) && +
DispatchUiEvent(new GuideToolEvent(GuideToolEvent.TOGGLE_GUIDE_TOOL)) } /> } +
CreateLinkEvent('achievements/toggle') }> + { (unseenAchievementCount > 0) && + }
-
+
GetUserProfile(GetSessionDataManager().userId) } /> +
CreateLinkEvent('navigator/search/myworld_view') } /> +
CreateLinkEvent('avatar-editor/toggle') } /> +
CreateLinkEvent('user-settings/toggle') } /> +
CreateLinkEvent('groupforum/toggle') } title={ LocalizeText('toolbar.icon.label.forums') } /> + { children } + ); }; diff --git a/src/components/toolbar/ToolbarView.tsx b/src/components/toolbar/ToolbarView.tsx index a3322a7..3e7b98d 100644 --- a/src/components/toolbar/ToolbarView.tsx +++ b/src/components/toolbar/ToolbarView.tsx @@ -3,28 +3,15 @@ import { AnimatePresence, motion } from 'framer-motion'; import { FC, useEffect, useState } from 'react'; import { GetConfigurationValue, MessengerIconState, OpenMessengerChat, setYoutubeRoomEnabled, VisitDesktop } from '../../api'; import { Flex, LayoutAvatarImageView, LayoutItemCountView } from '../../common'; -import { useAchievements, useFriends, useInventoryUnseenTracker, useMessageEvent, useMessenger, useNitroEvent, useSessionInfo, useWiredTools } from '../../hooks'; +import { useAchievements, useFriends, useInventoryUnseenTracker, useMessageEvent, useMessenger, useNitroEvent, useSessionInfo } from '../../hooks'; import { ToolbarItemView } from './ToolbarItemView'; import { ToolbarMeView } from './ToolbarMeView'; import { YouTubePlayerView } from './YouTubePlayerView'; -const containerVariants = { - hidden: {}, - visible: { transition: { staggerChildren: 0.05 } }, - exit: { transition: { staggerChildren: 0.03, staggerDirection: -1 as const } } -}; - -const itemVariants = { - hidden: { opacity: 0, y: 10, scale: 0.8 }, - visible: { opacity: 1, y: 0, scale: 1, transition: { type: 'spring', stiffness: 400, damping: 22 } }, - exit: { opacity: 0, y: 6, scale: 0.85, transition: { duration: 0.1 } } -}; - export const ToolbarView: FC<{ isInRoom: boolean }> = props => { const { isInRoom } = props; const [ isMeExpanded, setMeExpanded ] = useState(false); - const [ isToolbarOpen, setIsToolbarOpen ] = useState(false); const [ useGuideTool, setUseGuideTool ] = useState(false); const [ youtubeEnabled, setYoutubeEnabled ] = useState(false); const { userFigure = null } = useSessionInfo(); @@ -32,10 +19,7 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props => const { getTotalUnseen = 0 } = useAchievements(); const { requests = [] } = useFriends(); const { iconState = MessengerIconState.HIDDEN } = useMessenger(); - const { openMonitor, showToolbarButton } = useWiredTools(); const isMod = GetSessionDataManager().isModerator; - const hasDesktopUnifiedShell = (isInRoom && isToolbarOpen); - const showDesktopShell = (isToolbarOpen || !isInRoom); useMessageEvent(YouTubeRoomSettingsEvent, event => { @@ -78,11 +62,13 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props => const targetBounds = target.getBoundingClientRect(); const imageBounds = image.getBoundingClientRect(); + const left = (imageBounds.x - targetBounds.x); const top = (imageBounds.y - targetBounds.y); const squared = Math.sqrt(((left * left) + (top * top))); const wait = (500 - Math.abs(((((1 / squared) * 100) * 500) * 0.5))); const height = 20; + const motionName = (`ToolbarBouncing[${ iconName }]`); if(!Motions.getMotionByTag(motionName)) @@ -153,62 +139,3 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props => ); }; - -const TOOLBAR_STYLES = ` - .tb-icon { - opacity: 1; - transition: transform 0.15s ease; - cursor: pointer; - } - - .tb-icon:hover { - transform: translateY(-2px); - } - - .tb-icon:active { - transform: translateY(0); - } - - .tb-toggle { - width: 32px; - height: 32px; - flex-shrink: 0; - border-radius: 9px; - background: rgba(18, 16, 14, 0.80); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border: 1px solid rgba(255, 255, 255, 0.08); - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5); - transition: background 0.15s, border-color 0.15s; - } - - .tb-toggle:hover { - background: rgba(30, 26, 20, 0.88); - border-color: rgba(255, 255, 255, 0.13); - } - - .tb-bar-scroll { - overflow-x: auto; - overflow-y: visible; - scrollbar-width: none; - -ms-overflow-style: none; - flex-wrap: nowrap; - } - - .tb-bar-scroll::-webkit-scrollbar { - display: none; - } - - .tb-open-shell { - scrollbar-width: none; - -ms-overflow-style: none; - } - - .tb-open-shell::-webkit-scrollbar { - display: none; - } -`; diff --git a/src/css/nitrocard/NitroCardView.css b/src/css/nitrocard/NitroCardView.css index 16e81c8..482bc1c 100644 --- a/src/css/nitrocard/NitroCardView.css +++ b/src/css/nitrocard/NitroCardView.css @@ -220,6 +220,7 @@ font-family: Ubuntu, sans-serif; color: #111; } +} @media (max-width: 991.98px) { .content-area { @@ -247,7 +248,7 @@ } } -@include media-breakpoint-down(lg) { +@media (max-width: 991.98px) { .nitro-card { resize: none !important; max-width: calc(100vw - 16px) !important;