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.insertFinalNewline": true,
"files.trimFinalNewlines": true, "files.trimFinalNewlines": true,
"editor.wordWrap": "on", "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": "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", "build:prod": "npx browserslist@latest --update-db && yarn build",
"test": "craco test", "test": "craco test",
"eject": "react-scripts eject" "eject": "react-scripts eject",
"eslint": "eslint src --ext .ts,.tsx"
}, },
"dependencies": { "dependencies": {
"@craco/craco": "^6.3.0", "@craco/craco": "^6.3.0",
@ -20,11 +21,11 @@
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"emoji-toolkit": "^6.6.0", "emoji-toolkit": "^6.6.0",
"node-sass": "^6.0.1", "node-sass": "^6.0.1",
"react": "^17.0.2", "react": "^18.0.0",
"react-bootstrap": "^2.2.2", "react-bootstrap": "^2.2.2",
"react-dom": "^17.0.2", "react-dom": "^18.0.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"react-slider": "^1.3.1", "react-slider": "^2.0.0",
"react-transition-group": "^4.4.2", "react-transition-group": "^4.4.2",
"react-virtualized": "^9.22.3", "react-virtualized": "^9.22.3",
"react-youtube": "^7.13.1", "react-youtube": "^7.13.1",
@ -41,7 +42,13 @@
"@types/react-slider": "^1.3.1", "@types/react-slider": "^1.3.1",
"@types/react-transition-group": "^4.4.2", "@types/react-transition-group": "^4.4.2",
"@types/react-virtualized": "^9.21.13", "@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" "react-error-overlay": "6.0.9"
} }
} }

View File

@ -6,5 +6,6 @@ export class MessengerSettings
public userFriendLimit: number = 0, public userFriendLimit: number = 0,
public normalFriendLimit: number = 0, public normalFriendLimit: number = 0,
public extendedFriendLimit: 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 itemCount: number = 0,
public creditsCount: number = 0, public creditsCount: number = 0,
public accepts: boolean = false, public accepts: boolean = false,
public canTrade: boolean = false) {} public canTrade: boolean = false)
{}
} }

View File

@ -3,7 +3,6 @@ export interface IUnseenItemTracker
dispose(): void; dispose(): void;
resetCategory(category: number): boolean; resetCategory(category: number): boolean;
resetItems(category: number, itemIds: number[]): boolean; resetItems(category: number, itemIds: number[]): boolean;
resetCategoryIfEmpty(category: number): boolean;
isUnseen(category: number, itemId: number): boolean; isUnseen(category: number, itemId: number): boolean;
removeUnseen(category: number, itemId: number): boolean; removeUnseen(category: number, itemId: number): boolean;
getIds(category: number): number[]; 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 { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Base } from '..'; import { Base } from '..';
import { BatchUpdates } from '../../hooks';
import { DraggableWindowPosition } from './DraggableWindowPosition'; import { DraggableWindowPosition } from './DraggableWindowPosition';
const CURRENT_WINDOWS: HTMLElement[] = []; const CURRENT_WINDOWS: HTMLElement[] = [];
@ -134,12 +133,9 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
offsetX = (document.body.offsetWidth - elementRef.current.offsetWidth) - elementRef.current.offsetLeft; offsetX = (document.body.offsetWidth - elementRef.current.offsetWidth) - elementRef.current.offsetLeft;
} }
BatchUpdates(() =>
{
setDelta({ x: 0, y: 0 }); setDelta({ x: 0, y: 0 });
setOffset({ x: offsetX, y: offsetY }); setOffset({ x: offsetX, y: offsetY });
setIsDragging(false); setIsDragging(false);
});
if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY }); if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY });
}, [ dragHandler, delta, offset, uniqueKey ]); }, [ dragHandler, delta, offset, uniqueKey ]);
@ -201,11 +197,8 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
} }
} }
BatchUpdates(() =>
{
setDelta({ x: 0, y: 0 }); setDelta({ x: 0, y: 0 });
setOffset({ x: offsetX, y: offsetY }); setOffset({ x: offsetX, y: offsetY });
});
return () => return () =>
{ {
@ -213,7 +206,7 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
if(index >= 0) CURRENT_WINDOWS.splice(index, 1); if(index >= 0) CURRENT_WINDOWS.splice(index, 1);
} }
}, [ handleSelector, windowPosition, uniqueKey, disableDrag, bringToTop ]); }, [ handleSelector, windowPosition, uniqueKey, disableDrag, offsetLeft, offsetTop, bringToTop ]);
useEffect(() => useEffect(() =>
{ {

View File

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

View File

@ -8,15 +8,11 @@ interface LayoutLimitedEditionStyledNumberViewProps
export const LayoutLimitedEditionStyledNumberView: FC<LayoutLimitedEditionStyledNumberViewProps> = props => export const LayoutLimitedEditionStyledNumberView: FC<LayoutLimitedEditionStyledNumberViewProps> = props =>
{ {
const { value = 0 } = props; const { value = 0 } = props;
const numbers = value.toString().split(''); const numbers = value.toString().split('');
return ( return (
<> <>
{ numbers.map((number, index) => { numbers.map((number, index) => <i key={ index } className={ 'limited-edition-number n-' + number } />) }
{
return <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 { AchievementCategory, AddEventLinkTracker, CloneObject, GetAchievementCategoryImageUrl, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common'; import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
import { AchievementsUIUnseenCountEvent } from '../../events'; import { AchievementsUIUnseenCountEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks'; import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { AchievementCategoryView } from './views/AchievementCategoryView'; import { AchievementCategoryView } from './views/AchievementCategoryView';
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView'; import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
@ -92,11 +92,8 @@ export const AchievementsView: FC<{}> = props =>
existing.achievements.push(achievement); existing.achievements.push(achievement);
} }
BatchUpdates(() =>
{
setAchievementCategories(categories); setAchievementCategories(categories);
setIsInitalized(true); setIsInitalized(true);
});
}, []); }, []);
UseMessageEventHook(AchievementsEvent, onAchievementsEvent); UseMessageEventHook(AchievementsEvent, onAchievementsEvent);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@ import { BuyMarketplaceOfferMessageComposer, GetMarketplaceOffersMessageComposer
import { FC, useCallback, useMemo, useState } from 'react'; import { FC, useCallback, useMemo, useState } from 'react';
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api'; import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api';
import { Button, ButtonGroup, Column, Text } from '../../../../../../common'; import { Button, ButtonGroup, Column, Text } from '../../../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../../../hooks'; import { UseMessageEventHook } from '../../../../../../hooks';
import { GetCurrencyAmount } from '../../../../../purse/common/CurrencyHelper'; import { GetCurrencyAmount } from '../../../../../purse/common/CurrencyHelper';
import { CatalogLayoutProps } from '../CatalogLayout.types'; import { CatalogLayoutProps } from '../CatalogLayout.types';
import { CatalogLayoutMarketplaceItemView, PUBLIC_OFFER } from './CatalogLayoutMarketplaceItemView'; import { CatalogLayoutMarketplaceItemView, PUBLIC_OFFER } from './CatalogLayoutMarketplaceItemView';
@ -75,12 +75,8 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
latestOffers.set(entry.offerId, offerEntry); latestOffers.set(entry.offerId, offerEntry);
}); });
BatchUpdates(() =>
{
setTotalItemsFound(parser.totalItemsFound); setTotalItemsFound(parser.totalItemsFound);
setOffers(latestOffers); setOffers(latestOffers);
});
}, []); }, []);
const onMarketplaceBuyOfferResultEvent = useCallback( (event: MarketplaceBuyOfferResultEvent) => 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)); SendMessageComposer(new MakeOfferMessageComposer(askingPrice, item.isWallItem ? 2 : 1, item.id));
setItem(null); setItem(null);
}, },
() => { setItem(null) }, null, null, LocalizeText('inventory.marketplace.confirm_offer.title')); () =>
{
setItem(null)
}, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
} }
return ( return (

View File

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

View File

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

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { LocalizeText, ProductTypeEnum } from '../../../../../api'; import { LocalizeText, ProductTypeEnum } from '../../../../../api';
import { AutoGrid, AutoGridProps, Button, ButtonGroup } from '../../../../../common'; import { AutoGrid, AutoGridProps, Button, ButtonGroup } from '../../../../../common';
import { BatchUpdates } from '../../../../../hooks';
import { useCatalogContext } from '../../../CatalogContext'; import { useCatalogContext } from '../../../CatalogContext';
import { IPurchasableOffer } from '../../../common/IPurchasableOffer'; import { IPurchasableOffer } from '../../../common/IPurchasableOffer';
import { Offer } from '../../../common/Offer'; import { Offer } from '../../../common/Offer';
@ -52,12 +51,9 @@ export const CatalogSpacesWidgetView: FC<CatalogSpacesWidgetViewProps> = props =
} }
} }
BatchUpdates(() =>
{
setGroupedOffers(groupedOffers); setGroupedOffers(groupedOffers);
setSelectedGroupIndex(0); setSelectedGroupIndex(0);
setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]); setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]);
});
}, [ currentPage ]); }, [ currentPage ]);
useEffect(() => 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 { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized';
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api'; import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
import { BatchUpdates } from '../../hooks';
import { ChatHistoryContextProvider } from './ChatHistoryContext'; import { ChatHistoryContextProvider } from './ChatHistoryContext';
import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler'; import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler';
import { ChatEntryType } from './common/ChatEntryType'; import { ChatEntryType } from './common/ChatEntryType';
@ -91,11 +90,8 @@ export const ChatHistoryView: FC<{}> = props =>
chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1)); chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1));
roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1)); roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1));
BatchUpdates(() =>
{
setChatHistoryState(chatState); setChatHistoryState(chatState);
setRoomHistoryState(roomState); setRoomHistoryState(roomState);
});
return () => return () =>
{ {

View File

@ -2,7 +2,7 @@ import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } fr
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api'; import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, Text, UserProfileIconView } from '../../../../common'; 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 interface FriendsSearchViewProps extends NitroCardAccordionSetViewProps
{ {
@ -21,11 +21,8 @@ export const FriendsSearchView: FC<FriendsSearchViewProps> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
BatchUpdates(() =>
{
setFriendResults(parser.friends); setFriendResults(parser.friends);
setOtherResults(parser.others); setOtherResults(parser.others);
});
}, []); }, []);
UseMessageEventHook(HabboSearchResultEvent, onHabboSearchResultEvent); 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 { FC, KeyboardEvent, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api'; 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 { 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'; import { FriendsMessengerThreadView } from './FriendsMessengerThreadView';
export const FriendsMessengerView: FC<{}> = props => export const FriendsMessengerView: FC<{}> = props =>
@ -54,11 +54,8 @@ export const FriendsMessengerView: FC<{}> = props =>
if(!thread) return; if(!thread) return;
BatchUpdates(() =>
{
setActiveThread(thread); setActiveThread(thread);
setIsVisible(true); setIsVisible(true);
});
} }
} }
}, },

View File

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

View File

@ -3,7 +3,7 @@ import { GroupAdminGiveComposer, GroupAdminTakeComposer, GroupConfirmMemberRemov
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { AddEventLinkTracker, GetSessionDataManager, GetUserProfile, LocalizeText, NotificationUtilities, RemoveLinkEventTracker, SendMessageComposer } from '../../../api'; 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 { 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 => export const GroupMembersView: FC<{}> = props =>
{ {
@ -76,12 +76,9 @@ export const GroupMembersView: FC<{}> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
BatchUpdates(() =>
{
setMembersData(parser); setMembersData(parser);
setLevelId(parser.level); setLevelId(parser.level);
setTotalPages(Math.ceil(parser.totalMembersCount / parser.pageSize)); setTotalPages(Math.ceil(parser.totalMembersCount / parser.pageSize));
});
}, []); }, []);
UseMessageEventHook(GroupMembersEvent, onGroupMembersEvent); UseMessageEventHook(GroupMembersEvent, onGroupMembersEvent);
@ -111,11 +108,8 @@ export const GroupMembersView: FC<{}> = props =>
const groupId = (parseInt(parts[1]) || -1); const groupId = (parseInt(parts[1]) || -1);
const levelId = (parseInt(parts[2]) || 3); const levelId = (parseInt(parts[2]) || 3);
BatchUpdates(() =>
{
setGroupId(groupId); setGroupId(groupId);
setLevelId(levelId); setLevelId(levelId);
});
}, []); }, []);
useEffect(() => useEffect(() =>
@ -146,14 +140,11 @@ export const GroupMembersView: FC<{}> = props =>
{ {
if(groupId === -1) return; if(groupId === -1) return;
BatchUpdates(() =>
{
setLevelId(-1); setLevelId(-1);
setMembersData(null); setMembersData(null);
setTotalPages(0); setTotalPages(0);
setSearchQuery(''); setSearchQuery('');
setRemovingMemberName(null); setRemovingMemberName(null);
})
}, [ groupId ]); }, [ groupId ]);
if((groupId === -1) || !membersData) return null; 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 { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api'; import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
import { Base, Button, Column, Flex, Text } from '../../../../common'; import { Base, Button, Column, Flex, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { IGroupData } from '../../common/IGroupData'; import { IGroupData } from '../../common/IGroupData';
interface GroupTabIdentityViewProps interface GroupTabIdentityViewProps
@ -64,13 +63,10 @@ export const GroupTabIdentityView: FC<GroupTabIdentityViewProps> = props =>
}, [ groupData, groupName, groupDescription, groupHomeroomId, setGroupData ]); }, [ groupData, groupName, groupDescription, groupHomeroomId, setGroupData ]);
useEffect(() => useEffect(() =>
{
BatchUpdates(() =>
{ {
setGroupName(groupData.groupName || ''); setGroupName(groupData.groupName || '');
setGroupDescription(groupData.groupDescription || ''); setGroupDescription(groupData.groupDescription || '');
setGroupHomeroomId(groupData.groupHomeroomId); setGroupHomeroomId(groupData.groupHomeroomId);
});
}, [ groupData ]); }, [ groupData ]);
useEffect(() => useEffect(() =>

View File

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

View File

@ -85,7 +85,7 @@ export const GuideToolOngoingView: FC<GuideToolOngoingViewProps> = props =>
{ messageGroups.map((group, index) => { messageGroups.map((group, index) =>
{ {
return ( 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"> <Base shrink className="message-avatar">
{ (!isOwnChat(group.userId)) && { (!isOwnChat(group.userId)) &&
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } /> } <LayoutAvatarImageView figure={ userFigure } direction={ 2 } /> }

View File

@ -207,7 +207,10 @@ export const HcCenterView: FC<{}> = props =>
<hr className="w-100 text-black my-1" /> <hr className="w-100 text-black my-1" />
<div>{LocalizeText('hccenter.breakdown.total', [ 'credits', 'actual' ], [ getHcPaydayAmount(), <div>{LocalizeText('hccenter.breakdown.total', [ 'credits', 'actual' ], [ getHcPaydayAmount(),
((((kickbackData.kickbackPercentage * kickbackData.totalCreditsSpent) + kickbackData.creditRewardForStreakBonus) * 100) / 100).toString() ])}</div> ((((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')} LocalizeText('hccenter.special.infolink')}
</div> </div>
</Popover.Body> </Popover.Body>
@ -221,7 +224,10 @@ export const HcCenterView: FC<{}> = props =>
<Column gap={ 1 }> <Column gap={ 1 }>
<div className="hc-logo" /> <div className="hc-logo" />
<Flex> <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') } { LocalizeText((clubStatus === ClubStatus.ACTIVE) ? 'hccenter.btn.extend' : 'hccenter.btn.buy') }
</Button> </Button>
</Flex> </Flex>
@ -243,7 +249,10 @@ export const HcCenterView: FC<{}> = props =>
<Column className="rounded-start bg-primary p-2 payday-special mb-1"> <Column className="rounded-start bg-primary p-2 payday-special mb-1">
<h4 className="mb-1">{LocalizeText('hccenter.special.title')}</h4> <h4 className="mb-1">{LocalizeText('hccenter.special.title')}</h4>
<div>{LocalizeText('hccenter.special.info')}</div> <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> </Column>
<div className="payday flex-shrink-0 p-2"> <div className="payday flex-shrink-0 p-2">
<h5 className="mb-2 ms-2">{LocalizeText('hccenter.special.time.title')}</h5> <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> <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 dangerouslySetInnerHTML={{ __html: unclaimedGifts > 0 ? LocalizeText('hccenter.unclaimedgifts', [ 'unclaimedgifts' ], [ unclaimedGifts.toString() ]) : LocalizeText('hccenter.gift.info') }}></div>
</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> </div>
} }
{GetConfiguration('hc.center')['benefits.info'] && {GetConfiguration('hc.center')['benefits.info'] &&
<div className="benefits text-black py-2"> <div className="benefits text-black py-2">
<h5 className="mb-1 text-primary">{LocalizeText('hccenter.general.title')}</h5> <h5 className="mb-1 text-primary">{LocalizeText('hccenter.general.title')}</h5>
<div className="mb-2" dangerouslySetInnerHTML={{ __html: LocalizeText('hccenter.general.info') }} /> <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> </div>
} }
</NitroCardContentView> </NitroCardContentView>

View File

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

View File

@ -4,11 +4,11 @@ import { AddEventLinkTracker, GetLocalization, GetRoomEngine, LocalizeText, Remo
import { isObjectMoverRequested, setObjectMoverRequested } from '../../api/inventory/InventoryUtilities'; import { isObjectMoverRequested, setObjectMoverRequested } from '../../api/inventory/InventoryUtilities';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { useInventoryTrade, useInventoryUnseenTracker, UseMessageEventHook, UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../hooks'; import { useInventoryTrade, useInventoryUnseenTracker, UseMessageEventHook, UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../hooks';
import { InventoryBadgeView } from './views/InventoryBadgeView'; import { InventoryBadgeView } from './views/badge/InventoryBadgeView';
import { InventoryBotView } from './views/InventoryBotView'; import { InventoryBotView } from './views/bot/InventoryBotView';
import { InventoryFurnitureView } from './views/InventoryFurnitureView'; import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
import { InventoryPetView } from './views/InventoryPetView'; import { InventoryTradeView } from './views/furniture/InventoryTradeView';
import { InventoryTradeView } from './views/InventoryTradeView'; import { InventoryPetView } from './views/pet/InventoryPetView';
const TAB_FURNITURE: string = 'inventory.furni'; const TAB_FURNITURE: string = 'inventory.furni';
const TAB_BOTS: string = 'inventory.bots'; const TAB_BOTS: string = 'inventory.bots';
@ -130,10 +130,8 @@ export const InventoryView: FC<{}> = props =>
<NitroCardTabsView> <NitroCardTabsView>
{ TABS.map((name, index) => { TABS.map((name, index) =>
{ {
const unseenCount = getCount(UNSEEN_CATEGORIES[index]);
return ( 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) } { LocalizeText(name) }
</NitroCardTabsItemView> </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 { FC, useEffect, useState } from 'react';
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../api'; import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, LayoutGridItem, Text } from '../../../common'; import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, Text } from '../../../../common';
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../hooks'; import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryBadgeItemView } from './InventoryBadgeItemView';
export const InventoryBadgeView: FC<{}> = props => 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(); const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
useEffect(() => 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); return () => deactivate(id);
} }, [ isVisible, activate, deactivate ]);
}, [ badgeCodes, getCount, resetCategory ]);
const InventoryBadgeItemView: FC<{ badgeCode: string }> = props => useEffect(() =>
{ {
const { badgeCode = null, children = null, ...rest } = props; setIsVisible(true);
const badgeId = getBadgeId(badgeCode);
const unseen = isUnseen(UnseenItemCategory.BADGE, badgeId);
const select = () => return () => setIsVisible(false);
{ }, []);
selectBadge(badgeCode);
if(unseen) removeUnseen(UnseenItemCategory.BADGE, badgeId);
}
return (
<LayoutGridItem itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onMouseDown={ select } { ...rest }>
<LayoutBadgeImageView badgeCode={ badgeCode } />
{ children }
</LayoutGridItem>
);
}
return ( return (
<Grid> <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 { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { attemptBotPlacement, GetRoomEngine, IBotItem, LocalizeText, UnseenItemCategory } from '../../../api'; import { attemptBotPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutAvatarImageView, LayoutGridItem, LayoutRoomPreviewerView, Text } from '../../../common'; import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryBots, useInventoryUnseenTracker } from '../../../hooks'; import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryBotItemView } from './InventoryBotItemView';
interface InventoryBotViewProps interface InventoryBotViewProps
{ {
@ -14,22 +15,9 @@ interface InventoryBotViewProps
export const InventoryBotView: FC<InventoryBotViewProps> = props => export const InventoryBotView: FC<InventoryBotViewProps> = props =>
{ {
const { roomSession = null, roomPreviewer = null } = props; const { roomSession = null, roomPreviewer = null } = props;
const { botItems = [], selectedBot = null, selectBot = null } = useInventoryBots(); const [ isVisible, setIsVisible ] = useState(false);
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker(); const { botItems = [], selectedBot = null, activate = null, deactivate = null } = useInventoryBots();
const { 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 ]);
useEffect(() => useEffect(() =>
{ {
@ -53,44 +41,31 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
roomPreviewer.addAvatarIntoRoom(botData.figure, 0); roomPreviewer.addAvatarIntoRoom(botData.figure, 0);
}, [ roomPreviewer, selectedBot ]); }, [ 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') } />; 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 ( return (
<Grid> <Grid>
<Column size={ 7 } overflow="hidden"> <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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'; import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
import { GroupItem, LocalizeText } from '../../../api'; import { GroupItem, LocalizeText } from '../../../../api';
import { Button, Flex } from '../../../common'; import { Button, Flex } from '../../../../common';
export interface InventoryFurnitureSearchViewProps export interface InventoryFurnitureSearchViewProps
{ {

View File

@ -1,10 +1,11 @@
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer'; import { IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../api'; import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../common'; import { AutoGrid, Button, Column, Grid, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../hooks'; import { useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks';
import { attemptPlaceMarketplaceOffer } from '../../../hooks/inventory/common'; import { attemptPlaceMarketplaceOffer } from '../../../../hooks/inventory/common';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryFurnitureItemView } from './InventoryFurnitureItemView';
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView'; import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
interface InventoryFurnitureViewProps interface InventoryFurnitureViewProps
@ -16,9 +17,10 @@ interface InventoryFurnitureViewProps
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props => export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
{ {
const { roomSession = null, roomPreviewer = null } = props; const { roomSession = null, roomPreviewer = null } = props;
const [ isVisible, setIsVisible ] = useState(false);
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>([]); const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>([]);
const { groupItems = [], selectedItem = null, selectItem = null, activate = null, deactivate = null } = useInventoryFurni(); const { groupItems = [], selectedItem = null, activate = null, deactivate = null } = useInventoryFurni();
const { getCount = null, resetCategory = null } = useInventoryUnseenTracker(); const { resetItems = null } = useInventoryUnseenTracker();
useEffect(() => useEffect(() =>
{ {
@ -72,65 +74,30 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
useEffect(() => useEffect(() =>
{ {
if(!groupItems || !groupItems.length) return; if(!selectedItem || !selectedItem.hasUnseenItems) return;
return () => resetItems(UnseenItemCategory.FURNI, selectedItem.items.map(item => item.id));
{
const count = getCount(UnseenItemCategory.FURNI);
if(!count) return; selectedItem.hasUnseenItems = false;
}, [ selectedItem, resetItems ]);
resetCategory(UnseenItemCategory.FURNI);
for(const groupItem of groupItems) groupItem.hasUnseenItems = false;
}
}, [ groupItems, getCount, resetCategory ]);
useEffect(() => useEffect(() =>
{ {
if(!isVisible) return;
const id = activate(); const id = activate();
return () => deactivate(id); return () => deactivate(id);
}, [ activate, deactivate ]); }, [ isVisible, 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;
}
}
useEffect(() => useEffect(() =>
{ {
if(!isActive) return; setIsVisible(true);
groupItem.hasUnseenItems = false; return () => setIsVisible(false);
}, [ isActive, groupItem ]); }, []);
const count = groupItem.getUnlockedCount(); if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.title') } desc={ LocalizeText('inventory.empty.desc') } />;
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 } />;
}
return ( return (
<Grid> <Grid>

View File

@ -1,10 +1,10 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IObjectData, TradingListAddItemComposer, TradingListAddItemsComposer } from '@nitrots/nitro-renderer'; import { IObjectData, TradingListAddItemComposer, TradingListAddItemsComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../api'; import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../../api';
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../common'; import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../../common';
import { useInventoryTrade } from '../../../hooks'; import { useInventoryTrade } from '../../../../hooks';
import { getGuildFurniType } from '../../../hooks/inventory/common/TradingUtilities'; import { getGuildFurniType } from '../../../../hooks/inventory/common/TradingUtilities';
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView'; import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
interface InventoryTradeViewProps 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 { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { attemptPetPlacement, GetRoomEngine, IPetItem, LocalizeText, UnseenItemCategory } from '../../../api'; import { attemptPetPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutPetImageView, LayoutRoomPreviewerView, Text } from '../../../common'; import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
import { useInventoryPets, useInventoryUnseenTracker } from '../../../hooks'; import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { InventoryPetItemView } from './InventoryPetItemView';
interface InventoryPetViewProps interface InventoryPetViewProps
{ {
@ -14,22 +15,9 @@ interface InventoryPetViewProps
export const InventoryPetView: FC<InventoryPetViewProps> = props => export const InventoryPetView: FC<InventoryPetViewProps> = props =>
{ {
const { roomSession = null, roomPreviewer = null } = props; const { roomSession = null, roomPreviewer = null } = props;
const { petItems = null, selectedPet = null, selectPet = null } = useInventoryPets(); const [ isVisible, setIsVisible ] = useState(false);
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker(); const { petItems = null, selectedPet = null, activate = null, deactivate = null } = useInventoryPets();
const { 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 ]);
useEffect(() => useEffect(() =>
{ {
@ -52,44 +40,31 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
roomPreviewer.addPetIntoRoom(petData.figureString); roomPreviewer.addPetIntoRoom(petData.figureString);
}, [ roomPreviewer, selectedPet ]); }, [ 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') } />; 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 ( return (
<Grid> <Grid>
<Column size={ 7 } overflow="hidden"> <Column size={ 7 } overflow="hidden">

View File

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

View File

@ -2,7 +2,7 @@ import { ChatRecordData, GetUserChatlogMessageComposer, UserChatlogEvent } from
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { SendMessageComposer } from '../../../../api'; import { SendMessageComposer } from '../../../../api';
import { DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; import { DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks'; import { UseMessageEventHook } from '../../../../hooks';
import { ChatlogView } from '../chatlog/ChatlogView'; import { ChatlogView } from '../chatlog/ChatlogView';
interface ModToolsUserChatlogViewProps interface ModToolsUserChatlogViewProps
@ -23,11 +23,8 @@ export const ModToolsUserChatlogView: FC<ModToolsUserChatlogViewProps> = props =
if(!parser || parser.data.userId !== userId) return; if(!parser || parser.data.userId !== userId) return;
BatchUpdates(() =>
{
setUsername(parser.data.username); setUsername(parser.data.username);
setUserChatlog(parser.data.roomChatlogs); setUserChatlog(parser.data.roomChatlogs);
});
}, [ userId ]); }, [ userId ]);
UseMessageEventHook(UserChatlogEvent, onModtoolUserChatlogEvent); 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 { 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 { FC, useCallback } from 'react';
import { CreateLinkEvent, CreateRoomSession, DoorStateType, GetConfiguration, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api'; 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'; import { useNavigatorContext } from './NavigatorContext';
export const NavigatorMessageHandler: FC<{}> = props => export const NavigatorMessageHandler: FC<{}> = props =>
@ -271,19 +271,14 @@ export const NavigatorMessageHandler: FC<{}> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
BatchUpdates(() =>
{
setTopLevelContexts(parser.topLevelContexts); setTopLevelContexts(parser.topLevelContexts);
setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null); setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
});
}, [ setTopLevelContexts, setTopLevelContext ]); }, [ setTopLevelContexts, setTopLevelContext ]);
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) => const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
BatchUpdates(() =>
{
setTopLevelContext(prevValue => setTopLevelContext(prevValue =>
{ {
let newValue = prevValue; let newValue = prevValue;
@ -313,7 +308,6 @@ export const NavigatorMessageHandler: FC<{}> = props =>
}); });
setSearchResult(parser.result); setSearchResult(parser.result);
});
}, [ topLevelContexts, setTopLevelContext, setSearchResult ]); }, [ topLevelContexts, setTopLevelContext, setSearchResult ]);
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) => 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 { FC, useCallback, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, DoorStateType, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api'; import { AddEventLinkTracker, DoorStateType, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; 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 { NavigatorContextProvider } from './NavigatorContext';
import { NavigatorMessageHandler } from './NavigatorMessageHandler'; import { NavigatorMessageHandler } from './NavigatorMessageHandler';
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView'; import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
@ -37,11 +37,8 @@ export const NavigatorView: FC<{}> = props =>
switch(event.type) switch(event.type)
{ {
case RoomSessionEvent.CREATED: case RoomSessionEvent.CREATED:
BatchUpdates(() =>
{
setIsVisible(false); setIsVisible(false);
setCreatorOpen(false); setCreatorOpen(false);
});
return; return;
} }
}, []); }, []);
@ -96,11 +93,8 @@ export const NavigatorView: FC<{}> = props =>
switch(parts[1]) switch(parts[1])
{ {
case 'show': { case 'show': {
BatchUpdates(() =>
{
setIsVisible(true); setIsVisible(true);
setNeedsSearch(true); setNeedsSearch(true);
});
return; return;
} }
case 'hide': case 'hide':
@ -114,11 +108,8 @@ export const NavigatorView: FC<{}> = props =>
return; return;
} }
BatchUpdates(() =>
{
setIsVisible(true); setIsVisible(true);
setNeedsSearch(true); setNeedsSearch(true);
});
return; return;
} }
case 'toggle-room-info': case 'toggle-room-info':
@ -145,11 +136,8 @@ export const NavigatorView: FC<{}> = props =>
} }
return; return;
case 'create': case 'create':
BatchUpdates(() =>
{
setIsVisible(true); setIsVisible(true);
setCreatorOpen(true); setCreatorOpen(true);
});
return; return;
case 'search': case 'search':
if(parts.length > 2) if(parts.length > 2)
@ -162,11 +150,8 @@ export const NavigatorView: FC<{}> = props =>
pendingSearch.current = { value: searchValue, code: topLevelContextCode }; pendingSearch.current = { value: searchValue, code: topLevelContextCode };
BatchUpdates(() =>
{
setIsVisible(true); setIsVisible(true);
setNeedsSearch(true); setNeedsSearch(true);
});
} }
return; return;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@ import { RoomBannedUsersComposer, RoomDataParser, RoomSettingsEvent, SaveRoomSet
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { IRoomData, LocalizeText, SendMessageComposer } from '../../../../api'; import { IRoomData, LocalizeText, SendMessageComposer } from '../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common';
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks'; import { UseMessageEventHook } from '../../../../hooks';
import { NavigatorRoomSettingsAccessTabView } from './NavigatorRoomSettingsAccessTabView'; import { NavigatorRoomSettingsAccessTabView } from './NavigatorRoomSettingsAccessTabView';
import { NavigatorRoomSettingsBasicTabView } from './NavigatorRoomSettingsBasicTabView'; import { NavigatorRoomSettingsBasicTabView } from './NavigatorRoomSettingsBasicTabView';
import { NavigatorRoomSettingsModTabView } from './NavigatorRoomSettingsModTabView'; import { NavigatorRoomSettingsModTabView } from './NavigatorRoomSettingsModTabView';
@ -64,12 +64,9 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent); UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent);
const close = () => const close = () =>
{
BatchUpdates(() =>
{ {
setRoomData(null); setRoomData(null);
setCurrentTab(TABS[0]); setCurrentTab(TABS[0]);
});
} }
const handleChange = (field: string, value: string | number | boolean) => 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 { FC, MouseEvent, useEffect, useState } from 'react';
import { Overlay, Popover } from 'react-bootstrap'; import { Overlay, Popover } from 'react-bootstrap';
import { Base, NitroCardContentView } from '../../../../common'; import { Base, NitroCardContentView } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface NavigatorSearchResultItemInfoViewProps interface NavigatorSearchResultItemInfoViewProps
{ {
@ -19,8 +18,6 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
{ {
event.stopPropagation(); event.stopPropagation();
BatchUpdates(() =>
{
let visible = false; let visible = false;
setIsVisible(prevValue => setIsVisible(prevValue =>
@ -31,7 +28,6 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
}); });
if(visible) setTarget((event.target as (EventTarget & HTMLElement))); if(visible) setTarget((event.target as (EventTarget & HTMLElement)));
})
} }
useEffect(() => useEffect(() =>

View File

@ -3,7 +3,6 @@ import { NavigatorSearchResultList } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { LocalizeText, NavigatorSearchResultViewDisplayMode } from '../../../../api'; import { LocalizeText, NavigatorSearchResultViewDisplayMode } from '../../../../api';
import { AutoGrid, AutoGridProps, Column, Flex, Grid, Text } from '../../../../common'; import { AutoGrid, AutoGridProps, Column, Flex, Grid, Text } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { NavigatorSearchResultItemView } from './NavigatorSearchResultItemView'; import { NavigatorSearchResultItemView } from './NavigatorSearchResultItemView';
export interface NavigatorSearchResultViewProps extends AutoGridProps export interface NavigatorSearchResultViewProps extends AutoGridProps
@ -43,11 +42,8 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
{ {
if(!searchResult) return; if(!searchResult) return;
BatchUpdates(() =>
{
//setIsExtended(searchResult.closed); //setIsExtended(searchResult.closed);
setDisplayMode(searchResult.mode); setDisplayMode(searchResult.mode);
});
}, [ searchResult,props ]); }, [ searchResult,props ]);
const gridHasTwoColumns = (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS); 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 React, { FC, KeyboardEvent, useEffect, useState } from 'react';
import { INavigatorSearchFilter, LocalizeText, SearchFilterOptions } from '../../../../api'; import { INavigatorSearchFilter, LocalizeText, SearchFilterOptions } from '../../../../api';
import { Button, Flex } from '../../../../common'; import { Button, Flex } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
import { useNavigatorContext } from '../../NavigatorContext'; import { useNavigatorContext } from '../../NavigatorContext';
export interface NavigatorSearchViewProps export interface NavigatorSearchViewProps
@ -39,7 +38,7 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
useEffect(() => useEffect(() =>
{ {
if(!searchResult) return null; if(!searchResult) return;
const split = searchResult.data.split(':'); const split = searchResult.data.split(':');
@ -60,11 +59,8 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
if(!filter) filter = SearchFilterOptions[0]; if(!filter) filter = SearchFilterOptions[0];
BatchUpdates(() =>
{
setSearchFilterIndex(SearchFilterOptions.findIndex(option => (option === filter))); setSearchFilterIndex(SearchFilterOptions.findIndex(option => (option === filter)));
setSearchValue(value); setSearchValue(value);
});
}, [ searchResult ]); }, [ searchResult ]);
return ( return (

View File

@ -2,7 +2,6 @@ import { NitroLogger } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { AddEventLinkTracker, GetConfiguration, NotificationUtilities, RemoveLinkEventTracker } from '../../api'; import { AddEventLinkTracker, GetConfiguration, NotificationUtilities, RemoveLinkEventTracker } from '../../api';
import { Base, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; import { Base, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
import { BatchUpdates } from '../../hooks';
const NEW_LINE_REGEX = /\n\r|\n|\r/mg; 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 splitData = text.split(NEW_LINE_REGEX);
const line = splitData.shift().split('|'); const line = splitData.shift().split('|');
BatchUpdates(() =>
{
setHeader(line[0]); setHeader(line[0]);
setDimensions(prevValue => setDimensions(prevValue =>
@ -43,7 +40,6 @@ export const NitropediaView: FC<{}> = props =>
}); });
setContent(splitData.join('')); setContent(splitData.join(''));
});
} }
catch (error) 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 }> <LayoutNotificationAlertView title={title} close={close} {...rest} type={ hasFrank ? NotificationAlertType.DEFAULT : item.alertType }>
<Flex fullHeight overflow="auto" gap={ hasFrank || (item.imageUrl && !imageFailed) ? 2 : 0 }> <Flex fullHeight overflow="auto" gap={ hasFrank || (item.imageUrl && !imageFailed) ? 2 : 0 }>
{hasFrank && !item.imageUrl && <Base className="notification-frank flex-shrink-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' : '' ]}> <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) => { (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 { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { CreateLinkEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUserActionMessage } from '../../../../api'; import { CreateLinkEvent, GetOwnRoomObject, GetUserProfile, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUserActionMessage } from '../../../../api';
import { Base, Flex } from '../../../../common'; import { Base, Flex } from '../../../../common';
import { BatchUpdates, useFriends } from '../../../../hooks'; import { useFriends } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext'; import { useRoomContext } from '../../RoomContext';
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView'; import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView'; import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
@ -207,12 +207,9 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
}, [ userData, respectsLeft, widgetHandler, close, ]); }, [ userData, respectsLeft, widgetHandler, close, ]);
useEffect(() => useEffect(() =>
{
BatchUpdates(() =>
{ {
setMode(MODE_NORMAL); setMode(MODE_NORMAL);
setRespectsLeft(userData.respectLeft); setRespectsLeft(userData.respectLeft);
});
}, [ userData ]); }, [ userData ]);
return ( return (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api'; import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { BatchUpdates, UseEventDispatcherHook } from '../../../../hooks'; import { UseEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext'; import { useRoomContext } from '../../RoomContext';
import { ChooserWidgetView } from './ChooserWidgetView'; import { ChooserWidgetView } from './ChooserWidgetView';
@ -24,12 +24,9 @@ export const UserChooserWidgetView: FC<{}> = props =>
}, [ isVisible, widgetHandler ]); }, [ isVisible, widgetHandler ]);
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) => const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
{
BatchUpdates(() =>
{ {
setItems(event.items); setItems(event.items);
setIsVisible(true); setIsVisible(true);
});
}, []); }, []);
UseEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent); UseEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
@ -51,12 +48,9 @@ export const UserChooserWidgetView: FC<{}> = props =>
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent); UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() => const close = useCallback(() =>
{
BatchUpdates(() =>
{ {
setIsVisible(false); setIsVisible(false);
setItems(null); setItems(null);
});
}, []); }, []);
if(!isVisible) return 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 { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { GetNitroInstance, GetRoomEngine, GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api'; import { GetNitroInstance, GetRoomEngine, GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
import { Base, BaseProps } from '../../../../common'; import { Base, BaseProps } from '../../../../common';
import { BatchUpdates } from '../../../../hooks';
interface ContextMenuViewProps extends BaseProps<HTMLDivElement> interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
{ {
@ -102,11 +101,8 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES; if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES;
else if(y > maxTop) y = maxTop; else if(y > maxTop) y = maxTop;
BatchUpdates(() =>
{
setCurrentDeltaY(maxStack); setCurrentDeltaY(maxStack);
setPos({ x, y }); setPos({ x, y });
});
}, [ deltaYStack, currentDeltaY, getOffset ]); }, [ deltaYStack, currentDeltaY, getOffset ]);
const update = useCallback((time: number) => const update = useCallback((time: number) =>
@ -144,12 +140,9 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
}, [ pos, opacity, style ]); }, [ pos, opacity, style ]);
useEffect(() => useEffect(() =>
{
BatchUpdates(() =>
{ {
setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE)); setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE));
setCurrentDeltaY(-1000000); setCurrentDeltaY(-1000000);
});
}, []); }, []);
useEffect(() => useEffect(() =>

View File

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

View File

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

View File

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

View File

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

View File

@ -4,5 +4,6 @@ export class DimmerFurnitureWidgetPresetItem
public id: number = 0, public id: number = 0,
public type: number = 0, public type: number = 0,
public color: 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 ReactSlider from 'react-slider';
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api'; 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 { 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 { useRoomContext } from '../../../RoomContext';
import { DimmerFurnitureWidgetPresetItem } from './DimmerFurnitureWidgetPresetItem'; 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)); for(const preset of widgetEvent.presets) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
BatchUpdates(() =>
{
setPresets(presets); setPresets(presets);
setSelectedPresetId(widgetEvent.selectedPresetId); setSelectedPresetId(widgetEvent.selectedPresetId);
setIsVisible(true); setIsVisible(true);
});
return; return;
} }
case RoomWidgetUpdateDimmerEvent.HIDE: { case RoomWidgetUpdateDimmerEvent.HIDE: {
@ -55,8 +52,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
case RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE: { case RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE: {
const widgetEvent = (event as RoomWidgetUpdateDimmerStateEvent); const widgetEvent = (event as RoomWidgetUpdateDimmerStateEvent);
BatchUpdates(() =>
{
setLastDimmerState(dimmerState); setLastDimmerState(dimmerState);
setDimmerState(widgetEvent.state); setDimmerState(widgetEvent.state);
setSelectedPresetId(widgetEvent.presetId); setSelectedPresetId(widgetEvent.presetId);
@ -66,7 +61,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
setSelectedColor(widgetEvent.color); setSelectedColor(widgetEvent.color);
setBrightness(widgetEvent.brightness); setBrightness(widgetEvent.brightness);
setSelectedBrightness(widgetEvent.brightness); setSelectedBrightness(widgetEvent.brightness);
});
return; return;
} }
@ -83,13 +77,10 @@ export const FurnitureDimmerView: FC<{}> = props =>
if(!preset) return; if(!preset) return;
BatchUpdates(() =>
{
setSelectedPresetId(preset.id); setSelectedPresetId(preset.id);
setSelectedEffectId(preset.type); setSelectedEffectId(preset.type);
setSelectedColor(preset.color); setSelectedColor(preset.color);
setSelectedBrightness(preset.light); setSelectedBrightness(preset.light);
});
}, [ presets ]); }, [ presets ]);
const close = useCallback(() => const close = useCallback(() =>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,5 +6,6 @@ export class FurnitureStickieData
public color: string, public color: string,
public text: string, public text: string,
public canModify: boolean = false, 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 ownerName: string,
public date: string, public date: string,
public message: 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 YouTube, { Options } from 'react-youtube';
import { FurnitureYoutubeDisplayWidgetHandler, LocalizeText, RoomWidgetUpdateYoutubeDisplayEvent, SendMessageComposer } from '../../../../../api'; import { FurnitureYoutubeDisplayWidgetHandler, LocalizeText, RoomWidgetUpdateYoutubeDisplayEvent, SendMessageComposer } from '../../../../../api';
import { Grid, LayoutGridItem, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../common'; import { Grid, LayoutGridItem, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../common';
import { BatchUpdates, UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks'; import { UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext'; import { useRoomContext } from '../../../RoomContext';
import { YoutubeVideoPlaybackStateEnum } from './utils/YoutubeVideoPlaybackStateEnum'; import { YoutubeVideoPlaybackStateEnum } from './utils/YoutubeVideoPlaybackStateEnum';
@ -53,13 +53,10 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return; if(objectId !== parser.furniId) return;
BatchUpdates(() =>
{
setVideoId(parser.videoId); setVideoId(parser.videoId);
setVideoStart(parser.startAtSeconds); setVideoStart(parser.startAtSeconds);
setVideoEnd(parser.endAtSeconds); setVideoEnd(parser.endAtSeconds);
setCurrentVideoState(parser.state); setCurrentVideoState(parser.state);
});
}, [ objectId ]); }, [ objectId ]);
const onPlaylists = useCallback((event: YoutubeDisplayPlaylistsEvent) => const onPlaylists = useCallback((event: YoutubeDisplayPlaylistsEvent) =>
@ -70,15 +67,12 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return; if(objectId !== parser.furniId) return;
BatchUpdates(() =>
{
setPlaylists(parser.playlists); setPlaylists(parser.playlists);
setSelectedItem(parser.selectedPlaylistId); setSelectedItem(parser.selectedPlaylistId);
setVideoId(null); setVideoId(null);
setCurrentVideoState(-1); setCurrentVideoState(-1);
setVideoEnd(null); setVideoEnd(null);
setVideoStart(null); setVideoStart(null);
});
}, [ objectId ]); }, [ objectId ]);
const onControlVideo = useCallback((event: YoutubeControlVideoMessageEvent) => const onControlVideo = useCallback((event: YoutubeControlVideoMessageEvent) =>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@ import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomE
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { CreateLinkEvent, GetRoomSession, GetSessionDataManager, GetUserProfile, LocalizeText, SendMessageComposer } from '../../api'; import { CreateLinkEvent, GetRoomSession, GetSessionDataManager, GetUserProfile, LocalizeText, SendMessageComposer } from '../../api';
import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; 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 { BadgesContainerView } from './views/BadgesContainerView';
import { FriendsContainerView } from './views/FriendsContainerView'; import { FriendsContainerView } from './views/FriendsContainerView';
import { GroupsContainerView } from './views/GroupsContainerView'; import { GroupsContainerView } from './views/GroupsContainerView';
@ -15,13 +15,10 @@ export const UserProfileView: FC<{}> = props =>
const [ userRelationships, setUserRelationships ] = useState<RelationshipStatusInfoMessageParser>(null); const [ userRelationships, setUserRelationships ] = useState<RelationshipStatusInfoMessageParser>(null);
const onClose = () => const onClose = () =>
{
BatchUpdates(() =>
{ {
setUserProfile(null); setUserProfile(null);
setUserBadges([]); setUserBadges([]);
setUserRelationships(null); setUserRelationships(null);
});
} }
const onLeaveGroup = useCallback(() => const onLeaveGroup = useCallback(() =>
@ -59,8 +56,6 @@ export const UserProfileView: FC<{}> = props =>
let isSameProfile = false; let isSameProfile = false;
BatchUpdates(() =>
{
setUserProfile(prevValue => setUserProfile(prevValue =>
{ {
if(prevValue && prevValue.id) isSameProfile = (prevValue.id === parser.id); if(prevValue && prevValue.id) isSameProfile = (prevValue.id === parser.id);
@ -73,7 +68,6 @@ export const UserProfileView: FC<{}> = props =>
setUserBadges([]); setUserBadges([]);
setUserRelationships(null); setUserRelationships(null);
} }
});
SendMessageComposer(new UserCurrentBadgesComposer(parser.id)); SendMessageComposer(new UserCurrentBadgesComposer(parser.id));
SendMessageComposer(new UserRelationshipsComposer(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 { FC, useCallback, useEffect, useState } from 'react';
import { SendMessageComposer, ToggleFavoriteGroup } from '../../../api'; import { SendMessageComposer, ToggleFavoriteGroup } from '../../../api';
import { AutoGrid, Base, Column, Flex, Grid, GridProps, LayoutBadgeImageView, LayoutGridItem } from '../../../common'; 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'; import { GroupInformationView } from '../../groups/views/GroupInformationView';
interface GroupsContainerViewProps extends GridProps interface GroupsContainerViewProps extends GridProps
@ -37,8 +37,6 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
}, [ selectedGroupId ]); }, [ selectedGroupId ]);
useEffect(() => useEffect(() =>
{
BatchUpdates(() =>
{ {
setGroupInformation(null); setGroupInformation(null);
@ -54,7 +52,6 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
return groups[0].groupId; return groups[0].groupId;
}); });
} }
});
}, [ groups ]); }, [ groups ]);
if(!groups || !groups.length) if(!groups || !groups.length)

View File

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

View File

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

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