Merge branch '@update/react-18' into @update/friends

This commit is contained in:
Bill 2022-04-02 01:44:08 -04:00
commit 6f865f05ec
240 changed files with 3517 additions and 3697 deletions

View File

@ -1,86 +0,0 @@
module.exports = {
'extends': [
'react-app',
'react-app/jest'
],
'rules': {
'linebreak-style': [
'off'
],
'quotes': [
'error',
'single'
],
'brace-style': [
'error',
'allman',
{
'allowSingleLine': true
}
],
'object-curly-spacing': [
'error',
'always'
],
'keyword-spacing': [
'error',
{
'overrides': {
'if': {
'after': false
},
'for': {
'after': false
},
'while': {
'after': false
},
'switch': {
'after': false
}
}
}
],
'@typescript-eslint/no-explicit-any': [
'off'
],
'@typescript-eslint/ban-ts-comment': [
'off'
],
'@typescript-eslint/no-empty-function': [
'error',
{
'allow': [
'functions',
'arrowFunctions',
'generatorFunctions',
'methods',
'generatorMethods',
'constructors'
]
}
],
'@typescript-eslint/no-unused-vars': [
'off'
],
'@typescript-eslint/ban-types': [
'error',
{
'types': {
'String': true,
'Boolean': true,
'Number': true,
'Symbol': true,
'{}': false,
'Object': false,
'object': false,
'Function': false
},
'extendDefaults': true
}
],
'no-switch-case-fall-through': [
'off'
]
}
}

55
.eslintrc.json Normal file
View File

@ -0,0 +1,55 @@
{
"settings": {
"react": {
"pragma": "React",
"version": "18.0.0"
}
},
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
"linebreak-style": [ "off" ],
"quotes": [ "error", "single" ],
"@typescript-eslint/indent": [ "error", 4, { "SwitchCase": 1 } ],
"array-bracket-spacing": [ "error", "always" ],
"brace-style": [ "error", "allman" ],
"react/prop-types": [ "off" ],
"object-curly-spacing": [ "error", "always" ],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"String": true,
"Boolean": true,
"Number": true,
"Symbol": true,
"{}": false,
"Object": false,
"object": false,
"Function": false
},
"extendDefaults": true
}
],
"no-switch-case-fall-through": [ "off" ]
}
}

View File

@ -1 +0,0 @@
*.scss

View File

@ -14,5 +14,7 @@
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"editor.wordWrap": "on",
"emmet.showExpandedAbbreviation": "never"
"emmet.showExpandedAbbreviation": "never",
"eslint.validate": [ "javascript", "javascriptreact", "html", "typescriptreact" ],
"eslint.workingDirectories": [ "./src" ]
}

View File

@ -7,7 +7,8 @@
"build": "cross-env SKIP_PREFLIGHT_CHECK=true GENERATE_SOURCEMAP=false IMAGE_INLINE_SIZE_LIMIT=100000 craco build",
"build:prod": "npx browserslist@latest --update-db && yarn build",
"test": "craco test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"eslint": "eslint src --ext .ts,.tsx"
},
"dependencies": {
"@craco/craco": "^6.3.0",
@ -20,11 +21,11 @@
"cross-env": "^7.0.3",
"emoji-toolkit": "^6.6.0",
"node-sass": "^6.0.1",
"react": "^17.0.2",
"react": "^18.0.0",
"react-bootstrap": "^2.2.2",
"react-dom": "^17.0.2",
"react-dom": "^18.0.0",
"react-scripts": "4.0.3",
"react-slider": "^1.3.1",
"react-slider": "^2.0.0",
"react-transition-group": "^4.4.2",
"react-virtualized": "^9.22.3",
"react-youtube": "^7.13.1",
@ -41,7 +42,13 @@
"@types/react-slider": "^1.3.1",
"@types/react-transition-group": "^4.4.2",
"@types/react-virtualized": "^9.21.13",
"@typescript-eslint/eslint-plugin": "^4.29.1",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"eslint": "^8.12.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"react-error-overlay": "6.0.9"
}
}

View File

@ -6,5 +6,6 @@ export class MessengerSettings
public userFriendLimit: number = 0,
public normalFriendLimit: number = 0,
public extendedFriendLimit: number = 0,
public categories: FriendCategoryData[] = []) {}
public categories: FriendCategoryData[] = [])
{}
}

View File

@ -10,5 +10,6 @@ export class TradeUserData
public itemCount: number = 0,
public creditsCount: number = 0,
public accepts: boolean = false,
public canTrade: boolean = false) {}
public canTrade: boolean = false)
{}
}

View File

@ -3,7 +3,6 @@ export interface IUnseenItemTracker
dispose(): void;
resetCategory(category: number): boolean;
resetItems(category: number, itemIds: number[]): boolean;
resetCategoryIfEmpty(category: number): boolean;
isUnseen(category: number, itemId: number): boolean;
removeUnseen(category: number, itemId: number): boolean;
getIds(category: number): number[];

View File

@ -2,7 +2,6 @@ import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { Base } from '..';
import { BatchUpdates } from '../../hooks';
import { DraggableWindowPosition } from './DraggableWindowPosition';
const CURRENT_WINDOWS: HTMLElement[] = [];
@ -134,12 +133,9 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
offsetX = (document.body.offsetWidth - elementRef.current.offsetWidth) - elementRef.current.offsetLeft;
}
BatchUpdates(() =>
{
setDelta({ x: 0, y: 0 });
setOffset({ x: offsetX, y: offsetY });
setIsDragging(false);
});
if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY });
}, [ dragHandler, delta, offset, uniqueKey ]);
@ -201,11 +197,8 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
}
}
BatchUpdates(() =>
{
setDelta({ x: 0, y: 0 });
setOffset({ x: offsetX, y: offsetY });
});
return () =>
{
@ -213,7 +206,7 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
if(index >= 0) CURRENT_WINDOWS.splice(index, 1);
}
}, [ handleSelector, windowPosition, uniqueKey, disableDrag, bringToTop ]);
}, [ handleSelector, windowPosition, uniqueKey, disableDrag, offsetLeft, offsetTop, bringToTop ]);
useEffect(() =>
{

View File

@ -67,7 +67,8 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
setRandomValue(Math.random());
},
dispose: () => {},
dispose: () =>
{},
disposed: false
}, null);

View File

@ -8,15 +8,11 @@ interface LayoutLimitedEditionStyledNumberViewProps
export const LayoutLimitedEditionStyledNumberView: FC<LayoutLimitedEditionStyledNumberViewProps> = props =>
{
const { value = 0 } = props;
const numbers = value.toString().split('');
return (
<>
{ numbers.map((number, index) =>
{
return <i key={ index } className={ 'limited-edition-number n-' + number } />;
})}
{ numbers.map((number, index) => <i key={ index } className={ 'limited-edition-number n-' + number } />) }
</>
);
}

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { AchievementCategory, AddEventLinkTracker, CloneObject, GetAchievementCategoryImageUrl, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
import { AchievementsUIUnseenCountEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { AchievementCategoryView } from './views/AchievementCategoryView';
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
@ -92,11 +92,8 @@ export const AchievementsView: FC<{}> = props =>
existing.achievements.push(achievement);
}
BatchUpdates(() =>
{
setAchievementCategories(categories);
setIsInitalized(true);
});
}, []);
UseMessageEventHook(AchievementsEvent, onAchievementsEvent);

View File

@ -4,5 +4,6 @@ export class CameraPicture
{
constructor(
public texture: NitroTexture,
public imageUrl: string) {}
public imageUrl: string)
{}
}

View File

@ -2,5 +2,6 @@ export class CameraPictureThumbnail
{
constructor(
public effectName: string,
public thumbnailUrl: string) {}
public thumbnailUrl: string)
{}
}

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { InventoryEvent } from '../../../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
import { DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
export interface CameraWidgetCheckoutViewProps
{
@ -26,12 +26,9 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
const publishDisabled = useMemo(() => GetConfiguration<boolean>('camera.publish.disabled', false), []);
const onCameraPurchaseOKMessageEvent = useCallback((event: CameraPurchaseOKMessageEvent) =>
{
BatchUpdates(() =>
{
setPicturesBought(value => (value + 1));
setIsWaiting(false);
});
}, []);
UseMessageEventHook(CameraPurchaseOKMessageEvent, onCameraPurchaseOKMessageEvent);
@ -40,13 +37,10 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
{
const parser = event.getParser();
BatchUpdates(() =>
{
setPublishUrl(parser.extraDataId);
setPublishCooldown(parser.secondsToWait);
setWasPicturePublished(parser.ok);
setIsWaiting(false);
});
}, []);
UseMessageEventHook(CameraPublishStatusMessageEvent, onCameraPublishStatusMessageEvent);

View File

@ -1,7 +1,7 @@
import { CampaignCalendarData, CampaignCalendarDataMessageEvent, CampaignCalendarDoorOpenedMessageEvent, OpenCampaignCalendarDoorAsStaffComposer, OpenCampaignCalendarDoorComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { AddEventLinkTracker, CalendarItem, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
import { BatchUpdates, UseMessageEventHook } from '../../hooks';
import { UseMessageEventHook } from '../../hooks';
import { CalendarView } from './CalendarView';
export const CampaignView: FC<{}> = props =>
@ -30,8 +30,6 @@ export const CampaignView: FC<{}> = props =>
const lastAttempt = lastOpenAttempt;
if(parser.doorOpened)
{
BatchUpdates(() =>
{
setCalendarData(prev =>
{
@ -48,7 +46,6 @@ export const CampaignView: FC<{}> = props =>
return copy;
});
});
}
setLastOpenAttempt(-1);

View File

@ -3,7 +3,7 @@ import { GuildMembershipsMessageEvent } from '@nitrots/nitro-renderer/src/nitro/
import { FC, useCallback } from 'react';
import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, NotificationAlertType, NotificationUtilities, ProductTypeEnum } from '../../api';
import { CatalogGiftReceiverNotFoundEvent, CatalogNameResultEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { useCatalogContext } from './CatalogContext';
import { CatalogNode } from './common/CatalogNode';
import { CatalogPetPalette } from './common/CatalogPetPalette';
@ -43,11 +43,8 @@ export const CatalogMessageHandler: FC<{}> = props =>
return catalogNode;
}
BatchUpdates(() =>
{
setRootNode(getCatalogNode(parser.root, 0, null));
setOffersToNodes(offers);
});
}, [ setRootNode, setOffersToNodes ]);
const onCatalogPageMessageEvent = useCallback((event: CatalogPageMessageEvent) =>
@ -77,8 +74,6 @@ export const CatalogMessageHandler: FC<{}> = props =>
if((currentType === CatalogType.NORMAL) || ((purchasableOffer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (purchasableOffer.pricingModel !== Offer.PRICING_MODEL_MULTI))) purchasableOffers.push(purchasableOffer);
}
BatchUpdates(() =>
{
if(parser.frontPageItems && parser.frontPageItems.length) setFrontPageItems(parser.frontPageItems);
setIsBusy(false);
@ -87,7 +82,6 @@ export const CatalogMessageHandler: FC<{}> = props =>
{
showCatalogPage(parser.pageId, parser.layoutCode, new PageLocalization(parser.localization.images.concat(), parser.localization.texts.concat()), purchasableOffers, parser.offerId, parser.acceptSeasonCurrencyAsCredits);
}
});
}, [ currentType, pageId, setFrontPageItems, setIsBusy, showCatalogPage ]);
const onPurchaseOKMessageEvent = useCallback((event: PurchaseOKMessageEvent) =>

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
import { AddEventLinkTracker, GetRoomEngine, LocalizeText, NotificationAlertType, NotificationUtilities, PlaySound, RemoveLinkEventTracker, SendMessageComposer, SoundNames } from '../../api';
import { Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { CatalogPurchasedEvent } from '../../events';
import { BatchUpdates, UseMessageEventHook, UseUiEvent } from '../../hooks';
import { UseMessageEventHook, UseUiEvent } from '../../hooks';
import { CatalogContextProvider } from './CatalogContext';
import { CatalogMessageHandler } from './CatalogMessageHandler';
import { CatalogPage } from './common/CatalogPage';
@ -43,8 +43,6 @@ export const CatalogView: FC<{}> = props =>
const [ catalogOptions, setCatalogOptions ] = useState<ICatalogOptions>({});
const resetState = useCallback(() =>
{
BatchUpdates(() =>
{
setPageId(-1);
setPreviousPageId(-1);
@ -56,7 +54,6 @@ export const CatalogView: FC<{}> = props =>
setSearchResult(null);
setFrontPageItems([]);
setIsVisible(false);
});
}, []);
const onCatalogPublishedMessageEvent = useCallback((event: CatalogPublishedMessageEvent) =>
@ -119,11 +116,8 @@ export const CatalogView: FC<{}> = props =>
{
if(pageId < 0) return;
BatchUpdates(() =>
{
setIsBusy(true);
setPageId(pageId);
});
if(pageId > -1) SendMessageComposer(new GetCatalogPageComposer(pageId, offerId, currentType));
}, [ currentType ]);
@ -132,8 +126,6 @@ export const CatalogView: FC<{}> = props =>
{
const catalogPage = (new CatalogPage(pageId, layoutCode, localization, offers, acceptSeasonCurrencyAsCredits) as ICatalogPage);
BatchUpdates(() =>
{
setCurrentPage(catalogPage);
setPreviousPageId(prevValue => ((pageId !== -1) ? pageId : prevValue));
setNavigationHidden(false);
@ -149,7 +141,6 @@ export const CatalogView: FC<{}> = props =>
break;
}
}
});
}, []);
const activateNode = useCallback((targetNode: ICatalogNode, offerId: number = -1) =>
@ -213,8 +204,6 @@ export const CatalogView: FC<{}> = props =>
}, [ setActiveNodes, loadCatalogPage ]);
const openPageById = useCallback((id: number) =>
{
BatchUpdates(() =>
{
setSearchResult(null);
@ -230,12 +219,9 @@ export const CatalogView: FC<{}> = props =>
if(node) activateNode(node);
}
});
}, [ isVisible, rootNode, getNodeById, activateNode ]);
const openPageByName = useCallback((name: string) =>
{
BatchUpdates(() =>
{
setSearchResult(null);
@ -251,12 +237,9 @@ export const CatalogView: FC<{}> = props =>
if(node) activateNode(node);
}
});
}, [ isVisible, rootNode, getNodeByName, activateNode ]);
const openPageByOfferId = useCallback((offerId: number) =>
{
BatchUpdates(() =>
{
setSearchResult(null);
@ -274,7 +257,6 @@ export const CatalogView: FC<{}> = props =>
activateNode(nodes[0], offerId);
}
});
}, [ isVisible, getNodesByOfferId, activateNode ]);
const onCatalogPurchasedEvent = useCallback((event: CatalogPurchasedEvent) =>
@ -415,7 +397,10 @@ export const CatalogView: FC<{}> = props =>
<CatalogMessageHandler />
{ isVisible &&
<NitroCardView uniqueKey="catalog" className="nitro-catalog">
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event => { setIsVisible(false); } } />
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event =>
{
setIsVisible(false);
} } />
<NitroCardTabsView>
{ rootNode && (rootNode.children.length > 0) && rootNode.children.map(child =>
{

View File

@ -5,5 +5,6 @@ export class CatalogPetPalette
constructor(
public readonly breed: string,
public readonly palettes: SellablePetPaletteData[]
) {}
)
{}
}

View File

@ -6,6 +6,6 @@ export class SearchResult
constructor(
public readonly searchValue: string,
public readonly offers: IPurchasableOffer[],
public readonly filteredNodes: ICatalogNode[]
) {}
public readonly filteredNodes: ICatalogNode[])
{}
}

View File

@ -8,7 +8,8 @@ export class SubscriptionInfo
public readonly clubPeriods: number = 0,
public readonly isVip: boolean = false,
public readonly pastDays: number = 0,
public readonly pastVipDays: number = 0) {}
public readonly pastVipDays: number = 0)
{}
public get lastUpdated(): number
{

View File

@ -5,7 +5,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { GetSessionDataManager, LocalizeText, ProductTypeEnum, SendMessageComposer } from '../../../../api';
import { Base, Button, ButtonGroup, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events';
import { BatchUpdates, UseUiEvent } from '../../../../hooks';
import { UseUiEvent } from '../../../../hooks';
import { useCatalogContext } from '../../CatalogContext';
export const CatalogGiftView: FC<{}> = props =>
@ -28,8 +28,6 @@ export const CatalogGiftView: FC<{}> = props =>
const { giftConfiguration = null } = catalogOptions;
const close = useCallback(() =>
{
BatchUpdates(() =>
{
setIsVisible(false);
setPageId(0);
@ -42,7 +40,6 @@ export const CatalogGiftView: FC<{}> = props =>
setSelectedRibbonIndex(0);
if(colors.length) setSelectedColorId(colors[0].id);
});
}, [ colors ]);
const onCatalogEvent = useCallback((event: CatalogEvent) =>
@ -55,15 +52,12 @@ export const CatalogGiftView: FC<{}> = props =>
case CatalogEvent.INIT_GIFT:
const castedEvent = (event as CatalogInitGiftEvent);
BatchUpdates(() =>
{
close();
setPageId(castedEvent.pageId);
setOfferId(castedEvent.offerId);
setExtraData(castedEvent.extraData);
setIsVisible(true);
});
return;
case CatalogEvent.GIFT_RECEIVER_NOT_FOUND:
setReceiverNotFound(true);
@ -144,8 +138,6 @@ export const CatalogGiftView: FC<{}> = props =>
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${giftData.colors[0].toString(16)}` });
}
BatchUpdates(() =>
{
setMaxBoxIndex(giftConfiguration.boxTypes.length - 1);
setMaxRibbonIndex(giftConfiguration.ribbonTypes.length - 1);
@ -154,7 +146,6 @@ export const CatalogGiftView: FC<{}> = props =>
setSelectedColorId(newColors[0].id);
setColors(newColors);
}
});
}, [ giftConfiguration ]);
if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null;

View File

@ -3,7 +3,7 @@ import { RedeemVoucherMessageComposer, VoucherRedeemErrorMessageEvent, VoucherRe
import { FC, useCallback, useState } from 'react';
import { LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../../api';
import { Button, Flex } from '../../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../../hooks';
import { UseMessageEventHook } from '../../../../../hooks';
export interface CatalogRedeemVoucherViewProps
{
@ -35,11 +35,8 @@ export const CatalogRedeemVoucherView: FC<CatalogRedeemVoucherViewProps> = props
NotificationUtilities.simpleAlert(message, null, null, null, LocalizeText('catalog.alert.voucherredeem.ok.title'));
BatchUpdates(() =>
{
setIsWaiting(false);
setVoucher('');
});
}, []);
UseMessageEventHook(VoucherRedeemOkMessageEvent, onVoucherRedeemOkMessageEvent);

View File

@ -4,7 +4,6 @@ import { FC, useCallback, useEffect, useState } from 'react';
import { GetSessionDataManager, LocalizeText } from '../../../../../api';
import { Button } from '../../../../../common/Button';
import { Flex } from '../../../../../common/Flex';
import { BatchUpdates } from '../../../../../hooks';
import { useCatalogContext } from '../../../CatalogContext';
import { CatalogPage } from '../../../common/CatalogPage';
import { CatalogType } from '../../../common/CatalogType';
@ -23,8 +22,6 @@ export const CatalogSearchView: FC<{}> = props =>
const { currentType = null, rootNode = null, setActiveNodes = null, offersToNodes = null, searchResult = null, setSearchResult = null, setCurrentPage = null } = useCatalogContext();
const updateSearchValue = (value: string) =>
{
BatchUpdates(() =>
{
if(!value || !value.length)
{
@ -37,7 +34,6 @@ export const CatalogSearchView: FC<{}> = props =>
setSearchValue(value);
setNeedsProcessing(true);
}
});
}
const processSearch = useCallback((search: string) =>
@ -96,11 +92,8 @@ export const CatalogSearchView: FC<{}> = props =>
FilterCatalogNode(search, foundFurniLines, rootNode, nodes);
BatchUpdates(() =>
{
setCurrentPage((new CatalogPage(-1, 'default_3x3', new PageLocalization([], []), offers, false, 1) as ICatalogPage));
setSearchResult(new SearchResult(search, offers, nodes.filter(node => (node.isVisible))));
});
}, [ offersToNodes, currentType, rootNode, setCurrentPage, setSearchResult ]);
useEffect(() =>

View File

@ -1,8 +1,8 @@
import { CancelMarketplaceOfferMessageComposer, GetMarketplaceOwnOffersMessageComposer, MarketplaceCancelOfferResultEvent, MarketplaceOwnOffersEvent, RedeemMarketplaceOfferCreditsMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useMemo, useState } from 'react';
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api';
import { Button, Column, Text } from '../../../../../../common';
import { BatchUpdates, UseMessageEventHook, UseMountEffect } from '../../../../../../hooks';
import { UseMessageEventHook } from '../../../../../../hooks';
import { CatalogLayoutProps } from '../CatalogLayout.types';
import { CatalogLayoutMarketplaceItemView, OWN_OFFER } from './CatalogLayoutMarketplaceItemView';
import { MarketplaceOfferData } from './common/MarketplaceOfferData';
@ -28,11 +28,8 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutProps> = prop
return newOffer;
});
BatchUpdates(() =>
{
setCreditsWaiting(parser.creditsWaiting);
setOffers(offers);
});
}, []);
UseMessageEventHook(MarketplaceOwnOffersEvent, onMarketPlaceOwnOffersEvent);
@ -77,10 +74,10 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutProps> = prop
SendMessageComposer(new CancelMarketplaceOfferMessageComposer(offerData.offerId));
};
UseMountEffect(() =>
useEffect(() =>
{
SendMessageComposer(new GetMarketplaceOwnOffersMessageComposer());
});
}, []);
return (
<Column overflow="hidden">

View File

@ -2,7 +2,7 @@ import { BuyMarketplaceOfferMessageComposer, GetMarketplaceOffersMessageComposer
import { FC, useCallback, useMemo, useState } from 'react';
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api';
import { Button, ButtonGroup, Column, Text } from '../../../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../../../hooks';
import { UseMessageEventHook } from '../../../../../../hooks';
import { GetCurrencyAmount } from '../../../../../purse/common/CurrencyHelper';
import { CatalogLayoutProps } from '../CatalogLayout.types';
import { CatalogLayoutMarketplaceItemView, PUBLIC_OFFER } from './CatalogLayoutMarketplaceItemView';
@ -75,12 +75,8 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
latestOffers.set(entry.offerId, offerEntry);
});
BatchUpdates(() =>
{
setTotalItemsFound(parser.totalItemsFound);
setOffers(latestOffers);
});
}, []);
const onMarketplaceBuyOfferResultEvent = useCallback( (event: MarketplaceBuyOfferResultEvent) =>

View File

@ -64,7 +64,10 @@ export const MarketplacePostOfferView : FC<{}> = props =>
SendMessageComposer(new MakeOfferMessageComposer(askingPrice, item.isWallItem ? 2 : 1, item.id));
setItem(null);
},
() => { setItem(null) }, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
() =>
{
setItem(null)
}, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
}
return (

View File

@ -4,7 +4,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { LocalizeText, SendMessageComposer } from '../../../../../../api';
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, LayoutPetImageView, Text } from '../../../../../../common';
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent, CatalogWidgetEvent } from '../../../../../../events';
import { BatchUpdates, DispatchUiEvent, UseUiEvent } from '../../../../../../hooks';
import { DispatchUiEvent, UseUiEvent } from '../../../../../../hooks';
import { useCatalogContext } from '../../../../CatalogContext';
import { GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../common/CatalogUtilities';
import { CatalogAddOnBadgeWidgetView } from '../../widgets/CatalogAddOnBadgeWidgetView';
@ -122,12 +122,9 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
const offer = page.offers[0];
BatchUpdates(() =>
{
setCurrentOffer(offer);
setPetIndex(GetPetIndexFromLocalization(offer.localizationId));
setColorsShowing(false);
});
}, [ page, setCurrentOffer ]);
useEffect(() =>
@ -153,21 +150,15 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
palettes.push(palette);
}
BatchUpdates(() =>
{
setSelectedPaletteIndex((palettes.length ? 0 : -1));
setSellablePalettes(palettes);
});
return;
}
}
BatchUpdates(() =>
{
setSelectedPaletteIndex(-1);
setSellablePalettes([]);
});
SendMessageComposer(new GetSellablePetPalettesComposer(productData.type));
}, [ currentOffer, petPalettes ]);
@ -178,11 +169,8 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
const colors = GetPetAvailableColors(petIndex, sellablePalettes);
BatchUpdates(() =>
{
setSelectedColorIndex((colors.length ? 0 : -1));
setSellableColors(colors);
});
}, [ petIndex, sellablePalettes ]);
useEffect(() =>

View File

@ -14,9 +14,10 @@ interface CatalogBadgeSelectorWidgetViewProps extends AutoGridProps
export const CatalogBadgeSelectorWidgetView: FC<CatalogBadgeSelectorWidgetViewProps> = props =>
{
const { columnCount = 5, ...rest } = props;
const [ isVisible, setIsVisible ] = useState(false);
const [ currentBadgeCode, setCurrentBadgeCode ] = useState<string>(null);
const { currentOffer = null, setPurchaseOptions = null } = useCatalogContext();
const { badgeCodes = [] } = useInventoryBadges();
const { badgeCodes = [], activate = null, deactivate = null } = useInventoryBadges();
const previewStuffData = useMemo(() =>
{
@ -45,6 +46,22 @@ export const CatalogBadgeSelectorWidgetView: FC<CatalogBadgeSelectorWidgetViewPr
});
}, [ currentOffer, previewStuffData, setPurchaseOptions ]);
useEffect(() =>
{
if(!isVisible) return;
const id = activate();
return () => deactivate(id);
}, [ isVisible, activate, deactivate ]);
useEffect(() =>
{
setIsVisible(true);
return () => setIsVisible(false);
}, []);
return (
<AutoGrid columnCount={ columnCount } { ...rest }>
{ badgeCodes && (badgeCodes.length > 0) && badgeCodes.map((badgeCode, index) =>

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, ProductTypeEnum } from '../../../../../api';
import { AutoGrid, AutoGridProps, Button, ButtonGroup } from '../../../../../common';
import { BatchUpdates } from '../../../../../hooks';
import { useCatalogContext } from '../../../CatalogContext';
import { IPurchasableOffer } from '../../../common/IPurchasableOffer';
import { Offer } from '../../../common/Offer';
@ -52,12 +51,9 @@ export const CatalogSpacesWidgetView: FC<CatalogSpacesWidgetViewProps> = props =
}
}
BatchUpdates(() =>
{
setGroupedOffers(groupedOffers);
setSelectedGroupIndex(0);
setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]);
});
}, [ currentPage ]);
useEffect(() =>

View File

@ -3,7 +3,6 @@ import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized';
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
import { BatchUpdates } from '../../hooks';
import { ChatHistoryContextProvider } from './ChatHistoryContext';
import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler';
import { ChatEntryType } from './common/ChatEntryType';
@ -91,11 +90,8 @@ export const ChatHistoryView: FC<{}> = props =>
chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1));
roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1));
BatchUpdates(() =>
{
setChatHistoryState(chatState);
setRoomHistoryState(roomState);
});
return () =>
{

View File

@ -2,7 +2,7 @@ import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } fr
import { FC, useCallback, useEffect, useState } from 'react';
import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, Text, UserProfileIconView } from '../../../../common';
import { BatchUpdates, useFriends, UseMessageEventHook } from '../../../../hooks';
import { useFriends, UseMessageEventHook } from '../../../../hooks';
interface FriendsSearchViewProps extends NitroCardAccordionSetViewProps
{
@ -21,11 +21,8 @@ export const FriendsSearchView: FC<FriendsSearchViewProps> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setFriendResults(parser.friends);
setOtherResults(parser.others);
});
}, []);
UseMessageEventHook(HabboSearchResultEvent, onHabboSearchResultEvent);

View File

@ -0,0 +1,84 @@
import { FC, useMemo } from 'react';
import { GetSessionDataManager, LocalizeText } from '../../../../api';
import { Base, Flex, LayoutAvatarImageView } from '../../../../common';
import { GroupType } from '../../common/GroupType';
import { MessengerThread } from '../../common/MessengerThread';
import { MessengerThreadChat } from '../../common/MessengerThreadChat';
import { MessengerThreadChatGroup } from '../../common/MessengerThreadChatGroup';
import { getGroupChatData } from '../../common/Utils';
interface FriendsMessengerThreadGroupProps
{
thread: MessengerThread;
group: MessengerThreadChatGroup;
}
export const FriendsMessengerThreadGroup: FC<FriendsMessengerThreadGroupProps> = props =>
{
const { thread = null, group = null } = props;
const isOwnChat = useMemo(() =>
{
if(!thread || !group) return false;
if(group.type === GroupType.PRIVATE_CHAT && (group.userId === GetSessionDataManager().userId)) return true;
if( (group.type === GroupType.GROUP_CHAT) && (group.chats.length && getGroupChatData(group.chats[0].extraData).userId === GetSessionDataManager().userId)) return true;
return false;
}, [ group, thread ]);
if(!thread || !group) return null;
if(!group.userId)
{
return (
<>
{ group.chats.map((chat, index) =>
{
return (
<div key={ index } className="d-flex gap-2 w-100 justify-content-start">
<Base className="w-100 text-break">
{ chat.type === MessengerThreadChat.SECURITY_NOTIFICATION &&
<Base className="bg-light rounded mb-2 d-flex gap-2 px-2 py-1 small text-muted align-items-center">
<Base className="nitro-friends-spritesheet icon-warning flex-shrink-0" />
<Base>{ chat.message }</Base>
</Base> }
{ chat.type === MessengerThreadChat.ROOM_INVITE &&
<Base className="bg-light rounded mb-2 d-flex gap-2 px-2 py-1 small text-black align-items-center">
<Base className="messenger-notification-icon flex-shrink-0" />
<Base>{(LocalizeText('messenger.invitation') + ' ') }{ chat.message }</Base>
</Base> }
</Base>
</div>
);
}) }
</>
);
}
return (
<Flex className={ 'w-100 justify-content-' + (isOwnChat ? 'end' : 'start') } gap={ 2 }>
<Base className="message-avatar flex-shrink-0">
{ (group.type === GroupType.PRIVATE_CHAT && !isOwnChat) &&
<LayoutAvatarImageView figure={ thread.participant.figure } direction={ 2 } />
}
{ (group.type === GroupType.GROUP_CHAT && !isOwnChat) &&
<LayoutAvatarImageView figure={ getGroupChatData(group.chats[0].extraData).figure } direction={ 2} />
}
</Base>
<Base className={ 'bg-light text-black border-radius mb-2 rounded py-1 px-2 messages-group-' + (isOwnChat ? 'right' : 'left') }>
<Base className='fw-bold'>
{ (isOwnChat) && GetSessionDataManager().userName }
{ (!isOwnChat) && ((group.type === GroupType.GROUP_CHAT) ? getGroupChatData(group.chats[0].extraData).username : thread.participant.name)
}
</Base>
{ group.chats.map((chat, index) =><Base key={ index } className="text-break">{ chat.message }</Base>) }
</Base>
{ (isOwnChat) &&
<Base className="message-avatar flex-shrink-0">
<LayoutAvatarImageView figure={ GetSessionDataManager().figure } direction={ 4 } />
</Base> }
</Flex>
);
}

View File

@ -3,7 +3,7 @@ import { FollowFriendMessageComposer, ILinkEventTracker } from '@nitrots/nitro-r
import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api';
import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { BatchUpdates, useMessenger } from '../../../../hooks';
import { useMessenger } from '../../../../hooks';
import { FriendsMessengerThreadView } from './FriendsMessengerThreadView';
export const FriendsMessengerView: FC<{}> = props =>
@ -54,11 +54,8 @@ export const FriendsMessengerView: FC<{}> = props =>
if(!thread) return;
BatchUpdates(() =>
{
setActiveThread(thread);
setIsVisible(true);
});
}
}
},

View File

@ -2,7 +2,7 @@ import { GroupBuyComposer, GroupBuyDataComposer, GroupBuyDataEvent } from '@nitr
import { FC, useCallback, useEffect, useState } from 'react';
import { HasHabboClub, LocalizeText, SendMessageComposer } from '../../../api';
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
import { UseMessageEventHook } from '../../../hooks';
import { IGroupData } from '../common/IGroupData';
import { GroupTabBadgeView } from './tabs/GroupTabBadgeView';
import { GroupTabColorsView } from './tabs/GroupTabColorsView';
@ -94,18 +94,13 @@ export const GroupCreatorView: FC<GroupCreatorViewProps> = props =>
parser.availableRooms.forEach((name, id) => rooms.push({ id, name }));
BatchUpdates(() =>
{
setAvailableRooms(rooms);
setPurchaseCost(parser.groupCost);
});
}, []);
UseMessageEventHook(GroupBuyDataEvent, onGroupBuyDataEvent);
useEffect(() =>
{
BatchUpdates(() =>
{
setCurrentTab(1);
@ -119,7 +114,6 @@ export const GroupCreatorView: FC<GroupCreatorViewProps> = props =>
groupColors: null,
groupBadgeParts: null
});
});
SendMessageComposer(new GroupBuyDataComposer());
}, [ setGroupData ]);

View File

@ -3,7 +3,7 @@ import { GroupAdminGiveComposer, GroupAdminTakeComposer, GroupConfirmMemberRemov
import { FC, useCallback, useEffect, useState } from 'react';
import { AddEventLinkTracker, GetSessionDataManager, GetUserProfile, LocalizeText, NotificationUtilities, RemoveLinkEventTracker, SendMessageComposer } from '../../../api';
import { Base, Button, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
import { UseMessageEventHook } from '../../../hooks';
export const GroupMembersView: FC<{}> = props =>
{
@ -76,12 +76,9 @@ export const GroupMembersView: FC<{}> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setMembersData(parser);
setLevelId(parser.level);
setTotalPages(Math.ceil(parser.totalMembersCount / parser.pageSize));
});
}, []);
UseMessageEventHook(GroupMembersEvent, onGroupMembersEvent);
@ -111,11 +108,8 @@ export const GroupMembersView: FC<{}> = props =>
const groupId = (parseInt(parts[1]) || -1);
const levelId = (parseInt(parts[2]) || 3);
BatchUpdates(() =>
{
setGroupId(groupId);
setLevelId(levelId);
});
}, []);
useEffect(() =>
@ -146,14 +140,11 @@ export const GroupMembersView: FC<{}> = props =>
{
if(groupId === -1) return;
BatchUpdates(() =>
{
setLevelId(-1);
setMembersData(null);
setTotalPages(0);
setSearchQuery('');
setRemovingMemberName(null);
})
}, [ groupId ]);
if((groupId === -1) || !membersData) return null;

View File

@ -2,7 +2,6 @@ import { GroupDeleteComposer, GroupSaveInformationComposer } from '@nitrots/nitr
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
import { Base, Button, Column, Flex, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { IGroupData } from '../../common/IGroupData';
interface GroupTabIdentityViewProps
@ -64,13 +63,10 @@ export const GroupTabIdentityView: FC<GroupTabIdentityViewProps> = props =>
}, [ groupData, groupName, groupDescription, groupHomeroomId, setGroupData ]);
useEffect(() =>
{
BatchUpdates(() =>
{
setGroupName(groupData.groupName || '');
setGroupDescription(groupData.groupDescription || '');
setGroupHomeroomId(groupData.groupHomeroomId);
});
}, [ groupData ]);
useEffect(() =>

View File

@ -3,7 +3,6 @@ import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from '
import { SendMessageComposer } from '../../../../api';
import { LocalizeText } from '../../../../api/utils/LocalizeText';
import { Column, Flex, HorizontalRule, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { IGroupData } from '../../common/IGroupData';
const STATES: string[] = [ 'regular', 'exclusive', 'private' ];
@ -48,12 +47,9 @@ export const GroupTabSettingsView: FC<GroupTabSettingsViewProps> = props =>
}, [ groupData, groupState, groupDecorate, setGroupData ]);
useEffect(() =>
{
BatchUpdates(() =>
{
setGroupState(groupData.groupState);
setGroupDecorate(groupData.groupCanMembersDecorate);
});
}, [ groupData ]);
useEffect(() =>

View File

@ -85,7 +85,7 @@ export const GuideToolOngoingView: FC<GuideToolOngoingViewProps> = props =>
{ messageGroups.map((group, index) =>
{
return (
<Flex fullWidth justifyContent={ isOwnChat(group.userId) ? 'end' : 'start' } gap={ 2 }>
<Flex key={ index } fullWidth justifyContent={ isOwnChat(group.userId) ? 'end' : 'start' } gap={ 2 }>
<Base shrink className="message-avatar">
{ (!isOwnChat(group.userId)) &&
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } /> }

View File

@ -207,7 +207,10 @@ export const HcCenterView: FC<{}> = props =>
<hr className="w-100 text-black my-1" />
<div>{LocalizeText('hccenter.breakdown.total', [ 'credits', 'actual' ], [ getHcPaydayAmount(),
((((kickbackData.kickbackPercentage * kickbackData.totalCreditsSpent) + kickbackData.creditRewardForStreakBonus) * 100) / 100).toString() ])}</div>
<div className="btn btn-link text-primary p-0" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{
<div className="btn btn-link text-primary p-0" onClick={() =>
{
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage'])
}}>{
LocalizeText('hccenter.special.infolink')}
</div>
</Popover.Body>
@ -221,7 +224,10 @@ export const HcCenterView: FC<{}> = props =>
<Column gap={ 1 }>
<div className="hc-logo" />
<Flex>
<Button variant="success" onClick={ event => { CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.buy_hc']) } }>
<Button variant="success" onClick={ event =>
{
CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.buy_hc'])
} }>
{ LocalizeText((clubStatus === ClubStatus.ACTIVE) ? 'hccenter.btn.extend' : 'hccenter.btn.buy') }
</Button>
</Flex>
@ -243,7 +249,10 @@ export const HcCenterView: FC<{}> = props =>
<Column className="rounded-start bg-primary p-2 payday-special mb-1">
<h4 className="mb-1">{LocalizeText('hccenter.special.title')}</h4>
<div>{LocalizeText('hccenter.special.info')}</div>
<div className="btn btn-link text-white p-0 mt-auto align-self-baseline" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{LocalizeText('hccenter.special.infolink')}</div>
<div className="btn btn-link text-white p-0 mt-auto align-self-baseline" onClick={() =>
{
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage'])
}}>{LocalizeText('hccenter.special.infolink')}</div>
</Column>
<div className="payday flex-shrink-0 p-2">
<h5 className="mb-2 ms-2">{LocalizeText('hccenter.special.time.title')}</h5>
@ -273,14 +282,20 @@ export const HcCenterView: FC<{}> = props =>
<h4 className="mb-1">{LocalizeText('hccenter.gift.title')}</h4>
<div dangerouslySetInnerHTML={{ __html: unclaimedGifts > 0 ? LocalizeText('hccenter.unclaimedgifts', [ 'unclaimedgifts' ], [ unclaimedGifts.toString() ]) : LocalizeText('hccenter.gift.info') }}></div>
</div>
<button className="btn btn-primary btn-lg align-self-center ms-auto" onClick={() => { CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.hc_gifts']) }}>{LocalizeText(clubStatus === ClubStatus.ACTIVE ? 'hccenter.btn.gifts.redeem' : 'hccenter.btn.gifts.view')}</button>
<button className="btn btn-primary btn-lg align-self-center ms-auto" onClick={() =>
{
CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.hc_gifts'])
}}>{LocalizeText(clubStatus === ClubStatus.ACTIVE ? 'hccenter.btn.gifts.redeem' : 'hccenter.btn.gifts.view')}</button>
</div>
}
{GetConfiguration('hc.center')['benefits.info'] &&
<div className="benefits text-black py-2">
<h5 className="mb-1 text-primary">{LocalizeText('hccenter.general.title')}</h5>
<div className="mb-2" dangerouslySetInnerHTML={{ __html: LocalizeText('hccenter.general.info') }} />
<button className="btn btn-link p-0 text-primary" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage']) }}>{LocalizeText('hccenter.general.infolink')}</button>
<button className="btn btn-link p-0 text-primary" onClick={() =>
{
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage'])
}}>{LocalizeText('hccenter.general.infolink')}</button>
</div>
}
</NitroCardContentView>

View File

@ -2,7 +2,7 @@ import { FigureUpdateEvent, RoomSessionEvent, UserInfoDataParser, UserInfoEvent
import { FC, useCallback, useState } from 'react';
import { GetConfiguration, GetConfigurationManager } from '../../api';
import { LayoutAvatarImageView } from '../../common';
import { BatchUpdates, UseMessageEventHook, UseRoomSessionManagerEvent } from '../../hooks';
import { UseMessageEventHook, UseRoomSessionManagerEvent } from '../../hooks';
import { WidgetSlotView } from './views/widgets/WidgetSlotView';
export const HotelView: FC<{}> = props =>
{
@ -16,11 +16,8 @@ export const HotelView: FC<{}> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setUserInfo(parser.userInfo);
setUserFigure(parser.userInfo.figure);
});
}, []);
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);

View File

@ -4,11 +4,11 @@ import { AddEventLinkTracker, GetLocalization, GetRoomEngine, LocalizeText, Remo
import { isObjectMoverRequested, setObjectMoverRequested } from '../../api/inventory/InventoryUtilities';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { useInventoryTrade, useInventoryUnseenTracker, UseMessageEventHook, UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../hooks';
import { InventoryBadgeView } from './views/InventoryBadgeView';
import { InventoryBotView } from './views/InventoryBotView';
import { InventoryFurnitureView } from './views/InventoryFurnitureView';
import { InventoryPetView } from './views/InventoryPetView';
import { InventoryTradeView } from './views/InventoryTradeView';
import { InventoryBadgeView } from './views/badge/InventoryBadgeView';
import { InventoryBotView } from './views/bot/InventoryBotView';
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
import { InventoryTradeView } from './views/furniture/InventoryTradeView';
import { InventoryPetView } from './views/pet/InventoryPetView';
const TAB_FURNITURE: string = 'inventory.furni';
const TAB_BOTS: string = 'inventory.bots';
@ -130,10 +130,8 @@ export const InventoryView: FC<{}> = props =>
<NitroCardTabsView>
{ TABS.map((name, index) =>
{
const unseenCount = getCount(UNSEEN_CATEGORIES[index]);
return (
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) } count={ unseenCount }>
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) } count={ getCount(UNSEEN_CATEGORIES[index]) }>
{ LocalizeText(name) }
</NitroCardTabsItemView>
);

View File

@ -0,0 +1,19 @@
import { FC } from 'react';
import { UnseenItemCategory } from '../../../../api';
import { LayoutBadgeImageView, LayoutGridItem } from '../../../../common';
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
export const InventoryBadgeItemView: FC<{ badgeCode: string }> = props =>
{
const { badgeCode = null, children = null, ...rest } = props;
const { selectedBadgeCode = null, setSelectedBadgeCode = null, getBadgeId = null } = useInventoryBadges();
const { isUnseen = null } = useInventoryUnseenTracker();
const unseen = isUnseen(UnseenItemCategory.BADGE, getBadgeId(badgeCode));
return (
<LayoutGridItem itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onMouseDown={ event => setSelectedBadgeCode(badgeCode) } { ...rest }>
<LayoutBadgeImageView badgeCode={ badgeCode } />
{ children }
</LayoutGridItem>
);
}

View File

@ -1,47 +1,37 @@
import { FC, useEffect } from 'react';
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../api';
import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, LayoutGridItem, Text } from '../../../common';
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../hooks';
import { FC, useEffect, useState } from 'react';
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, Text } from '../../../../common';
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryBadgeItemView } from './InventoryBadgeItemView';
export const InventoryBadgeView: FC<{}> = props =>
{
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, selectBadge = null, getBadgeId = null } = useInventoryBadges();
const [ isVisible, setIsVisible ] = useState(false);
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, getBadgeId = null, activate = null, deactivate = null } = useInventoryBadges();
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() =>
{
if(!badgeCodes || !badgeCodes.length) return;
if(!selectedBadgeCode || !isUnseen(UnseenItemCategory.BADGE, getBadgeId(selectedBadgeCode))) return;
return () =>
removeUnseen(UnseenItemCategory.BADGE, getBadgeId(selectedBadgeCode));
}, [ selectedBadgeCode, isUnseen, removeUnseen, getBadgeId ]);
useEffect(() =>
{
const count = getCount(UnseenItemCategory.BADGE);
if(!isVisible) return;
if(!count) return;
const id = activate();
resetCategory(UnseenItemCategory.BADGE);
}
}, [ badgeCodes, getCount, resetCategory ]);
return () => deactivate(id);
}, [ isVisible, activate, deactivate ]);
const InventoryBadgeItemView: FC<{ badgeCode: string }> = props =>
useEffect(() =>
{
const { badgeCode = null, children = null, ...rest } = props;
const badgeId = getBadgeId(badgeCode);
const unseen = isUnseen(UnseenItemCategory.BADGE, badgeId);
setIsVisible(true);
const select = () =>
{
selectBadge(badgeCode);
if(unseen) removeUnseen(UnseenItemCategory.BADGE, badgeId);
}
return (
<LayoutGridItem itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onMouseDown={ select } { ...rest }>
<LayoutBadgeImageView badgeCode={ badgeCode } />
{ children }
</LayoutGridItem>
);
}
return () => setIsVisible(false);
}, []);
return (
<Grid>

View File

@ -0,0 +1,40 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useState } from 'react';
import { attemptBotPlacement, IBotItem, UnseenItemCategory } from '../../../../api';
import { LayoutAvatarImageView, LayoutGridItem } from '../../../../common';
import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
export const InventoryBotItemView: FC<{ botItem: IBotItem }> = props =>
{
const { botItem = null, children = null, ...rest } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const { selectedBot = null, setSelectedBot = null } = useInventoryBots();
const { isUnseen = null } = useInventoryUnseenTracker();
const unseen = isUnseen(UnseenItemCategory.BOT, botItem.botData.id);
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
setSelectedBot(botItem);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || (selectedBot !== botItem)) return;
attemptBotPlacement(botItem);
return;
}
}
return (
<LayoutGridItem itemActive={ (selectedBot === botItem) } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } { ...rest }>
<LayoutAvatarImageView figure={ botItem.botData.figure } direction={ 3 } headOnly={ true } />
{ children }
</LayoutGridItem>
);
}

View File

@ -1,9 +1,10 @@
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { attemptBotPlacement, GetRoomEngine, IBotItem, LocalizeText, UnseenItemCategory } from '../../../api';
import { AutoGrid, Button, Column, Grid, LayoutAvatarImageView, LayoutGridItem, LayoutRoomPreviewerView, Text } from '../../../common';
import { useInventoryBots, useInventoryUnseenTracker } from '../../../hooks';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
import { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { attemptBotPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryBotItemView } from './InventoryBotItemView';
interface InventoryBotViewProps
{
@ -14,22 +15,9 @@ interface InventoryBotViewProps
export const InventoryBotView: FC<InventoryBotViewProps> = props =>
{
const { roomSession = null, roomPreviewer = null } = props;
const { botItems = [], selectedBot = null, selectBot = null } = useInventoryBots();
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() =>
{
if(!botItems || !botItems.length) return;
return () =>
{
const count = getCount(UnseenItemCategory.BOT);
if(!count) return;
resetCategory(UnseenItemCategory.BOT);
}
}, [ botItems, getCount, resetCategory ]);
const [ isVisible, setIsVisible ] = useState(false);
const { botItems = [], selectedBot = null, activate = null, deactivate = null } = useInventoryBots();
const { isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() =>
{
@ -53,44 +41,31 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
roomPreviewer.addAvatarIntoRoom(botData.figure, 0);
}, [ roomPreviewer, selectedBot ]);
useEffect(() =>
{
if(!selectedBot || !isUnseen(UnseenItemCategory.BOT, selectedBot.botData.id)) return;
removeUnseen(UnseenItemCategory.BOT, selectedBot.botData.id);
}, [ selectedBot, isUnseen, removeUnseen ]);
useEffect(() =>
{
if(!isVisible) return;
const id = activate();
return () => deactivate(id);
}, [ isVisible, activate, deactivate ]);
useEffect(() =>
{
setIsVisible(true);
return () => setIsVisible(false);
}, []);
if(!botItems || !botItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.bots.title') } desc={ LocalizeText('inventory.empty.bots.desc') } />;
const InventoryBotItemView: FC<{ botItem: IBotItem }> = props =>
{
const { botItem = null } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const isActive = (botItem === selectedBot);
const unseen = isUnseen(UnseenItemCategory.BOT, botItem.botData.id);
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
selectBot(botItem);
if(unseen) removeUnseen(UnseenItemCategory.BOT, botItem.botData.id);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || !isActive) return;
attemptBotPlacement(botItem);
return;
}
}
return (
<LayoutGridItem itemActive={ isActive } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
<LayoutAvatarImageView figure={ botItem.botData.figure } direction={ 3 } headOnly={ true } />
</LayoutGridItem>
);
}
return (
<Grid>
<Column size={ 7 } overflow="hidden">

View File

@ -0,0 +1,35 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useState } from 'react';
import { attemptItemPlacement, GroupItem } from '../../../../api';
import { LayoutGridItem } from '../../../../common';
import { useInventoryFurni } from '../../../../hooks';
export const InventoryFurnitureItemView: FC<{ groupItem: GroupItem }> = props =>
{
const { groupItem = null, ...rest } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const { selectedItem = null, setSelectedItem = null } = useInventoryFurni();
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
setSelectedItem(groupItem);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || !(groupItem === selectedItem)) return;
attemptItemPlacement(groupItem);
return;
}
}
const count = groupItem.getUnlockedCount();
return <LayoutGridItem className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ groupItem.getUnlockedCount() } itemActive={ (groupItem === selectedItem) } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } { ...rest } />;
}

View File

@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
import { GroupItem, LocalizeText } from '../../../api';
import { Button, Flex } from '../../../common';
import { GroupItem, LocalizeText } from '../../../../api';
import { Button, Flex } from '../../../../common';
export interface InventoryFurnitureSearchViewProps
{

View File

@ -1,10 +1,11 @@
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../api';
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../common';
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../hooks';
import { attemptPlaceMarketplaceOffer } from '../../../hooks/inventory/common';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
import { IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks';
import { attemptPlaceMarketplaceOffer } from '../../../../hooks/inventory/common';
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryFurnitureItemView } from './InventoryFurnitureItemView';
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
interface InventoryFurnitureViewProps
@ -16,9 +17,10 @@ interface InventoryFurnitureViewProps
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
{
const { roomSession = null, roomPreviewer = null } = props;
const [ isVisible, setIsVisible ] = useState(false);
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>([]);
const { groupItems = [], selectedItem = null, selectItem = null, activate = null, deactivate = null } = useInventoryFurni();
const { getCount = null, resetCategory = null } = useInventoryUnseenTracker();
const { groupItems = [], selectedItem = null, activate = null, deactivate = null } = useInventoryFurni();
const { resetItems = null } = useInventoryUnseenTracker();
useEffect(() =>
{
@ -72,65 +74,30 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
useEffect(() =>
{
if(!groupItems || !groupItems.length) return;
if(!selectedItem || !selectedItem.hasUnseenItems) return;
return () =>
{
const count = getCount(UnseenItemCategory.FURNI);
resetItems(UnseenItemCategory.FURNI, selectedItem.items.map(item => item.id));
if(!count) return;
resetCategory(UnseenItemCategory.FURNI);
for(const groupItem of groupItems) groupItem.hasUnseenItems = false;
}
}, [ groupItems, getCount, resetCategory ]);
selectedItem.hasUnseenItems = false;
}, [ selectedItem, resetItems ]);
useEffect(() =>
{
if(!isVisible) return;
const id = activate();
return () => deactivate(id);
}, [ activate, deactivate ]);
if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.title') } desc={ LocalizeText('inventory.empty.desc') } />;
const InventoryFurnitureItemView: FC<{ groupItem: GroupItem }> = props =>
{
const { groupItem = null } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const isActive = (groupItem === selectedItem);
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
selectItem(groupItem);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || !isActive) return;
attemptItemPlacement(groupItem);
return;
}
}
}, [ isVisible, activate, deactivate ]);
useEffect(() =>
{
if(!isActive) return;
setIsVisible(true);
groupItem.hasUnseenItems = false;
}, [ isActive, groupItem ]);
return () => setIsVisible(false);
}, []);
const count = groupItem.getUnlockedCount();
return <LayoutGridItem className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
}
if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.title') } desc={ LocalizeText('inventory.empty.desc') } />;
return (
<Grid>

View File

@ -1,10 +1,10 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IObjectData, TradingListAddItemComposer, TradingListAddItemsComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../api';
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../common';
import { useInventoryTrade } from '../../../hooks';
import { getGuildFurniType } from '../../../hooks/inventory/common/TradingUtilities';
import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../../api';
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../../common';
import { useInventoryTrade } from '../../../../hooks';
import { getGuildFurniType } from '../../../../hooks/inventory/common/TradingUtilities';
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
interface InventoryTradeViewProps

View File

@ -0,0 +1,40 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useState } from 'react';
import { attemptPetPlacement, IPetItem, UnseenItemCategory } from '../../../../api';
import { LayoutGridItem, LayoutPetImageView } from '../../../../common';
import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
export const InventoryPetItemView: FC<{ petItem: IPetItem }> = props =>
{
const { petItem = null, children = null, ...rest } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const { selectedPet = null, setSelectedPet = null } = useInventoryPets();
const { isUnseen } = useInventoryUnseenTracker();
const unseen = isUnseen(UnseenItemCategory.PET, petItem.petData.id);
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
setSelectedPet(petItem);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || !(petItem === selectedPet)) return;
attemptPetPlacement(petItem);
return;
}
}
return (
<LayoutGridItem itemActive={ (petItem === selectedPet) } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } { ...rest }>
<LayoutPetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
{ children }
</LayoutGridItem>
);
}

View File

@ -1,9 +1,10 @@
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { attemptPetPlacement, GetRoomEngine, IPetItem, LocalizeText, UnseenItemCategory } from '../../../api';
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutPetImageView, LayoutRoomPreviewerView, Text } from '../../../common';
import { useInventoryPets, useInventoryUnseenTracker } from '../../../hooks';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
import { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { attemptPetPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryPetItemView } from './InventoryPetItemView';
interface InventoryPetViewProps
{
@ -14,22 +15,9 @@ interface InventoryPetViewProps
export const InventoryPetView: FC<InventoryPetViewProps> = props =>
{
const { roomSession = null, roomPreviewer = null } = props;
const { petItems = null, selectedPet = null, selectPet = null } = useInventoryPets();
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() =>
{
if(!petItems || !petItems.length) return;
return () =>
{
const count = getCount(UnseenItemCategory.PET);
if(!count) return;
resetCategory(UnseenItemCategory.PET);
}
}, [ petItems, getCount, resetCategory ]);
const [ isVisible, setIsVisible ] = useState(false);
const { petItems = null, selectedPet = null, activate = null, deactivate = null } = useInventoryPets();
const { isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() =>
{
@ -52,44 +40,31 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
roomPreviewer.addPetIntoRoom(petData.figureString);
}, [ roomPreviewer, selectedPet ]);
useEffect(() =>
{
if(!selectedPet || !isUnseen(UnseenItemCategory.PET, selectedPet.petData.id)) return;
removeUnseen(UnseenItemCategory.PET, selectedPet.petData.id);
}, [ selectedPet, isUnseen, removeUnseen ]);
useEffect(() =>
{
if(!isVisible) return;
const id = activate();
return () => deactivate(id);
}, [ isVisible, activate, deactivate ]);
useEffect(() =>
{
setIsVisible(true);
return () => setIsVisible(false);
}, []);
if(!petItems || !petItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.pets.title') } desc={ LocalizeText('inventory.empty.pets.desc') } />;
const InventoryPetItemView: FC<{ petItem: IPetItem }> = props =>
{
const { petItem = null } = props;
const [ isMouseDown, setMouseDown ] = useState(false);
const isActive = (petItem === selectedPet);
const unseen = isUnseen(UnseenItemCategory.PET, petItem.petData.id);
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
selectPet(petItem);
if(unseen) removeUnseen(UnseenItemCategory.PET, petItem.petData.id);
setMouseDown(true);
return;
case MouseEventType.MOUSE_UP:
setMouseDown(false);
return;
case MouseEventType.ROLL_OUT:
if(!isMouseDown || !isActive) return;
attemptPetPlacement(petItem);
return;
}
}
return (
<LayoutGridItem itemActive={ isActive } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
<LayoutPetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
</LayoutGridItem>
);
}
return (
<Grid>
<Column size={ 7 } overflow="hidden">

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
import { SendMessageComposer, TryVisitRoom } from '../../../../api';
import { Button, Column, DraggableWindowPosition, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { ModToolsOpenRoomChatlogEvent } from '../../../../events/mod-tools/ModToolsOpenRoomChatlogEvent';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
import { DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
interface ModToolsRoomViewProps
{
@ -36,15 +36,12 @@ export const ModToolsRoomView: FC<ModToolsRoomViewProps> = props =>
if(!parser || parser.data.flatId !== roomId) return;
BatchUpdates(() =>
{
setLoadedRoomId(parser.data.flatId);
setName(parser.data.room.name);
setOwnerId(parser.data.ownerId);
setOwnerName(parser.data.ownerName);
setOwnerInRoom(parser.data.ownerInRoom);
setUsersInRoom(parser.data.userCount);
});
}, [ roomId ]);
UseMessageEventHook(ModeratorRoomInfoEvent, onModtoolRoomInfoEvent);

View File

@ -2,7 +2,7 @@ import { ChatRecordData, GetUserChatlogMessageComposer, UserChatlogEvent } from
import { FC, useCallback, useEffect, useState } from 'react';
import { SendMessageComposer } from '../../../../api';
import { DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks';
import { UseMessageEventHook } from '../../../../hooks';
import { ChatlogView } from '../chatlog/ChatlogView';
interface ModToolsUserChatlogViewProps
@ -23,11 +23,8 @@ export const ModToolsUserChatlogView: FC<ModToolsUserChatlogViewProps> = props =
if(!parser || parser.data.userId !== userId) return;
BatchUpdates(() =>
{
setUsername(parser.data.username);
setUserChatlog(parser.data.roomChatlogs);
});
}, [ userId ]);
UseMessageEventHook(UserChatlogEvent, onModtoolUserChatlogEvent);

View File

@ -1,7 +1,7 @@
import { CanCreateRoomEventEvent, CantConnectMessageParser, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomResultEvent, HabboWebTools, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback } from 'react';
import { CreateLinkEvent, CreateRoomSession, DoorStateType, GetConfiguration, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api';
import { BatchUpdates, UseMessageEventHook } from '../../hooks';
import { UseMessageEventHook } from '../../hooks';
import { useNavigatorContext } from './NavigatorContext';
export const NavigatorMessageHandler: FC<{}> = props =>
@ -271,19 +271,14 @@ export const NavigatorMessageHandler: FC<{}> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setTopLevelContexts(parser.topLevelContexts);
setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
});
}, [ setTopLevelContexts, setTopLevelContext ]);
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setTopLevelContext(prevValue =>
{
let newValue = prevValue;
@ -313,7 +308,6 @@ export const NavigatorMessageHandler: FC<{}> = props =>
});
setSearchResult(parser.result);
});
}, [ topLevelContexts, setTopLevelContext, setSearchResult ]);
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) =>

View File

@ -3,7 +3,7 @@ import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, L
import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, DoorStateType, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { BatchUpdates, UseRoomSessionManagerEvent, useSharedNavigatorData } from '../../hooks';
import { UseRoomSessionManagerEvent, useSharedNavigatorData } from '../../hooks';
import { NavigatorContextProvider } from './NavigatorContext';
import { NavigatorMessageHandler } from './NavigatorMessageHandler';
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
@ -37,11 +37,8 @@ export const NavigatorView: FC<{}> = props =>
switch(event.type)
{
case RoomSessionEvent.CREATED:
BatchUpdates(() =>
{
setIsVisible(false);
setCreatorOpen(false);
});
return;
}
}, []);
@ -96,11 +93,8 @@ export const NavigatorView: FC<{}> = props =>
switch(parts[1])
{
case 'show': {
BatchUpdates(() =>
{
setIsVisible(true);
setNeedsSearch(true);
});
return;
}
case 'hide':
@ -114,11 +108,8 @@ export const NavigatorView: FC<{}> = props =>
return;
}
BatchUpdates(() =>
{
setIsVisible(true);
setNeedsSearch(true);
});
return;
}
case 'toggle-room-info':
@ -145,11 +136,8 @@ export const NavigatorView: FC<{}> = props =>
}
return;
case 'create':
BatchUpdates(() =>
{
setIsVisible(true);
setCreatorOpen(true);
});
return;
case 'search':
if(parts.length > 2)
@ -162,11 +150,8 @@ export const NavigatorView: FC<{}> = props =>
pendingSearch.current = { value: searchValue, code: topLevelContextCode };
BatchUpdates(() =>
{
setIsVisible(true);
setNeedsSearch(true);
});
}
return;
}

View File

@ -3,7 +3,6 @@ import { HabboClubLevelEnum, RoomCreateComposer } from '@nitrots/nitro-renderer'
import { FC, useEffect, useState } from 'react';
import { GetClubMemberLevel, GetConfiguration, IRoomModel, LocalizeText, RoomModels, SendMessageComposer } from '../../../api';
import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, Text } from '../../../common';
import { BatchUpdates } from '../../../hooks';
import { useNavigatorContext } from '../NavigatorContext';
export const NavigatorRoomCreatorView: FC<{}> = props =>
@ -39,11 +38,8 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
for(let i = 10; i <= 100; i = i + 10) list.push(i);
BatchUpdates(() =>
{
setMaxVisitorsList(list);
setVisitorsCount(list[0]);
});
}
}, [ maxVisitorsList ]);

View File

@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react';
import { CreateLinkEvent, GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../api';
import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../common';
import { FloorplanEditorEvent, RoomWidgetThumbnailEvent } from '../../../events';
import { BatchUpdates, DispatchUiEvent } from '../../../hooks';
import { DispatchUiEvent } from '../../../hooks';
import { useNavigatorContext } from '../NavigatorContext';
export class NavigatorRoomInfoViewProps
@ -85,11 +85,9 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
{
if(!navigatorData) return;
BatchUpdates(() =>
{
setIsRoomPicked(navigatorData.currentRoomIsStaffPick);
if(navigatorData.enteredGuestRoom) setIsRoomMuted(navigatorData.enteredGuestRoom.allInRoomMuted);
});
}, [ navigatorData ]);
if(!navigatorData.enteredGuestRoom) return null;

View File

@ -2,7 +2,6 @@ import { RoomDataParser } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { IRoomData, LocalizeText } from '../../../../api';
import { Column, Flex, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface NavigatorRoomSettingsTabViewProps
{
@ -25,13 +24,10 @@ export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabView
}
useEffect(() =>
{
BatchUpdates(() =>
{
setPassword('');
setConfirmPassword('');
setIsTryingPassword(false);
});
}, [ roomData ]);
return (

View File

@ -3,7 +3,6 @@ import { RoomDeleteComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { CreateLinkEvent, GetMaxVisitorsList, IRoomData, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { useNavigatorContext } from '../../NavigatorContext';
const ROOM_NAME_MIN_LENGTH = 3;
@ -53,12 +52,9 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
}
useEffect(() =>
{
BatchUpdates(() =>
{
setRoomName(roomData.roomName);
setRoomDescription(roomData.roomDescription);
});
}, [ roomData ]);
return (

View File

@ -2,7 +2,7 @@ import { RoomBannedUsersComposer, RoomDataParser, RoomSettingsEvent, SaveRoomSet
import { FC, useCallback, useState } from 'react';
import { IRoomData, LocalizeText, SendMessageComposer } from '../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks';
import { UseMessageEventHook } from '../../../../hooks';
import { NavigatorRoomSettingsAccessTabView } from './NavigatorRoomSettingsAccessTabView';
import { NavigatorRoomSettingsBasicTabView } from './NavigatorRoomSettingsBasicTabView';
import { NavigatorRoomSettingsModTabView } from './NavigatorRoomSettingsModTabView';
@ -64,12 +64,9 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent);
const close = () =>
{
BatchUpdates(() =>
{
setRoomData(null);
setCurrentTab(TABS[0]);
});
}
const handleChange = (field: string, value: string | number | boolean) =>

View File

@ -2,7 +2,6 @@ import { RoomDataParser } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { Overlay, Popover } from 'react-bootstrap';
import { Base, NitroCardContentView } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface NavigatorSearchResultItemInfoViewProps
{
@ -19,8 +18,6 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
{
event.stopPropagation();
BatchUpdates(() =>
{
let visible = false;
setIsVisible(prevValue =>
@ -31,7 +28,6 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
});
if(visible) setTarget((event.target as (EventTarget & HTMLElement)));
})
}
useEffect(() =>

View File

@ -3,7 +3,6 @@ import { NavigatorSearchResultList } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { LocalizeText, NavigatorSearchResultViewDisplayMode } from '../../../../api';
import { AutoGrid, AutoGridProps, Column, Flex, Grid, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { NavigatorSearchResultItemView } from './NavigatorSearchResultItemView';
export interface NavigatorSearchResultViewProps extends AutoGridProps
@ -43,11 +42,8 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
{
if(!searchResult) return;
BatchUpdates(() =>
{
//setIsExtended(searchResult.closed);
setDisplayMode(searchResult.mode);
});
}, [ searchResult,props ]);
const gridHasTwoColumns = (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS);

View File

@ -2,7 +2,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { FC, KeyboardEvent, useEffect, useState } from 'react';
import { INavigatorSearchFilter, LocalizeText, SearchFilterOptions } from '../../../../api';
import { Button, Flex } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { useNavigatorContext } from '../../NavigatorContext';
export interface NavigatorSearchViewProps
@ -39,7 +38,7 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
useEffect(() =>
{
if(!searchResult) return null;
if(!searchResult) return;
const split = searchResult.data.split(':');
@ -60,11 +59,8 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
if(!filter) filter = SearchFilterOptions[0];
BatchUpdates(() =>
{
setSearchFilterIndex(SearchFilterOptions.findIndex(option => (option === filter)));
setSearchValue(value);
});
}, [ searchResult ]);
return (

View File

@ -2,7 +2,6 @@ import { NitroLogger } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, GetConfiguration, NotificationUtilities, RemoveLinkEventTracker } from '../../api';
import { Base, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
import { BatchUpdates } from '../../hooks';
const NEW_LINE_REGEX = /\n\r|\n|\r/mg;
@ -25,8 +24,6 @@ export const NitropediaView: FC<{}> = props =>
const splitData = text.split(NEW_LINE_REGEX);
const line = splitData.shift().split('|');
BatchUpdates(() =>
{
setHeader(line[0]);
setDimensions(prevValue =>
@ -43,7 +40,6 @@ export const NitropediaView: FC<{}> = props =>
});
setContent(splitData.join(''));
});
}
catch (error)

View File

@ -26,7 +26,10 @@ export const NotificationDefaultAlertView: FC<NotificationDefaultAlertViewProps>
<LayoutNotificationAlertView title={title} close={close} {...rest} type={ hasFrank ? NotificationAlertType.DEFAULT : item.alertType }>
<Flex fullHeight overflow="auto" gap={ hasFrank || (item.imageUrl && !imageFailed) ? 2 : 0 }>
{hasFrank && !item.imageUrl && <Base className="notification-frank flex-shrink-0" /> }
{item.imageUrl && !imageFailed && <img src={item.imageUrl} alt={item.title} onError={() => { setImageFailed(true) }} className="align-self-baseline" />}
{item.imageUrl && !imageFailed && <img src={item.imageUrl} alt={item.title} onError={() =>
{
setImageFailed(true)
}} className="align-self-baseline" />}
<Base classNames={[ 'notification-text overflow-y-auto d-flex flex-column w-100', (item.clickUrl && !hasFrank) ? 'justify-content-center' : '' ]}>
{ (item.messages.length > 0) && item.messages.map((message, index) =>
{

View File

@ -3,7 +3,7 @@ import { RoomControllerLevel, RoomObjectCategory, RoomObjectVariable } from '@ni
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { CreateLinkEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUserActionMessage } from '../../../../api';
import { Base, Flex } from '../../../../common';
import { BatchUpdates, useFriends } from '../../../../hooks';
import { useFriends } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
@ -207,12 +207,9 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
}, [ userData, respectsLeft, widgetHandler, close, ]);
useEffect(() =>
{
BatchUpdates(() =>
{
setMode(MODE_NORMAL);
setRespectsLeft(userData.respectLeft);
});
}, [ userData ]);
return (

View File

@ -1,7 +1,6 @@
import { PetType, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { CreateLinkEvent, GetConfiguration, GetOwnRoomObject, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUserActionMessage } from '../../../../api';
import { BatchUpdates } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
@ -129,8 +128,6 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
}
useEffect(() =>
{
BatchUpdates(() =>
{
setMode(prevValue =>
{
@ -142,7 +139,6 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
});
setRespectsLeft(petData.respectsPetLeft);
});
}, [ petData ]);
return (

View File

@ -1,7 +1,6 @@
import { PetType, RoomControllerLevel, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { GetOwnRoomObject, GetSessionDataManager, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUserActionMessage } from '../../../../api';
import { BatchUpdates } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
@ -96,8 +95,6 @@ export const AvatarInfoWidgetPetView: FC<AvatarInfoWidgetPetViewProps> = props =
}
useEffect(() =>
{
BatchUpdates(() =>
{
setMode(prevValue =>
{
@ -109,7 +106,6 @@ export const AvatarInfoWidgetPetView: FC<AvatarInfoWidgetPetViewProps> = props =
});
setRespectsLeft(petData.respectsPetLeft);
});
}, [ petData ]);
return (

View File

@ -1,7 +1,6 @@
import { FC, MouseEvent, useEffect, useState } from 'react';
import { Overlay, Popover } from 'react-bootstrap';
import { Base, Flex, Grid, NitroCardContentView } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface ChatInputStyleSelectorViewProps
{
@ -17,17 +16,12 @@ export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = p
const [ selectorVisible, setSelectorVisible ] = useState(false);
const selectStyle = (styleId: number) =>
{
BatchUpdates(() =>
{
selectChatStyleId(styleId);
setSelectorVisible(false);
});
}
const toggleSelector = (event: MouseEvent<HTMLElement>) =>
{
BatchUpdates(() =>
{
let visible = false;
@ -39,7 +33,6 @@ export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = p
});
if(visible) setTarget((event.target as (EventTarget & HTMLElement)));
})
}
useEffect(() =>

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { GetClubMemberLevel, GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetFloodControlEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { Text } from '../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks';
import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ChatInputStyleSelectorView } from './ChatInputStyleSelectorView';
@ -210,12 +210,9 @@ export const ChatInputView: FC<{}> = props =>
UseEventDispatcherHook(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT, eventDispatcher, onRoomWidgetChatInputContentUpdateEvent);
const onRoomWidgetFloodControlEvent = useCallback((event: RoomWidgetFloodControlEvent) =>
{
BatchUpdates(() =>
{
setFloodBlocked(true);
setFloodBlockedSeconds(event.seconds);
});
}, []);
UseEventDispatcherHook(RoomWidgetFloodControlEvent.FLOOD_CONTROL, eventDispatcher, onRoomWidgetFloodControlEvent);

View File

@ -1,7 +1,7 @@
import { SecurityLevel } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { GetSessionDataManager, LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks';
import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ChooserWidgetView } from './ChooserWidgetView';
@ -25,12 +25,9 @@ export const FurniChooserWidgetView: FC<{}> = props =>
}, [ isVisible, widgetHandler ]);
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
{
BatchUpdates(() =>
{
setItems(event.items);
setIsVisible(true);
});
}, []);
UseEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
@ -52,12 +49,9 @@ export const FurniChooserWidgetView: FC<{}> = props =>
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() =>
{
BatchUpdates(() =>
{
setIsVisible(false);
setItems(null);
});
}, []);
if(!items) return null;

View File

@ -1,6 +1,6 @@
import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks';
import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { ChooserWidgetView } from './ChooserWidgetView';
@ -24,12 +24,9 @@ export const UserChooserWidgetView: FC<{}> = props =>
}, [ isVisible, widgetHandler ]);
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
{
BatchUpdates(() =>
{
setItems(event.items);
setIsVisible(true);
});
}, []);
UseEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
@ -51,12 +48,9 @@ export const UserChooserWidgetView: FC<{}> = props =>
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() =>
{
BatchUpdates(() =>
{
setIsVisible(false);
setItems(null);
});
}, []);
if(!isVisible) return null;

View File

@ -2,7 +2,6 @@ import { FixedSizeStack, NitroPoint, NitroRectangle, RoomObjectType } from '@nit
import { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { GetNitroInstance, GetRoomEngine, GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
import { Base, BaseProps } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
{
@ -102,11 +101,8 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES;
else if(y > maxTop) y = maxTop;
BatchUpdates(() =>
{
setCurrentDeltaY(maxStack);
setPos({ x, y });
});
}, [ deltaYStack, currentDeltaY, getOffset ]);
const update = useCallback((time: number) =>
@ -144,12 +140,9 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
}, [ pos, opacity, style ]);
useEffect(() =>
{
BatchUpdates(() =>
{
setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE));
setCurrentDeltaY(-1000000);
});
}, []);
useEffect(() =>

View File

@ -1,7 +1,7 @@
import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomWidgetDoorbellEvent, RoomWidgetLetUserInMessage } from '../../../../api';
import { Base, Button, Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks';
import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
export const DoorbellWidgetView: FC<{}> = props =>
@ -14,11 +14,8 @@ export const DoorbellWidgetView: FC<{}> = props =>
{
if(users.indexOf(userName) >= 0) return;
BatchUpdates(() =>
{
setUsers([ ...users, userName ]);
setIsVisible(true);
});
}, [ users ]);
const removeUser = useCallback((userName: string) =>

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent, SendMessageComposer } from '../../../../../api';
import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
import { UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
export const FurnitureBackgroundColorView: FC<{}> = props =>
@ -36,13 +36,10 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
const model = roomObject.model;
BatchUpdates(() =>
{
setObjectId(roomObject.id);
setHue(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
setSaturation(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
setLightness(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
});
return;
}

View File

@ -1,7 +1,7 @@
import { ContextMenuEnum, GroupFurniContextMenuInfoMessageEvent, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryJoinGroup, TryVisitRoom } from '../../../../../api';
import { BatchUpdates, UseMessageEventHook, UseRoomEngineEvent } from '../../../../../hooks';
import { UseMessageEventHook, UseRoomEngineEvent } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView';
@ -26,14 +26,11 @@ export const FurnitureContextMenuView: FC<{}> = props =>
const { roomSession = null, widgetHandler = null } = useRoomContext();
const close = useCallback(() =>
{
BatchUpdates(() =>
{
setObjectId(-1);
setGroupData(null);
setIsGroupMember(false);
setMode(null);
});
}, []);
const closeConfirm = () =>
@ -53,40 +50,29 @@ export const FurnitureContextMenuView: FC<{}> = props =>
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id);
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
});
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id);
setConfirmMode(EFFECTBOX_OPEN);
});
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id);
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
});
close();
return;
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
BatchUpdates(() =>
{
setObjectId(object.id);
switch(event.contextMenu)
@ -106,7 +92,6 @@ export const FurnitureContextMenuView: FC<{}> = props =>
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
return;
}
});
return;
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
@ -125,13 +110,10 @@ export const FurnitureContextMenuView: FC<{}> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setObjectId(parser.objectId);
setGroupData(parser);
setIsGroupMember(parser.userIsMember);
setMode(GROUP_FURNITURE);
});
}, []);
UseMessageEventHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, RoomWidgetUpdateCustomStackHeightEvent, SendMessageComposer } from '../../../../../api';
import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
import { UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
const MAX_HEIGHT: number = 40;
@ -16,12 +16,9 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
const { eventDispatcher = null } = useRoomContext();
const close = () =>
{
BatchUpdates(() =>
{
setObjectId(-1);
setHeight(0);
});
}
const updateHeight = useCallback((height: number, fromServer: boolean = false) =>
@ -32,12 +29,9 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
if(!fromServer) ((height > MAX_HEIGHT) && (height = MAX_HEIGHT));
BatchUpdates(() =>
{
setHeight(parseFloat(height.toFixed(2)));
if(!fromServer) setPendingHeight(height * 100);
});
}, []);
const onRoomWidgetUpdateCustomStackHeightEvent = useCallback((event: RoomWidgetUpdateCustomStackHeightEvent) =>

View File

@ -4,5 +4,6 @@ export class DimmerFurnitureWidgetPresetItem
public id: number = 0,
public type: number = 0,
public color: number = 0,
public light: number = 0) {}
public light: number = 0)
{}
}

View File

@ -4,7 +4,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import ReactSlider from 'react-slider';
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api';
import { Base, Button, Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { DimmerFurnitureWidgetPresetItem } from './DimmerFurnitureWidgetPresetItem';
@ -39,12 +39,9 @@ export const FurnitureDimmerView: FC<{}> = props =>
for(const preset of widgetEvent.presets) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
BatchUpdates(() =>
{
setPresets(presets);
setSelectedPresetId(widgetEvent.selectedPresetId);
setIsVisible(true);
});
return;
}
case RoomWidgetUpdateDimmerEvent.HIDE: {
@ -55,8 +52,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
case RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE: {
const widgetEvent = (event as RoomWidgetUpdateDimmerStateEvent);
BatchUpdates(() =>
{
setLastDimmerState(dimmerState);
setDimmerState(widgetEvent.state);
setSelectedPresetId(widgetEvent.presetId);
@ -66,7 +61,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
setSelectedColor(widgetEvent.color);
setBrightness(widgetEvent.brightness);
setSelectedBrightness(widgetEvent.brightness);
});
return;
}
@ -83,13 +77,10 @@ export const FurnitureDimmerView: FC<{}> = props =>
if(!preset) return;
BatchUpdates(() =>
{
setSelectedPresetId(preset.id);
setSelectedEffectId(preset.type);
setSelectedColor(preset.color);
setSelectedBrightness(preset.light);
});
}, [ presets ]);
const close = useCallback(() =>

View File

@ -1,7 +1,7 @@
import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
export const FurnitureExchangeCreditView: FC<{}> = props =>
@ -11,23 +11,17 @@ export const FurnitureExchangeCreditView: FC<{}> = props =>
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
const onRoomWidgetUpdateCreditFurniEvent = useCallback((event: RoomWidgetUpdateCreditFurniEvent) =>
{
BatchUpdates(() =>
{
setObjectId(event.objectId);
setValue(event.value);
});
}, []);
UseEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
const close = () =>
{
BatchUpdates(() =>
{
setObjectId(-1);
setValue(0);
});
}
const redeem = () =>

View File

@ -1,7 +1,7 @@
import { FC, useCallback, useState } from 'react';
import { IPhotoData, LocalizeText, RoomWidgetUpdateExternalImageEvent } from '../../../../../api';
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
export const FurnitureExternalImageView: FC<{}> = props =>
@ -20,14 +20,10 @@ export const FurnitureExternalImageView: FC<{}> = props =>
{
switch(event.type)
{
case RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE: {
BatchUpdates(() =>
{
case RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE:
setObjectId(event.objectId);
setPhotoData(event.photoData);
});
}
return;
}
}, []);

View File

@ -6,5 +6,6 @@ export class FurnitureEngravingLockData
public type: number = 0,
public usernames: string[] = [],
public figures: string[] = [],
public date: string = null) {}
public date: string = null)
{}
}

View File

@ -2,7 +2,7 @@ import { FriendFurniConfirmLockMessageComposer, LoveLockFurniFinishedEvent, Love
import { FC, useCallback, useState } from 'react';
import { GetRoomEngine, GetRoomSession, LocalizeText, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
import { DraggableWindow, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseMessageEventHook, UseRoomEngineEvent } from '../../../../../hooks';
import { UseEventDispatcherHook, UseMessageEventHook, UseRoomEngineEvent } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { FurnitureEngravingLockData } from './FriendFurniLockData';
@ -30,11 +30,8 @@ export const FurnitureFriendFurniView: FC<{}> = props =>
{
if(data.length !== 6) return;
BatchUpdates(() =>
{
setEngravingLockData(new FurnitureEngravingLockData(widgetEvent.objectId, widgetEvent.category, type, [ data[1], data[2] ], [ data[3], data[4] ], data[5]));
setEngravingStage(0);
});
}
return;
}
@ -59,11 +56,8 @@ export const FurnitureFriendFurniView: FC<{}> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setEngravingLockData(new FurnitureEngravingLockData(parser.furniId));
setEngravingStage(parser.start ? 1 : 2);
});
}, []);
UseMessageEventHook(LoveLockFurniStartEvent, onLoveLockFurniStartEvent);

View File

@ -2,7 +2,6 @@ import { RoomObjectCategory, RoomObjectOperationType } from '@nitrots/nitro-rend
import { FC, useCallback, useMemo, useState } from 'react';
import { CreateLinkEvent, GetRoomEngine, GetSessionDataManager, LocalizeText, ProductTypeEnum, RoomWidgetPresentOpenMessage, RoomWidgetUpdatePresentDataEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
import { Button, Column, Flex, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks/events/UseEventDispatcherHook';
import { useRoomContext } from '../../../RoomContext';
@ -49,8 +48,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
switch(event.type)
{
case RoomWidgetUpdatePresentDataEvent.PACKAGEINFO: {
BatchUpdates(() =>
{
setOpenRequested(false);
setObjectId(event.objectId);
setText(event.giftMessage);
@ -58,7 +55,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
setSenderName(event.purchaserName);
setSenderFigure(event.purchaserFigure);
setImageUrl(event.imageUrl);
});
return;
}
case RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR:
@ -70,8 +66,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
else if(event.type === RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE) imageType = 'packagecard_icon_landscape';
else if(event.type === RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER) imageType = 'packagecard_icon_wallpaper';
BatchUpdates(() =>
{
setObjectId(event.objectId);
setClassId(event.classId);
setItemType(event.itemType);
@ -81,26 +75,20 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
setPlacedItemType(event.placedItemType);
setPlacedInRoom(event.placedInRoom);
setImageUrl(getGiftImageUrl(imageType));
});
return;
}
case RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB: {
BatchUpdates(() =>
{
setObjectId(event.objectId);
setClassId(event.classId);
setItemType(event.itemType);
setText(event.giftMessage);
setIsOwnerOfFurniture(event.isController);
setImageUrl(getGiftImageUrl('packagecard_icon_hc'));
});
return;
}
case RoomWidgetUpdatePresentDataEvent.CONTENTS: {
if(!openRequested) return;
BatchUpdates(() =>
{
setObjectId(event.objectId);
setClassId(event.classId);
setItemType(event.itemType);
@ -110,7 +98,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
setPlacedItemType(event.placedItemType);
setPlacedInRoom(event.placedInRoom);
setImageUrl(event.imageUrl);
});
return;
}
case RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE: {
@ -142,8 +129,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() =>
{
BatchUpdates(() =>
{
setObjectId(-1);
setOpenRequested(false);
@ -151,7 +136,6 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
setPlacedInRoom(false);
setText(null);
setIsOwnerOfFurniture(false);
});
}, []);
const isSpaces = useMemo(() =>

View File

@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoomObjectOperationType } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { ProcessRoomObjectOperation, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { ObjectLocationView } from '../../object-location/ObjectLocationView';
@ -33,33 +33,24 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
switch(event.type)
{
case RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION: {
BatchUpdates(() =>
{
setIsVisible(true);
setObjectId(event.id);
setObjectType(event.category);
});
return;
}
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
if(event.id === objectId)
{
BatchUpdates(() =>
{
setIsVisible(false);
setObjectId(-1);
setObjectType(-1);
});
}
return;
}
case RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED: {
BatchUpdates(() =>
{
setIsVisible(false);
setObjectId(-1);
setObjectType(-1);
});
return;
}
}
@ -74,12 +65,9 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
moveFurniture();
BatchUpdates(() =>
{
setIsVisible(false);
setObjectId(-1);
setObjectType(-1);
});
}, [ moveFurniture ]);
UseEventDispatcherHook(RoomWidgetUpdateDecorateModeEvent.UPDATE_DECORATE, eventDispatcher, onRoomWidgetUpdateDecorateModeEvent);

View File

@ -7,5 +7,6 @@ export class FurnitureMannequinData
public figure: string,
public gender: string,
public clubLevel: number,
public renderedFigure: string = null) {}
public renderedFigure: string = null)
{}
}

View File

@ -2,7 +2,7 @@ import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMann
import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react';
import { GetAvatarRenderManager, GetClubMemberLevel, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent, SendMessageComposer } from '../../../../../api';
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../../hooks';
import { UseEventDispatcherHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
const MODE_NONE: number = -1;
@ -43,8 +43,6 @@ export const FurnitureMannequinView: FC<{}> = props =>
const figureContainer = GetAvatarRenderManager().createFigureContainer(event.figure);
const figureClubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, event.gender, MANNEQUIN_CLOTHING_PART_TYPES);
BatchUpdates(() =>
{
setObjectId(event.objectId);
setFigure(event.figure);
setGender(event.gender);
@ -69,7 +67,6 @@ export const FurnitureMannequinView: FC<{}> = props =>
{
setMode(MODE_PEER);
}
});
}, [ roomSession ]);
UseEventDispatcherHook(RoomWidgetUpdateMannequinEvent.MANNEQUIN_UPDATE, eventDispatcher, onRoomWidgetUpdateMannequinEvent);
@ -136,11 +133,8 @@ export const FurnitureMannequinView: FC<{}> = props =>
transformAsMannequinFigure(figureContainer);
BatchUpdates(() =>
{
setRenderedFigure(figureContainer.getFigureString());
setRenderedClubLevel(clubLevel);
});
break;
}
case MODE_UPDATE: {
@ -148,22 +142,16 @@ export const FurnitureMannequinView: FC<{}> = props =>
transformAsMannequinFigure(figureContainer);
BatchUpdates(() =>
{
setRenderedFigure(figureContainer.getFigureString());
setRenderedClubLevel(GetAvatarRenderManager().getFigureClubLevel(figureContainer, GetSessionDataManager().gender, MANNEQUIN_CLOTHING_PART_TYPES));
});
break;
}
case MODE_PEER:
case MODE_NO_CLUB: {
const figureContainer = getMergedFigureContainer(GetSessionDataManager().figure, figure);
BatchUpdates(() =>
{
setRenderedFigure(figureContainer.getFigureString());
setRenderedClubLevel(clubLevel);
});
break;
}
}

View File

@ -6,5 +6,6 @@ export class FurnitureStickieData
public color: string,
public text: string,
public canModify: boolean = false,
public isEditing: boolean = false) {}
public isEditing: boolean = false)
{}
}

View File

@ -7,5 +7,6 @@ export class FurnitureTrophyData
public ownerName: string,
public date: string,
public message: string,
public customTitle?: string) {}
public customTitle?: string)
{}
}

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useMemo, useState } from 'react';
import YouTube, { Options } from 'react-youtube';
import { FurnitureYoutubeDisplayWidgetHandler, LocalizeText, RoomWidgetUpdateYoutubeDisplayEvent, SendMessageComposer } from '../../../../../api';
import { Grid, LayoutGridItem, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
import { UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { YoutubeVideoPlaybackStateEnum } from './utils/YoutubeVideoPlaybackStateEnum';
@ -53,13 +53,10 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return;
BatchUpdates(() =>
{
setVideoId(parser.videoId);
setVideoStart(parser.startAtSeconds);
setVideoEnd(parser.endAtSeconds);
setCurrentVideoState(parser.state);
});
}, [ objectId ]);
const onPlaylists = useCallback((event: YoutubeDisplayPlaylistsEvent) =>
@ -70,15 +67,12 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return;
BatchUpdates(() =>
{
setPlaylists(parser.playlists);
setSelectedItem(parser.selectedPlaylistId);
setVideoId(null);
setCurrentVideoState(-1);
setVideoEnd(null);
setVideoStart(null);
});
}, [ objectId ]);
const onControlVideo = useCallback((event: YoutubeControlVideoMessageEvent) =>

View File

@ -3,7 +3,7 @@ import { CrackableDataType, GroupInformationComposer, GroupInformationEvent, Roo
import { FC, useCallback, useEffect, useState } from 'react';
import { CreateLinkEvent, GetGroupInformation, GetRoomEngine, LocalizeText, RoomWidgetFurniActionMessage, RoomWidgetUpdateInfostandFurniEvent, SendMessageComposer } from '../../../../api';
import { Button, Column, Flex, LayoutBadgeImageView, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, Text, UserProfileIconView } from '../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks';
import { UseMessageEventHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
interface InfoStandWidgetFurniViewProps
@ -129,8 +129,6 @@ export const InfoStandWidgetFurniView: FC<InfoStandWidgetFurniViewProps> = props
if(furniData.isStickie) pickupMode = PICKUP_MODE_NONE;
BatchUpdates(() =>
{
setPickupMode(pickupMode);
setCanMove(canMove);
setCanRotate(canRotate);
@ -145,7 +143,6 @@ export const InfoStandWidgetFurniView: FC<InfoStandWidgetFurniViewProps> = props
setGodMode(godMode);
setCanSeeFurniId(canSeeFurniId);
setGroupName(null);
});
if(furniData.groupId) SendMessageComposer(new GroupInformationComposer(furniData.groupId, false));
}, [ roomSession, furniData ]);

View File

@ -3,7 +3,7 @@ import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomS
import { Dispatch, FC, FocusEvent, KeyboardEvent, SetStateAction, useCallback, useEffect, useState } from 'react';
import { CloneObject, GetConfiguration, GetGroupInformation, GetSessionDataManager, GetUserProfile, LocalizeText, RoomWidgetChangeMottoMessage, RoomWidgetUpdateInfostandUserEvent, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, Text, UserProfileIconView } from '../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseMessageEventHook } from '../../../../hooks';
import { UseEventDispatcherHook, UseMessageEventHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { InfoStandWidgetUserRelationshipsView } from './InfoStandWidgetUserRelationshipsView';
@ -112,23 +112,17 @@ export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =
UseMessageEventHook(RelationshipStatusInfoEvent, onUserRelationshipsEvent);
useEffect(() =>
{
BatchUpdates(() =>
{
setIsEditingMotto(false);
setMotto(userData.motto);
});
SendMessageComposer(new UserRelationshipsComposer(userData.webID));
return () =>
{
BatchUpdates(() =>
{
setIsEditingMotto(false);
setMotto(null);
setRelationships(null);
});
}
}, [ userData ]);

View File

@ -3,7 +3,7 @@ import classNames from 'classnames';
import { FC, useCallback, useEffect, useState } from 'react';
import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
import { BatchUpdates, UseMessageEventHook, useSharedNavigatorData } from '../../../../hooks';
import { UseMessageEventHook, useSharedNavigatorData } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
export const RoomToolsWidgetView: FC<{}> = props =>
@ -46,12 +46,9 @@ export const RoomToolsWidgetView: FC<{}> = props =>
if(!parser.roomEnter) return;
BatchUpdates(() =>
{
if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName);
if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName);
if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags);
});
}, [ roomName, roomOwner, roomTags ]);
UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);

View File

@ -1,7 +1,7 @@
import { IQuestion } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { RoomWidgetPollMessage, RoomWidgetWordQuizUpdateEvent } from '../../../../api';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks';
import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext';
import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE, VoteValue } from './common/VoteValue';
import { WordQuizQuestionView } from './WordQuizQuestionView';
@ -31,8 +31,6 @@ export const WordQuizWidgetView: FC<{}> = props =>
switch(event.type)
{
case RoomWidgetWordQuizUpdateEvent.NEW_QUESTION:
BatchUpdates(() =>
{
setPollId(event.id);
setQuestion(event.question);
setAnswerSent(false);
@ -52,15 +50,12 @@ export const WordQuizWidgetView: FC<{}> = props =>
return null;
});
});
break;
case RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED: {
const userData = roomSession.userDataManager.getUserData(event.userId);
if(!userData) return;
BatchUpdates(() =>
{
setAnswerCounts(event.answerCounts);
setUserAnswers(prevValue =>
@ -76,13 +71,10 @@ export const WordQuizWidgetView: FC<{}> = props =>
return prevValue;
});
});
break;
}
case RoomWidgetWordQuizUpdateEvent.QUESTION_FINISHED:
if(question && question.id === event.questionId)
{
BatchUpdates(() =>
{
setAnswerCounts(event.answerCounts);
setAnswerSent(true);
@ -93,7 +85,6 @@ export const WordQuizWidgetView: FC<{}> = props =>
return setTimeout(() => clearQuestion(), DEFAULT_DISPLAY_DELAY) as unknown as number;
});
});
}
setUserAnswers(new Map());

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useState } from 'react';
import { CreateLinkEvent, GetSessionDataManager, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api';
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
import { AchievementsUIUnseenCountEvent, ModToolsEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, useFriends, useInventoryUnseenTracker, UseMessageEventHook, useMessenger, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
import { DispatchUiEvent, useFriends, useInventoryUnseenTracker, UseMessageEventHook, useMessenger, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
import { ToolbarMeView } from './ToolbarMeView';
export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
@ -24,11 +24,8 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
{
const parser = event.getParser();
BatchUpdates(() =>
{
setUserInfo(parser.userInfo);
setUserFigure(parser.userInfo.figure);
});
}, []);
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);

View File

@ -2,7 +2,7 @@ import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomE
import { FC, useCallback, useState } from 'react';
import { CreateLinkEvent, GetRoomSession, GetSessionDataManager, GetUserProfile, LocalizeText, SendMessageComposer } from '../../api';
import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
import { BatchUpdates, UseMessageEventHook, UseRoomEngineEvent } from '../../hooks';
import { UseMessageEventHook, UseRoomEngineEvent } from '../../hooks';
import { BadgesContainerView } from './views/BadgesContainerView';
import { FriendsContainerView } from './views/FriendsContainerView';
import { GroupsContainerView } from './views/GroupsContainerView';
@ -15,13 +15,10 @@ export const UserProfileView: FC<{}> = props =>
const [ userRelationships, setUserRelationships ] = useState<RelationshipStatusInfoMessageParser>(null);
const onClose = () =>
{
BatchUpdates(() =>
{
setUserProfile(null);
setUserBadges([]);
setUserRelationships(null);
});
}
const onLeaveGroup = useCallback(() =>
@ -59,8 +56,6 @@ export const UserProfileView: FC<{}> = props =>
let isSameProfile = false;
BatchUpdates(() =>
{
setUserProfile(prevValue =>
{
if(prevValue && prevValue.id) isSameProfile = (prevValue.id === parser.id);
@ -73,7 +68,6 @@ export const UserProfileView: FC<{}> = props =>
setUserBadges([]);
setUserRelationships(null);
}
});
SendMessageComposer(new UserCurrentBadgesComposer(parser.id));
SendMessageComposer(new UserRelationshipsComposer(parser.id));

View File

@ -2,7 +2,7 @@ import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser
import { FC, useCallback, useEffect, useState } from 'react';
import { SendMessageComposer, ToggleFavoriteGroup } from '../../../api';
import { AutoGrid, Base, Column, Flex, Grid, GridProps, LayoutBadgeImageView, LayoutGridItem } from '../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
import { UseMessageEventHook } from '../../../hooks';
import { GroupInformationView } from '../../groups/views/GroupInformationView';
interface GroupsContainerViewProps extends GridProps
@ -37,8 +37,6 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
}, [ selectedGroupId ]);
useEffect(() =>
{
BatchUpdates(() =>
{
setGroupInformation(null);
@ -54,7 +52,6 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
return groups[0].groupId;
});
}
});
}, [ groups ]);
if(!groups || !groups.length)

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useState } from 'react';
import { GetSessionDataManager, LocalizeText, WiredFurniType, WiredSelectionVisualizer } from '../../../api';
import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
import { BatchUpdates } from '../../../hooks';
import { useWiredContext } from '../WiredContext';
import { WiredFurniSelectorView } from './WiredFurniSelectorView';
@ -49,8 +48,6 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props =>
const spriteId = (trigger.spriteId || -1);
const furniData = GetSessionDataManager().getFloorItemData(spriteId);
BatchUpdates(() =>
{
if(!furniData)
{
setWiredName(('NAME: ' + spriteId));
@ -84,11 +81,8 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props =>
return [];
});
}
});
return () =>
{
BatchUpdates(() =>
{
setNeedsSave(false);
setIntParams([]);
@ -99,7 +93,6 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props =>
return [];
});
});
}
}, [ trigger, hasSpecialInput, requiresFurni, setIntParams, setStringParam, setFurniIds ]);

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useState } from 'react';
import { GetSessionDataManager, LocalizeText, WiredFurniType, WIRED_STRING_DELIMETER } from '../../../../api';
import { Button, Column, Flex, LayoutAvatarImageView, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { useWiredContext } from '../../WiredContext';
import { WiredActionBaseView } from './WiredActionBaseView';
@ -19,11 +18,8 @@ export const WiredActionBotChangeFigureView: FC<{}> = props =>
{
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
BatchUpdates(() =>
{
if(data.length > 0) setBotName(data[0]);
if(data.length > 1) setFigure(data[1].length > 0 ? data[1] : DEFAULT_FIGURE);
});
}, [ trigger ]);
return (

Some files were not shown because too many files have changed in this diff Show More