mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 07:26:19 +00:00
Merge latest duckie main with login UI
This commit is contained in:
+11
-15
@@ -1,6 +1,6 @@
|
||||
import { AvatarFigurePartType, GetAvatarRenderManager, GetSessionDataManager, RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FurniCategory, GetFurnitureDataForRoomObject, LocalizeText, SendMessageComposer } from '../../../../../api';
|
||||
import { BuildPurchasableClothingFigure, GetFurnitureDataForRoomObject, LocalizeText, SendMessageComposer } from '../../../../../api';
|
||||
import { Button, Column, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
||||
import { useRoom } from '../../../../../hooks';
|
||||
|
||||
@@ -41,22 +41,18 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
|
||||
{
|
||||
const furniData = GetFurnitureDataForRoomObject(roomSession.roomId, objectId, RoomObjectCategory.FLOOR);
|
||||
|
||||
if(furniData)
|
||||
if(furniData && furniData.customParams && furniData.customParams.length)
|
||||
{
|
||||
switch(furniData.specialType)
|
||||
const setIds = furniData.customParams.split(',')
|
||||
.map(part => parseInt(part))
|
||||
.filter(id => !isNaN(id));
|
||||
|
||||
for(const setId of setIds)
|
||||
{
|
||||
case FurniCategory.FIGURE_PURCHASABLE_SET:
|
||||
mode = MODE_PURCHASABLE_CLOTHING;
|
||||
|
||||
const setIds = furniData.customParams.split(',').map(part => parseInt(part));
|
||||
|
||||
for(const setId of setIds)
|
||||
{
|
||||
if(GetAvatarRenderManager().isValidFigureSetForGender(setId, gender)) validSets.push(setId);
|
||||
}
|
||||
|
||||
break;
|
||||
if(GetAvatarRenderManager().isValidFigureSetForGender(setId, gender)) validSets.push(setId);
|
||||
}
|
||||
|
||||
if(validSets.length) mode = MODE_PURCHASABLE_CLOTHING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +64,7 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
|
||||
}
|
||||
|
||||
setGender(gender);
|
||||
setNewFigure(GetAvatarRenderManager().getFigureStringWithFigureIds(figure, gender, validSets));
|
||||
setNewFigure(BuildPurchasableClothingFigure(figure, validSets));
|
||||
|
||||
// if owns clothing, change to it
|
||||
|
||||
|
||||
@@ -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<string[]>(null);
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [isOpenHistory, setIsOpenHistory] = useState<boolean>(false);
|
||||
const [isCollapsed, setIsCollapsed] = useState<boolean>(false);
|
||||
const [roomHistory, setRoomHistory] = useState<{ roomId: number, roomName: string }[]>([]);
|
||||
const [plugins, setPlugins] = useState<INitroPlugin[]>([]);
|
||||
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 (
|
||||
<div className="nitro-room-tools-container">
|
||||
<div className="nitro-room-tools-rail">
|
||||
<button type="button" className={ `nitro-room-tools-toggle ${ isCollapsed ? 'is-collapsed' : 'is-open' }` } onClick={ () => setIsCollapsed(value => !value) } title={ isCollapsed ? 'Apri strumenti stanza' : 'Chiudi strumenti stanza' }>
|
||||
{ isCollapsed ? <FaChevronRight className="text-[11px]" /> : <FaChevronLeft className="text-[11px]" /> }
|
||||
</button>
|
||||
<AnimatePresence initial={ false }>
|
||||
{ !isCollapsed &&
|
||||
<motion.div
|
||||
initial={ { opacity: 0, x: -10, scale: 0.96 } }
|
||||
animate={ { opacity: 1, x: 0, scale: 1 } }
|
||||
exit={ { opacity: 0, x: -10, scale: 0.96 } }
|
||||
transition={ { duration: 0.26, ease: [ 0.16, 1, 0.3, 1 ] } }
|
||||
className="flex flex-col items-center justify-center p-2 nitro-room-tools">
|
||||
<div className="cursor-pointer nitro-icon icon-cog" title={LocalizeText('room.settings.button.text')} onClick={() => handleToolClick('settings')} />
|
||||
<div className={classNames('cursor-pointer', 'nitro-icon', (!isZoomedIn && 'icon-zoom-less'), (isZoomedIn && 'icon-zoom-more'))} title={LocalizeText('room.zoom.button.text')} onClick={() => handleToolClick('zoom')} />
|
||||
<div className="cursor-pointer nitro-icon icon-chat-history" title={LocalizeText('room.chathistory.button.text')} onClick={() => handleToolClick('chat_history')} />
|
||||
<div className={classNames('cursor-pointer', 'nitro-icon', (areBubblesMuted ? 'icon-chat-disablebubble' : 'icon-chat-enablebubble'))} title={areBubblesMuted ? LocalizeText('room.unmute.button.text') : LocalizeText('room.mute.button.text')} onClick={() => handleToolClick('hiddenbubbles')} />
|
||||
useEffect(() => {
|
||||
const handleTabClose = () => {
|
||||
window.localStorage.removeItem('nitro.room.history');
|
||||
};
|
||||
window.addEventListener('beforeunload', handleTabClose);
|
||||
return () => window.removeEventListener('beforeunload', handleTabClose);
|
||||
}, []);
|
||||
|
||||
{navigatorData.canRate && (
|
||||
<div className="cursor-pointer nitro-icon icon-like-room" title={LocalizeText('room.like.button.text')} onClick={() => handleToolClick('like_room')} />
|
||||
)}
|
||||
<div className="cursor-pointer nitro-icon icon-room-link" title={LocalizeText('navigator.embed.caption')} onClick={() => handleToolClick('toggle_room_link')} />
|
||||
<div className="cursor-pointer nitro-icon icon-room-history-enabled" title={LocalizeText('room.history.button.tooltip')} onClick={() => handleToolClick('room_history')} />
|
||||
{plugins.map(plugin => (
|
||||
<div
|
||||
key={plugin.name}
|
||||
className={`cursor-pointer nitro-icon ${plugin.icon || 'icon-cog'}`}
|
||||
title={plugin.label}
|
||||
onClick={() => plugin.onOpen()}
|
||||
/>
|
||||
))}
|
||||
</motion.div> }
|
||||
</AnimatePresence>
|
||||
return (
|
||||
<div className="flex space-x-2 nitro-room-tools-container">
|
||||
<div className="flex flex-col items-center justify-center p-2 nitro-room-tools">
|
||||
<div className="cursor-pointer nitro-icon icon-cog" title={LocalizeText('room.settings.button.text')} onClick={() => handleToolClick('settings')} />
|
||||
<div className={classNames('cursor-pointer', 'nitro-icon', (!isZoomedIn && 'icon-zoom-less'), (isZoomedIn && 'icon-zoom-more'))} title={LocalizeText('room.zoom.button.text')} onClick={() => handleToolClick('zoom')} />
|
||||
<div className="cursor-pointer nitro-icon icon-chat-history" title={LocalizeText('room.chathistory.button.text')} onClick={() => handleToolClick('chat_history')} />
|
||||
<div className={classNames('cursor-pointer', 'nitro-icon', (areBubblesMuted ? 'icon-chat-disablebubble' : 'icon-chat-enablebubble'))} title={areBubblesMuted ? LocalizeText('room.unmute.button.text') : LocalizeText('room.mute.button.text')} onClick={() => handleToolClick('hiddenbubbles')} />
|
||||
|
||||
{navigatorData.canRate && (
|
||||
<div className="cursor-pointer nitro-icon icon-like-room" title={LocalizeText('room.like.button.text')} onClick={() => handleToolClick('like_room')} />
|
||||
)}
|
||||
<div className="cursor-pointer nitro-icon icon-room-link" title={LocalizeText('navigator.embed.caption')} onClick={() => handleToolClick('toggle_room_link')} />
|
||||
<div className="cursor-pointer nitro-icon icon-room-history-enabled" title={LocalizeText('room.history.button.tooltip')} onClick={() => handleToolClick('room_history')} />
|
||||
{plugins.map(plugin => (
|
||||
<div
|
||||
key={plugin.name}
|
||||
className={`cursor-pointer nitro-icon ${plugin.icon || 'icon-cog'}`}
|
||||
title={plugin.label}
|
||||
onClick={() => plugin.onOpen()}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col justify-center nitro-room-tools-side-container">
|
||||
<div className="flex flex-col justify-center">
|
||||
<AnimatePresence>
|
||||
{(!isCollapsed && (isOpen || !!roomName || !!roomOwner || !!(roomTags && roomTags.length))) && (
|
||||
{isOpen && (
|
||||
<motion.div initial={{ x: -100 }} animate={{ x: 0 }} exit={{ x: -100 }} transition={{ duration: 0.3 }}>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<div className="flex flex-col px-3 py-2 rounded nitro-room-tools-info">
|
||||
@@ -171,7 +161,7 @@ export const RoomToolsWidgetView: FC<{}> = props => {
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
{(!isCollapsed && isOpenHistory) && (
|
||||
{isOpenHistory && (
|
||||
<motion.div initial={{ x: -100 }} animate={{ x: 0 }} exit={{ x: -100 }} transition={{ duration: 0.3 }} className="nitro-room-tools-history">
|
||||
<div className="flex flex-col px-3 py-2 rounded nitro-room-history">
|
||||
{roomHistory.map(history => (
|
||||
|
||||
Reference in New Issue
Block a user