Merge branch 'merge/duckietm-main-20260407'

This commit is contained in:
Lorenzune
2026-04-07 17:14:27 +02:00
4 changed files with 58 additions and 69 deletions
@@ -57,9 +57,14 @@ export const CatalogGiftView: FC<{}> = props =>
const boxExtraData = useMemo(() => const boxExtraData = useMemo(() =>
{ {
if(!giftConfiguration) return ''; if(!giftConfiguration || !boxTypes.length) return '';
return ((boxTypes[selectedBoxIndex] * 1000) + giftConfiguration.ribbonTypes[selectedRibbonIndex]).toString(); const boxType = boxTypes[selectedBoxIndex];
const ribbonType = giftConfiguration.ribbonTypes[selectedRibbonIndex];
if(boxType === undefined || ribbonType === undefined) return '';
return ((boxType * 1000) + ribbonType).toString();
}, [ giftConfiguration, selectedBoxIndex, selectedRibbonIndex, boxTypes ]); }, [ giftConfiguration, selectedBoxIndex, selectedRibbonIndex, boxTypes ]);
const isColorable = useMemo(() => const isColorable = useMemo(() =>
@@ -137,6 +142,35 @@ export const CatalogGiftView: FC<{}> = props =>
useMessageEvent<GiftReceiverNotFoundEvent>(GiftReceiverNotFoundEvent, event => setReceiverNotFound(true)); useMessageEvent<GiftReceiverNotFoundEvent>(GiftReceiverNotFoundEvent, event => setReceiverNotFound(true));
const initializeGiftData = useCallback(() =>
{
if(!giftConfiguration) return;
const newBoxTypes = [ ...giftConfiguration.boxTypes ];
newBoxTypes.push(giftConfiguration.defaultStuffTypes[Math.floor((Math.random() * (giftConfiguration.defaultStuffTypes.length - 1)))]);
setBoxTypes(newBoxTypes);
setMaxBoxIndex(newBoxTypes.length - 1);
setMaxRibbonIndex(newBoxTypes.length - 1);
setSelectedBoxIndex(0);
setSelectedRibbonIndex(0);
const newColors: { id: number, color: string }[] = [];
for(const colorId of giftConfiguration.stuffTypes)
{
const giftData = GetSessionDataManager().getFloorItemData(colorId);
if(!giftData) continue;
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: ColorUtils.makeColorNumberHex(giftData.colors[0]) });
}
setColors(newColors);
if(newColors.length) setSelectedColorId(newColors[0].id);
}, [ giftConfiguration ]);
useUiEvent([ useUiEvent([
CatalogPurchasedEvent.PURCHASE_SUCCESS, CatalogPurchasedEvent.PURCHASE_SUCCESS,
CatalogEvent.INIT_GIFT ], event => CatalogEvent.INIT_GIFT ], event =>
@@ -155,6 +189,7 @@ export const CatalogGiftView: FC<{}> = props =>
setPageId(castedEvent.pageId); setPageId(castedEvent.pageId);
setOfferId(castedEvent.offerId); setOfferId(castedEvent.offerId);
setExtraData(castedEvent.extraData); setExtraData(castedEvent.extraData);
initializeGiftData();
setIsVisible(true); setIsVisible(true);
return; return;
} }
@@ -165,55 +200,14 @@ export const CatalogGiftView: FC<{}> = props =>
setReceiverNotFound(false); setReceiverNotFound(false);
}, [ receiverName ]); }, [ receiverName ]);
const createBoxTypes = useCallback(() =>
{
if(!giftConfiguration) return;
setBoxTypes(prev =>
{
let newPrev = [ ...giftConfiguration.boxTypes ];
newPrev.push(giftConfiguration.defaultStuffTypes[Math.floor((Math.random() * (giftConfiguration.defaultStuffTypes.length - 1)))]);
setMaxBoxIndex(newPrev.length - 1);
setMaxRibbonIndex(newPrev.length - 1);
return newPrev;
});
}, [ giftConfiguration ]);
useEffect(() => useEffect(() =>
{ {
if(!giftConfiguration) return; if(!isVisible || !giftConfiguration) return;
const newColors: { id: number, color: string }[] = []; initializeGiftData();
}, [ giftConfiguration, isVisible, initializeGiftData ]);
for(const colorId of giftConfiguration.stuffTypes) if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible || !boxTypes.length) return null;
{
const giftData = GetSessionDataManager().getFloorItemData(colorId);
if(!giftData) continue;
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: ColorUtils.makeColorNumberHex(giftData.colors[0]) });
}
createBoxTypes();
if(newColors.length)
{
setSelectedColorId(newColors[0].id);
setColors(newColors);
}
}, [ giftConfiguration, createBoxTypes ]);
useEffect(() =>
{
if(!isVisible) return;
createBoxTypes();
}, [ createBoxTypes, isVisible ]);
if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null;
const boxName = 'catalog.gift_wrapping_new.box.' + (isBoxDefault ? 'default' : boxTypes[selectedBoxIndex]); const boxName = 'catalog.gift_wrapping_new.box.' + (isBoxDefault ? 'default' : boxTypes[selectedBoxIndex]);
const ribbonName = `catalog.gift_wrapping_new.ribbon.${ selectedRibbonIndex }`; const ribbonName = `catalog.gift_wrapping_new.ribbon.${ selectedRibbonIndex }`;
@@ -242,13 +236,13 @@ export const CatalogGiftView: FC<{}> = props =>
<label className="form-check-label">{ LocalizeText('catalog.gift_wrapping.show_face.title') }</label> <label className="form-check-label">{ LocalizeText('catalog.gift_wrapping.show_face.title') }</label>
</div> </div>
<div className="items-center gap-2"> <div className="items-center gap-2">
{ selectedColorId &&
<div className="gift-preview"> <div className="gift-preview">
<LayoutFurniImageView extraData={ boxExtraData } productClassId={ colourId } productType={ ProductTypeEnum.FLOOR } /> { (colourId > 0 && boxExtraData) &&
</div> } <LayoutFurniImageView extraData={ boxExtraData } productClassId={ colourId } productType={ ProductTypeEnum.FLOOR } /> }
</div>
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex gap-2"> <div className="flex items-center gap-2">
<div className="relative inline-flex align-middle"> <div className="inline-flex">
<Button variant="primary" onClick={ () => handleAction('prev_box') }> <Button variant="primary" onClick={ () => handleAction('prev_box') }>
<FaChevronLeft className="fa-icon" /> <FaChevronLeft className="fa-icon" />
</Button> </Button>
@@ -264,8 +258,8 @@ export const CatalogGiftView: FC<{}> = props =>
</div> </div>
</div> </div>
</div> </div>
<Flex alignItems="center" className={ isColorable ? '' : 'opacity-50 pointer-events-none' } gap={ 2 }> <div className={ `flex items-center gap-2 ${ isColorable ? '' : 'opacity-50 pointer-events-none' }` }>
<div className="relative inline-flex align-middle"> <div className="inline-flex">
<Button variant="primary" onClick={ () => handleAction('prev_ribbon') }> <Button variant="primary" onClick={ () => handleAction('prev_ribbon') }>
<FaChevronLeft className="fa-icon" /> <FaChevronLeft className="fa-icon" />
</Button> </Button>
@@ -274,7 +268,7 @@ export const CatalogGiftView: FC<{}> = props =>
</Button> </Button>
</div> </div>
<Text fontWeight="bold">{ LocalizeText(ribbonName) }</Text> <Text fontWeight="bold">{ LocalizeText(ribbonName) }</Text>
</Flex> </div>
</div> </div>
</div> </div>
<Column className={ isColorable ? '' : 'opacity-50 pointer-events-none' } gap={ 1 }> <Column className={ isColorable ? '' : 'opacity-50 pointer-events-none' } gap={ 1 }>
@@ -1,11 +1,10 @@
import { RoomObjectCategory } from '@nitrots/nitro-renderer'; import { RoomObjectCategory } from '@nitrots/nitro-renderer';
import { FC } from 'react'; import { FC } from 'react';
import { LocalizeText } from '../../../../api'; import { LocalizeText } from '../../../../api';
import { Column, Text } from '../../../../common'; import { Column, DraggableWindow, Text } from '../../../../common';
import { useFurnitureHighScoreWidget } from '../../../../hooks'; import { useFurnitureHighScoreWidget } from '../../../../hooks';
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView'; import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
import { ContextMenuListView } from '../context-menu/ContextMenuListView'; import { ContextMenuListView } from '../context-menu/ContextMenuListView';
import { ObjectLocationView } from '../object-location/ObjectLocationView';
export const FurnitureHighScoreView: FC<{}> = props => export const FurnitureHighScoreView: FC<{}> = props =>
{ {
@@ -18,14 +17,14 @@ export const FurnitureHighScoreView: FC<{}> = props =>
{ Array.from(stuffDatas.entries()).map(([ objectId, stuffData ], index) => { Array.from(stuffDatas.entries()).map(([ objectId, stuffData ], index) =>
{ {
return ( return (
<ObjectLocationView key={ index } category={ RoomObjectCategory.FLOOR } objectId={ objectId }> <DraggableWindow key={ index } uniqueKey={ `high-score-${ objectId }` }>
<Column className="nitro-widget-high-score nitro-context-menu" gap={ 0 }> <Column className="nitro-widget-high-score nitro-context-menu bg-[#1e1f23] p-2 w-[280px] max-w-[280px] h-[320px]" gap={ 0 }>
<ContextMenuHeaderView> <ContextMenuHeaderView classNames={ [ 'drag-handler cursor-move' ] }>
{ LocalizeText('high.score.display.caption', [ 'scoretype', 'cleartype' ], [ LocalizeText(`high.score.display.scoretype.${ getScoreType(stuffData.scoreType) }`), LocalizeText(`high.score.display.cleartype.${ getClearType(stuffData.clearType) }`) ]) } { LocalizeText('high.score.display.caption', [ 'scoretype', 'cleartype' ], [ LocalizeText(`high.score.display.scoretype.${ getScoreType(stuffData.scoreType) }`), LocalizeText(`high.score.display.cleartype.${ getClearType(stuffData.clearType) }`) ]) }
</ContextMenuHeaderView> </ContextMenuHeaderView>
<ContextMenuListView className="h-full" gap={ 1 } overflow="hidden"> <ContextMenuListView className="!h-auto" gap={ 1 } overflow="hidden">
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex items-center"> <div className="flex items-center justify-between">
<Text bold center className="col-span-8" variant="white"> <Text bold center className="col-span-8" variant="white">
{ LocalizeText('high.score.display.users.header') } { LocalizeText('high.score.display.users.header') }
</Text> </Text>
@@ -39,7 +38,7 @@ export const FurnitureHighScoreView: FC<{}> = props =>
{ stuffData.entries.map((entry, index) => { stuffData.entries.map((entry, index) =>
{ {
return ( return (
<div key={ index } className="flex items-center"> <div key={ index } className="flex items-center justify-between">
<Text center className="col-span-8" variant="white"> <Text center className="col-span-8" variant="white">
{ entry.users.join(', ') } { entry.users.join(', ') }
</Text> </Text>
@@ -52,7 +51,7 @@ export const FurnitureHighScoreView: FC<{}> = props =>
</Column> </Column>
</ContextMenuListView> </ContextMenuListView>
</Column> </Column>
</ObjectLocationView> </DraggableWindow>
); );
}) } }) }
</> </>
View File
-4
View File
@@ -429,10 +429,6 @@
} }
.nitro-widget-high-score { .nitro-widget-high-score {
width: 280px;
max-width: 280px;
height: 320px;
border-radius: 0.3rem; border-radius: 0.3rem;
border: solid 1px #000; border: solid 1px #000;