mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-02-21 19:02:35 +01:00
Merge branch '@update/react-18' into @update/friends
This commit is contained in:
commit
6f865f05ec
86
.eslintrc.js
86
.eslintrc.js
@ -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
55
.eslintrc.json
Normal 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" ]
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
*.scss
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -14,5 +14,7 @@
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimFinalNewlines": true,
|
||||
"editor.wordWrap": "on",
|
||||
"emmet.showExpandedAbbreviation": "never"
|
||||
"emmet.showExpandedAbbreviation": "never",
|
||||
"eslint.validate": [ "javascript", "javascriptreact", "html", "typescriptreact" ],
|
||||
"eslint.workingDirectories": [ "./src" ]
|
||||
}
|
||||
|
17
package.json
17
package.json
@ -7,7 +7,8 @@
|
||||
"build": "cross-env SKIP_PREFLIGHT_CHECK=true GENERATE_SOURCEMAP=false IMAGE_INLINE_SIZE_LIMIT=100000 craco build",
|
||||
"build:prod": "npx browserslist@latest --update-db && yarn build",
|
||||
"test": "craco test",
|
||||
"eject": "react-scripts eject"
|
||||
"eject": "react-scripts eject",
|
||||
"eslint": "eslint src --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@craco/craco": "^6.3.0",
|
||||
@ -20,11 +21,11 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"emoji-toolkit": "^6.6.0",
|
||||
"node-sass": "^6.0.1",
|
||||
"react": "^17.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-bootstrap": "^2.2.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-slider": "^1.3.1",
|
||||
"react-slider": "^2.0.0",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"react-virtualized": "^9.22.3",
|
||||
"react-youtube": "^7.13.1",
|
||||
@ -41,7 +42,13 @@
|
||||
"@types/react-slider": "^1.3.1",
|
||||
"@types/react-transition-group": "^4.4.2",
|
||||
"@types/react-virtualized": "^9.21.13",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.17.0",
|
||||
"@typescript-eslint/parser": "^5.17.0",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.4.0",
|
||||
"react-error-overlay": "6.0.9"
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,8 @@ export const App: FC<{}> = props =>
|
||||
{
|
||||
const [ isReady, setIsReady ] = useState(false);
|
||||
const [ isError, setIsError ] = useState(false);
|
||||
const [message, setMessage] = useState('Getting Ready');
|
||||
const [percent, setPercent] = useState(0);
|
||||
const [ message, setMessage ] = useState('Getting Ready');
|
||||
const [ percent, setPercent ] = useState(0);
|
||||
|
||||
//@ts-ignore
|
||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||
|
@ -6,5 +6,6 @@ export class MessengerSettings
|
||||
public userFriendLimit: number = 0,
|
||||
public normalFriendLimit: number = 0,
|
||||
public extendedFriendLimit: number = 0,
|
||||
public categories: FriendCategoryData[] = []) {}
|
||||
public categories: FriendCategoryData[] = [])
|
||||
{}
|
||||
}
|
||||
|
@ -10,5 +10,6 @@ export class TradeUserData
|
||||
public itemCount: number = 0,
|
||||
public creditsCount: number = 0,
|
||||
public accepts: boolean = false,
|
||||
public canTrade: boolean = false) {}
|
||||
public canTrade: boolean = false)
|
||||
{}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ export interface IUnseenItemTracker
|
||||
dispose(): void;
|
||||
resetCategory(category: number): boolean;
|
||||
resetItems(category: number, itemIds: number[]): boolean;
|
||||
resetCategoryIfEmpty(category: number): boolean;
|
||||
isUnseen(category: number, itemId: number): boolean;
|
||||
removeUnseen(category: number, itemId: number): boolean;
|
||||
getIds(category: number): number[];
|
||||
|
@ -43,7 +43,7 @@ export class FurnitureInternalLinkHandler extends RoomWidgetHandler
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK];
|
||||
return [ RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK ];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
|
@ -49,7 +49,7 @@ export class FurnitureRoomLinkHandler extends RoomWidgetHandler
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK];
|
||||
return [ RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK ];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
|
@ -63,11 +63,11 @@ export class PollWidgetHandler extends RoomWidgetHandler
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [RoomSessionPollEvent.OFFER, RoomSessionPollEvent.ERROR, RoomSessionPollEvent.CONTENT];
|
||||
return [ RoomSessionPollEvent.OFFER, RoomSessionPollEvent.ERROR, RoomSessionPollEvent.CONTENT ];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [RoomWidgetPollMessage.ANSWER, RoomWidgetPollMessage.REJECT, RoomWidgetPollMessage.START];
|
||||
return [ RoomWidgetPollMessage.ANSWER, RoomWidgetPollMessage.REJECT, RoomWidgetPollMessage.START ];
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ export class RoomWidgetChatHandler extends RoomWidgetHandler implements IAvatarI
|
||||
text = LocalizeText('widget.chatbubble.pettreat', [ 'petname' ], [ username ]);
|
||||
break;
|
||||
case RoomSessionChatEvent.CHAT_TYPE_HAND_ITEM_RECEIVED:
|
||||
text = LocalizeText('widget.chatbubble.handitem', [ 'username', 'handitem' ], [ username, LocalizeText(('handitem' + chatEvent.extraParam))]);
|
||||
text = LocalizeText('widget.chatbubble.handitem', [ 'username', 'handitem' ], [ username, LocalizeText(('handitem' + chatEvent.extraParam)) ]);
|
||||
break;
|
||||
case RoomSessionChatEvent.CHAT_TYPE_MUTE_REMAINING: {
|
||||
const hours = ((chatEvent.extraParam > 0) ? Math.floor((chatEvent.extraParam / 3600)) : 0).toString();
|
||||
|
@ -64,7 +64,7 @@ export class WordQuizWidgetHandler extends RoomWidgetHandler
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [RoomSessionWordQuizEvent.ANSWERED, RoomSessionWordQuizEvent.FINISHED, RoomSessionWordQuizEvent.QUESTION];
|
||||
return [ RoomSessionWordQuizEvent.ANSWERED, RoomSessionWordQuizEvent.FINISHED, RoomSessionWordQuizEvent.QUESTION ];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
|
@ -4,7 +4,7 @@ export class RoomWidgetDanceMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static DANCE: string = 'RWDM_MESSAGE_DANCE';
|
||||
public static NORMAL_STYLE: number = 0;
|
||||
public static CLUB_STYLE: number[] = [2, 3, 4];
|
||||
public static CLUB_STYLE: number[] = [ 2, 3, 4 ];
|
||||
|
||||
private _style: number = 0;
|
||||
|
||||
|
@ -157,7 +157,7 @@ export class NotificationUtilities
|
||||
|
||||
public static handleHotelClosedMessage(open: number, minute: number, thrownOut: boolean): void
|
||||
{
|
||||
this.simpleAlert( LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm'], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
this.simpleAlert( LocalizeText(('opening.hours.' + (thrownOut ? 'disconnected' : 'closed')), [ 'h', 'm' ], [ this.getTimeZeroPadded(open), this.getTimeZeroPadded(minute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
|
||||
}
|
||||
|
||||
public static handleHotelMaintenanceMessage(minutesUntilMaintenance: number, duration: number): void
|
||||
|
@ -26,9 +26,9 @@ allowedColours.set('pink', 'pink');
|
||||
function encodeHTML(str: string)
|
||||
{
|
||||
return str.replace(/([\u00A0-\u9999<>&])(.|$)/g, function(full, char, next)
|
||||
{
|
||||
{
|
||||
if(char !== '&' || next !== '#')
|
||||
{
|
||||
{
|
||||
if(/[\u00A0-\u9999<>&]/.test(next))
|
||||
next = '&#' + next.charCodeAt(0) + ';';
|
||||
|
||||
|
@ -2,7 +2,6 @@ import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
|
||||
import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Base } from '..';
|
||||
import { BatchUpdates } from '../../hooks';
|
||||
import { DraggableWindowPosition } from './DraggableWindowPosition';
|
||||
|
||||
const CURRENT_WINDOWS: HTMLElement[] = [];
|
||||
@ -134,12 +133,9 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
offsetX = (document.body.offsetWidth - elementRef.current.offsetWidth) - elementRef.current.offsetLeft;
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setDelta({ x: 0, y: 0 });
|
||||
setOffset({ x: offsetX, y: offsetY });
|
||||
setIsDragging(false);
|
||||
});
|
||||
|
||||
if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY });
|
||||
}, [ dragHandler, delta, offset, uniqueKey ]);
|
||||
@ -201,11 +197,8 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
}
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setDelta({ x: 0, y: 0 });
|
||||
setOffset({ x: offsetX, y: offsetY });
|
||||
});
|
||||
|
||||
return () =>
|
||||
{
|
||||
@ -213,7 +206,7 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
|
||||
if(index >= 0) CURRENT_WINDOWS.splice(index, 1);
|
||||
}
|
||||
}, [ handleSelector, windowPosition, uniqueKey, disableDrag, bringToTop ]);
|
||||
}, [ handleSelector, windowPosition, uniqueKey, disableDrag, offsetLeft, offsetTop, bringToTop ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
|
@ -67,7 +67,8 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
||||
|
||||
setRandomValue(Math.random());
|
||||
},
|
||||
dispose: () => {},
|
||||
dispose: () =>
|
||||
{},
|
||||
disposed: false
|
||||
}, null);
|
||||
|
||||
|
@ -31,7 +31,7 @@ export const LayoutGiftTagView: FC<LayoutGiftTagViewProps> = props =>
|
||||
{ editable && (onChange !== null) &&
|
||||
<textarea className="gift-message h-100" maxLength={ 140 } value={ message } onChange={ (e) => onChange(e.target.value) } placeholder={ LocalizeText('catalog.gift_wrapping_new.message_hint') }></textarea> }
|
||||
{ userName &&
|
||||
<Text italics textEnd className="pe-1">{ LocalizeText('catalog.gift_wrapping_new.message_from', ['name'], [userName]) }</Text> }
|
||||
<Text italics textEnd className="pe-1">{ LocalizeText('catalog.gift_wrapping_new.message_from', [ 'name' ], [ userName ]) }</Text> }
|
||||
</Column>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
@ -15,7 +15,7 @@ export const LayoutNotificationAlertView: FC<LayoutNotificationAlertViewProps> =
|
||||
|
||||
const getClassNames = useMemo(() =>
|
||||
{
|
||||
const newClassNames: string[] = ['nitro-alert'];
|
||||
const newClassNames: string[] = [ 'nitro-alert' ];
|
||||
|
||||
newClassNames.push('nitro-alert-' + type);
|
||||
|
||||
|
@ -8,15 +8,11 @@ interface LayoutLimitedEditionStyledNumberViewProps
|
||||
export const LayoutLimitedEditionStyledNumberView: FC<LayoutLimitedEditionStyledNumberViewProps> = props =>
|
||||
{
|
||||
const { value = 0 } = props;
|
||||
|
||||
const numbers = value.toString().split('');
|
||||
|
||||
return (
|
||||
<>
|
||||
{ numbers.map((number, index) =>
|
||||
{
|
||||
return <i key={ index } className={ 'limited-edition-number n-' + number } />;
|
||||
})}
|
||||
{ numbers.map((number, index) => <i key={ index } className={ 'limited-edition-number n-' + number } />) }
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { AchievementCategory, AddEventLinkTracker, CloneObject, GetAchievementCategoryImageUrl, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
|
||||
import { AchievementsUIUnseenCountEvent } from '../../events';
|
||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||
import { AchievementCategoryView } from './views/AchievementCategoryView';
|
||||
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
|
||||
|
||||
@ -92,11 +92,8 @@ export const AchievementsView: FC<{}> = props =>
|
||||
existing.achievements.push(achievement);
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setAchievementCategories(categories);
|
||||
setIsInitalized(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(AchievementsEvent, onAchievementsEvent);
|
||||
|
@ -5,7 +5,7 @@ import { FigureData } from './FigureData';
|
||||
export class AvatarEditorGridPartItem implements IAvatarImageListener
|
||||
{
|
||||
private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter(0.2);
|
||||
private static THUMB_DIRECTIONS: number[] = [2, 6, 0, 4, 3, 1];
|
||||
private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ];
|
||||
private static DRAW_ORDER: string[] = [
|
||||
AvatarFigurePartType.LEFT_HAND_ITEM,
|
||||
AvatarFigurePartType.LEFT_HAND,
|
||||
|
@ -4,5 +4,6 @@ export class CameraPicture
|
||||
{
|
||||
constructor(
|
||||
public texture: NitroTexture,
|
||||
public imageUrl: string) {}
|
||||
public imageUrl: string)
|
||||
{}
|
||||
}
|
||||
|
@ -2,5 +2,6 @@ export class CameraPictureThumbnail
|
||||
{
|
||||
constructor(
|
||||
public effectName: string,
|
||||
public thumbnailUrl: string) {}
|
||||
public thumbnailUrl: string)
|
||||
{}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { InventoryEvent } from '../../../../events';
|
||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
||||
import { DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
||||
|
||||
export interface CameraWidgetCheckoutViewProps
|
||||
{
|
||||
@ -26,12 +26,9 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
|
||||
const publishDisabled = useMemo(() => GetConfiguration<boolean>('camera.publish.disabled', false), []);
|
||||
|
||||
const onCameraPurchaseOKMessageEvent = useCallback((event: CameraPurchaseOKMessageEvent) =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setPicturesBought(value => (value + 1));
|
||||
setIsWaiting(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(CameraPurchaseOKMessageEvent, onCameraPurchaseOKMessageEvent);
|
||||
@ -40,13 +37,10 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setPublishUrl(parser.extraDataId);
|
||||
setPublishCooldown(parser.secondsToWait);
|
||||
setWasPicturePublished(parser.ok);
|
||||
setIsWaiting(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(CameraPublishStatusMessageEvent, onCameraPublishStatusMessageEvent);
|
||||
|
@ -104,7 +104,7 @@ export const CalendarView: FC<CalendarViewProps> = props =>
|
||||
<Column size={ 10 }>
|
||||
<Flex justifyContent="between" alignItems="center" gap={ 1 }>
|
||||
<Column gap={ 1 }>
|
||||
<Text fontSize={ 3 }>{ LocalizeText('campaign.calendar.heading.day', ['number'], [(selectedDay + 1).toString()]) }</Text>
|
||||
<Text fontSize={ 3 }>{ LocalizeText('campaign.calendar.heading.day', [ 'number' ], [ (selectedDay + 1).toString() ]) }</Text>
|
||||
<Text>{ dayMessage(selectedDay) }</Text>
|
||||
</Column>
|
||||
<div>
|
||||
@ -121,7 +121,7 @@ export const CalendarView: FC<CalendarViewProps> = props =>
|
||||
</Flex>
|
||||
<Column center fullWidth>
|
||||
<Grid fit columnCount={ TOTAL_SHOWN_ITEMS } gap={ 1 }>
|
||||
{ [...Array(TOTAL_SHOWN_ITEMS)].map((e, i) =>
|
||||
{ [ ...Array(TOTAL_SHOWN_ITEMS) ].map((e, i) =>
|
||||
{
|
||||
const day = (index + i);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { CampaignCalendarData, CampaignCalendarDataMessageEvent, CampaignCalendarDoorOpenedMessageEvent, OpenCampaignCalendarDoorAsStaffComposer, OpenCampaignCalendarDoorComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, CalendarItem, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../hooks';
|
||||
import { UseMessageEventHook } from '../../hooks';
|
||||
import { CalendarView } from './CalendarView';
|
||||
|
||||
export const CampaignView: FC<{}> = props =>
|
||||
@ -30,8 +30,6 @@ export const CampaignView: FC<{}> = props =>
|
||||
const lastAttempt = lastOpenAttempt;
|
||||
|
||||
if(parser.doorOpened)
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCalendarData(prev =>
|
||||
{
|
||||
@ -48,11 +46,10 @@ export const CampaignView: FC<{}> = props =>
|
||||
|
||||
return copy;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setLastOpenAttempt(-1);
|
||||
}, [lastOpenAttempt]);
|
||||
}, [ lastOpenAttempt ]);
|
||||
|
||||
UseMessageEventHook(CampaignCalendarDoorOpenedMessageEvent, onCampaignCalendarDoorOpenedMessageEvent);
|
||||
|
||||
@ -71,7 +68,7 @@ export const CampaignView: FC<{}> = props =>
|
||||
{
|
||||
SendMessageComposer(new OpenCampaignCalendarDoorComposer(calendarData.campaignName, id));
|
||||
}
|
||||
}, [calendarData]);
|
||||
}, [ calendarData ]);
|
||||
|
||||
const onCalendarClose = useCallback(() =>
|
||||
{
|
||||
@ -101,7 +98,7 @@ export const CampaignView: FC<{}> = props =>
|
||||
{
|
||||
RemoveLinkEventTracker(linkTracker);
|
||||
}
|
||||
}, [onLinkReceived]);
|
||||
}, [ onLinkReceived ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -3,7 +3,7 @@ import { GuildMembershipsMessageEvent } from '@nitrots/nitro-renderer/src/nitro/
|
||||
import { FC, useCallback } from 'react';
|
||||
import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, NotificationAlertType, NotificationUtilities, ProductTypeEnum } from '../../api';
|
||||
import { CatalogGiftReceiverNotFoundEvent, CatalogNameResultEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../events';
|
||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||
import { useCatalogContext } from './CatalogContext';
|
||||
import { CatalogNode } from './common/CatalogNode';
|
||||
import { CatalogPetPalette } from './common/CatalogPetPalette';
|
||||
@ -43,11 +43,8 @@ export const CatalogMessageHandler: FC<{}> = props =>
|
||||
return catalogNode;
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setRootNode(getCatalogNode(parser.root, 0, null));
|
||||
setOffersToNodes(offers);
|
||||
});
|
||||
}, [ setRootNode, setOffersToNodes ]);
|
||||
|
||||
const onCatalogPageMessageEvent = useCallback((event: CatalogPageMessageEvent) =>
|
||||
@ -77,8 +74,6 @@ export const CatalogMessageHandler: FC<{}> = props =>
|
||||
if((currentType === CatalogType.NORMAL) || ((purchasableOffer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (purchasableOffer.pricingModel !== Offer.PRICING_MODEL_MULTI))) purchasableOffers.push(purchasableOffer);
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
if(parser.frontPageItems && parser.frontPageItems.length) setFrontPageItems(parser.frontPageItems);
|
||||
|
||||
setIsBusy(false);
|
||||
@ -87,7 +82,6 @@ export const CatalogMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
showCatalogPage(parser.pageId, parser.layoutCode, new PageLocalization(parser.localization.images.concat(), parser.localization.texts.concat()), purchasableOffers, parser.offerId, parser.acceptSeasonCurrencyAsCredits);
|
||||
}
|
||||
});
|
||||
}, [ currentType, pageId, setFrontPageItems, setIsBusy, showCatalogPage ]);
|
||||
|
||||
const onPurchaseOKMessageEvent = useCallback((event: PurchaseOKMessageEvent) =>
|
||||
|
@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetRoomEngine, LocalizeText, NotificationAlertType, NotificationUtilities, PlaySound, RemoveLinkEventTracker, SendMessageComposer, SoundNames } from '../../api';
|
||||
import { Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { CatalogPurchasedEvent } from '../../events';
|
||||
import { BatchUpdates, UseMessageEventHook, UseUiEvent } from '../../hooks';
|
||||
import { UseMessageEventHook, UseUiEvent } from '../../hooks';
|
||||
import { CatalogContextProvider } from './CatalogContext';
|
||||
import { CatalogMessageHandler } from './CatalogMessageHandler';
|
||||
import { CatalogPage } from './common/CatalogPage';
|
||||
@ -43,8 +43,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
const [ catalogOptions, setCatalogOptions ] = useState<ICatalogOptions>({});
|
||||
|
||||
const resetState = useCallback(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setPageId(-1);
|
||||
setPreviousPageId(-1);
|
||||
@ -56,7 +54,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
setSearchResult(null);
|
||||
setFrontPageItems([]);
|
||||
setIsVisible(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onCatalogPublishedMessageEvent = useCallback((event: CatalogPublishedMessageEvent) =>
|
||||
@ -119,11 +116,8 @@ export const CatalogView: FC<{}> = props =>
|
||||
{
|
||||
if(pageId < 0) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsBusy(true);
|
||||
setPageId(pageId);
|
||||
});
|
||||
|
||||
if(pageId > -1) SendMessageComposer(new GetCatalogPageComposer(pageId, offerId, currentType));
|
||||
}, [ currentType ]);
|
||||
@ -132,8 +126,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
{
|
||||
const catalogPage = (new CatalogPage(pageId, layoutCode, localization, offers, acceptSeasonCurrencyAsCredits) as ICatalogPage);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCurrentPage(catalogPage);
|
||||
setPreviousPageId(prevValue => ((pageId !== -1) ? pageId : prevValue));
|
||||
setNavigationHidden(false);
|
||||
@ -149,7 +141,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const activateNode = useCallback((targetNode: ICatalogNode, offerId: number = -1) =>
|
||||
@ -213,8 +204,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
}, [ setActiveNodes, loadCatalogPage ]);
|
||||
|
||||
const openPageById = useCallback((id: number) =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSearchResult(null);
|
||||
|
||||
@ -230,12 +219,9 @@ export const CatalogView: FC<{}> = props =>
|
||||
|
||||
if(node) activateNode(node);
|
||||
}
|
||||
});
|
||||
}, [ isVisible, rootNode, getNodeById, activateNode ]);
|
||||
|
||||
const openPageByName = useCallback((name: string) =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSearchResult(null);
|
||||
|
||||
@ -251,12 +237,9 @@ export const CatalogView: FC<{}> = props =>
|
||||
|
||||
if(node) activateNode(node);
|
||||
}
|
||||
});
|
||||
}, [ isVisible, rootNode, getNodeByName, activateNode ]);
|
||||
|
||||
const openPageByOfferId = useCallback((offerId: number) =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSearchResult(null);
|
||||
|
||||
@ -274,7 +257,6 @@ export const CatalogView: FC<{}> = props =>
|
||||
|
||||
activateNode(nodes[0], offerId);
|
||||
}
|
||||
});
|
||||
}, [ isVisible, getNodesByOfferId, activateNode ]);
|
||||
|
||||
const onCatalogPurchasedEvent = useCallback((event: CatalogPurchasedEvent) =>
|
||||
@ -415,7 +397,10 @@ export const CatalogView: FC<{}> = props =>
|
||||
<CatalogMessageHandler />
|
||||
{ isVisible &&
|
||||
<NitroCardView uniqueKey="catalog" className="nitro-catalog">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event => { setIsVisible(false); } } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
} } />
|
||||
<NitroCardTabsView>
|
||||
{ rootNode && (rootNode.children.length > 0) && rootNode.children.map(child =>
|
||||
{
|
||||
|
@ -5,5 +5,6 @@ export class CatalogPetPalette
|
||||
constructor(
|
||||
public readonly breed: string,
|
||||
public readonly palettes: SellablePetPaletteData[]
|
||||
) {}
|
||||
)
|
||||
{}
|
||||
}
|
||||
|
@ -85,21 +85,21 @@ export function GetPetAvailableColors(petIndex: number, palettes: SellablePetPal
|
||||
switch(petIndex)
|
||||
{
|
||||
case 0:
|
||||
return [[16743226], [16750435], [16764339], [0xF59500], [16498012], [16704690], [0xEDD400], [16115545], [16513201], [8694111], [11585939], [14413767], [6664599], [9553845], [12971486], [8358322], [10002885], [13292268], [10780600], [12623573], [14403561], [12418717], [14327229], [15517403], [14515069], [15764368], [16366271], [0xABABAB], [0xD4D4D4], [0xFFFFFF], [14256481], [14656129], [15848130], [14005087], [14337152], [15918540], [15118118], [15531929], [9764857], [11258085]];
|
||||
return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ];
|
||||
case 1:
|
||||
return [[16743226], [16750435], [16764339], [0xF59500], [16498012], [16704690], [0xEDD400], [16115545], [16513201], [8694111], [11585939], [14413767], [6664599], [9553845], [12971486], [8358322], [10002885], [13292268], [10780600], [12623573], [14403561], [12418717], [14327229], [15517403], [14515069], [15764368], [16366271], [0xABABAB], [0xD4D4D4], [0xFFFFFF], [14256481], [14656129], [15848130], [14005087], [14337152], [15918540], [15118118], [15531929], [9764857], [11258085]];
|
||||
return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ];
|
||||
case 2:
|
||||
return [[16579283], [15378351], [8830016], [15257125], [9340985], [8949607], [6198292], [8703620], [9889626], [8972045], [12161285], [13162269], [8620113], [12616503], [8628101], [0xD2FF00], [9764857]];
|
||||
return [ [ 16579283 ], [ 15378351 ], [ 8830016 ], [ 15257125 ], [ 9340985 ], [ 8949607 ], [ 6198292 ], [ 8703620 ], [ 9889626 ], [ 8972045 ], [ 12161285 ], [ 13162269 ], [ 8620113 ], [ 12616503 ], [ 8628101 ], [ 0xD2FF00 ], [ 9764857 ] ];
|
||||
case 3:
|
||||
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD]];
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ];
|
||||
case 4:
|
||||
return [[0xFFFFFF], [16053490], [15464440], [16248792], [15396319], [15007487]];
|
||||
return [ [ 0xFFFFFF ], [ 16053490 ], [ 15464440 ], [ 16248792 ], [ 15396319 ], [ 15007487 ] ];
|
||||
case 5:
|
||||
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD]];
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ];
|
||||
case 6:
|
||||
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD], [16767177], [16770205], [16751331]];
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ], [ 16767177 ], [ 16770205 ], [ 16751331 ] ];
|
||||
case 7:
|
||||
return [[0xCCCCCC], [0xAEAEAE], [16751331], [10149119], [16763290], [16743786]];
|
||||
return [ [ 0xCCCCCC ], [ 0xAEAEAE ], [ 16751331 ], [ 10149119 ], [ 16763290 ], [ 16743786 ] ];
|
||||
default: {
|
||||
const colors: number[][] = [];
|
||||
|
||||
|
@ -6,6 +6,6 @@ export class SearchResult
|
||||
constructor(
|
||||
public readonly searchValue: string,
|
||||
public readonly offers: IPurchasableOffer[],
|
||||
public readonly filteredNodes: ICatalogNode[]
|
||||
) {}
|
||||
public readonly filteredNodes: ICatalogNode[])
|
||||
{}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ export class SubscriptionInfo
|
||||
public readonly clubPeriods: number = 0,
|
||||
public readonly isVip: boolean = false,
|
||||
public readonly pastDays: number = 0,
|
||||
public readonly pastVipDays: number = 0) {}
|
||||
public readonly pastVipDays: number = 0)
|
||||
{}
|
||||
|
||||
public get lastUpdated(): number
|
||||
{
|
||||
|
@ -5,7 +5,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText, ProductTypeEnum, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Button, ButtonGroup, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events';
|
||||
import { BatchUpdates, UseUiEvent } from '../../../../hooks';
|
||||
import { UseUiEvent } from '../../../../hooks';
|
||||
import { useCatalogContext } from '../../CatalogContext';
|
||||
|
||||
export const CatalogGiftView: FC<{}> = props =>
|
||||
@ -28,8 +28,6 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
const { giftConfiguration = null } = catalogOptions;
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
setPageId(0);
|
||||
@ -42,7 +40,6 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
setSelectedRibbonIndex(0);
|
||||
|
||||
if(colors.length) setSelectedColorId(colors[0].id);
|
||||
});
|
||||
}, [ colors ]);
|
||||
|
||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||
@ -55,15 +52,12 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
case CatalogEvent.INIT_GIFT:
|
||||
const castedEvent = (event as CatalogInitGiftEvent);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
close();
|
||||
|
||||
setPageId(castedEvent.pageId);
|
||||
setOfferId(castedEvent.offerId);
|
||||
setExtraData(castedEvent.extraData);
|
||||
setIsVisible(true);
|
||||
});
|
||||
return;
|
||||
case CatalogEvent.GIFT_RECEIVER_NOT_FOUND:
|
||||
setReceiverNotFound(true);
|
||||
@ -144,8 +138,6 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${giftData.colors[0].toString(16)}` });
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setMaxBoxIndex(giftConfiguration.boxTypes.length - 1);
|
||||
setMaxRibbonIndex(giftConfiguration.ribbonTypes.length - 1);
|
||||
|
||||
@ -154,7 +146,6 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
setSelectedColorId(newColors[0].id);
|
||||
setColors(newColors);
|
||||
}
|
||||
});
|
||||
}, [ giftConfiguration ]);
|
||||
|
||||
if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null;
|
||||
@ -196,7 +187,7 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
<Column gap={ 1 }>
|
||||
<Text fontWeight="bold">{ LocalizeText(boxName) }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
{ LocalizeText(priceText, ['price'], [giftConfiguration.price.toString()]) }
|
||||
{ LocalizeText(priceText, [ 'price' ], [ giftConfiguration.price.toString() ]) }
|
||||
<LayoutCurrencyIcon type={ -1 } />
|
||||
</Flex>
|
||||
</Column>
|
||||
|
@ -3,7 +3,7 @@ import { RedeemVoucherMessageComposer, VoucherRedeemErrorMessageEvent, VoucherRe
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../../api';
|
||||
import { Button, Flex } from '../../../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../../../hooks';
|
||||
|
||||
export interface CatalogRedeemVoucherViewProps
|
||||
{
|
||||
@ -35,11 +35,8 @@ export const CatalogRedeemVoucherView: FC<CatalogRedeemVoucherViewProps> = props
|
||||
|
||||
NotificationUtilities.simpleAlert(message, null, null, null, LocalizeText('catalog.alert.voucherredeem.ok.title'));
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsWaiting(false);
|
||||
setVoucher('');
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(VoucherRedeemOkMessageEvent, onVoucherRedeemOkMessageEvent);
|
||||
|
@ -4,7 +4,6 @@ import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../../../../api';
|
||||
import { Button } from '../../../../../common/Button';
|
||||
import { Flex } from '../../../../../common/Flex';
|
||||
import { BatchUpdates } from '../../../../../hooks';
|
||||
import { useCatalogContext } from '../../../CatalogContext';
|
||||
import { CatalogPage } from '../../../common/CatalogPage';
|
||||
import { CatalogType } from '../../../common/CatalogType';
|
||||
@ -23,8 +22,6 @@ export const CatalogSearchView: FC<{}> = props =>
|
||||
const { currentType = null, rootNode = null, setActiveNodes = null, offersToNodes = null, searchResult = null, setSearchResult = null, setCurrentPage = null } = useCatalogContext();
|
||||
|
||||
const updateSearchValue = (value: string) =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
if(!value || !value.length)
|
||||
{
|
||||
@ -37,7 +34,6 @@ export const CatalogSearchView: FC<{}> = props =>
|
||||
setSearchValue(value);
|
||||
setNeedsProcessing(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const processSearch = useCallback((search: string) =>
|
||||
@ -96,11 +92,8 @@ export const CatalogSearchView: FC<{}> = props =>
|
||||
|
||||
FilterCatalogNode(search, foundFurniLines, rootNode, nodes);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCurrentPage((new CatalogPage(-1, 'default_3x3', new PageLocalization([], []), offers, false, 1) as ICatalogPage));
|
||||
setSearchResult(new SearchResult(search, offers, nodes.filter(node => (node.isVisible))));
|
||||
});
|
||||
}, [ offersToNodes, currentType, rootNode, setCurrentPage, setSearchResult ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -44,8 +44,8 @@ export const CatalogLayoutMarketplaceItemView: FC<MarketplaceItemViewProps> = pr
|
||||
text = hours + ' ' + LocalizeText('catalog.marketplace.offer.hours') + ' ' + text;
|
||||
}
|
||||
|
||||
return LocalizeText('catalog.marketplace.offer.time_left', ['time'], [text] );
|
||||
}, [offerData]);
|
||||
return LocalizeText('catalog.marketplace.offer.time_left', [ 'time' ], [ text ] );
|
||||
}, [ offerData ]);
|
||||
|
||||
return (
|
||||
<LayoutGridItem shrink center={ false } column={ false } alignItems="center" className="p-1">
|
||||
@ -59,8 +59,8 @@ export const CatalogLayoutMarketplaceItemView: FC<MarketplaceItemViewProps> = pr
|
||||
</> }
|
||||
{ (type === PUBLIC_OFFER) &&
|
||||
<>
|
||||
<Text>{ LocalizeText('catalog.marketplace.offer.price_public_item', ['price', 'average'], [offerData.price.toString(), offerData.averagePrice.toString() ]) }</Text>
|
||||
<Text>{ LocalizeText('catalog.marketplace.offer_count', ['count'], [offerData.offerCount.toString()]) }</Text>
|
||||
<Text>{ LocalizeText('catalog.marketplace.offer.price_public_item', [ 'price', 'average' ], [ offerData.price.toString(), offerData.averagePrice.toString() ]) }</Text>
|
||||
<Text>{ LocalizeText('catalog.marketplace.offer_count', [ 'count' ], [ offerData.offerCount.toString() ]) }</Text>
|
||||
</> }
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { CancelMarketplaceOfferMessageComposer, GetMarketplaceOwnOffersMessageComposer, MarketplaceCancelOfferResultEvent, MarketplaceOwnOffersEvent, RedeemMarketplaceOfferCreditsMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api';
|
||||
import { Button, Column, Text } from '../../../../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook, UseMountEffect } from '../../../../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../../../../hooks';
|
||||
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||
import { CatalogLayoutMarketplaceItemView, OWN_OFFER } from './CatalogLayoutMarketplaceItemView';
|
||||
import { MarketplaceOfferData } from './common/MarketplaceOfferData';
|
||||
@ -28,11 +28,8 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutProps> = prop
|
||||
return newOffer;
|
||||
});
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCreditsWaiting(parser.creditsWaiting);
|
||||
setOffers(offers);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(MarketplaceOwnOffersEvent, onMarketPlaceOwnOffersEvent);
|
||||
@ -77,10 +74,10 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutProps> = prop
|
||||
SendMessageComposer(new CancelMarketplaceOfferMessageComposer(offerData.offerId));
|
||||
};
|
||||
|
||||
UseMountEffect(() =>
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new GetMarketplaceOwnOffersMessageComposer());
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Column overflow="hidden">
|
||||
@ -91,7 +88,7 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutProps> = prop
|
||||
{ (creditsWaiting > 0) &&
|
||||
<Column center gap={ 1 } className="bg-muted rounded p-2">
|
||||
<Text>
|
||||
{ LocalizeText('catalog.marketplace.redeem.get_credits', ['count', 'credits'], [ soldOffers.length.toString(), creditsWaiting.toString() ]) }
|
||||
{ LocalizeText('catalog.marketplace.redeem.get_credits', [ 'count', 'credits' ], [ soldOffers.length.toString(), creditsWaiting.toString() ]) }
|
||||
</Text>
|
||||
<Button className="mt-1" onClick={ redeemSoldOffers }>
|
||||
{ LocalizeText('catalog.marketplace.offer.redeem') }
|
||||
|
@ -2,7 +2,7 @@ import { BuyMarketplaceOfferMessageComposer, GetMarketplaceOffersMessageComposer
|
||||
import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../../../../../api';
|
||||
import { Button, ButtonGroup, Column, Text } from '../../../../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../../../../hooks';
|
||||
import { GetCurrencyAmount } from '../../../../../purse/common/CurrencyHelper';
|
||||
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||
import { CatalogLayoutMarketplaceItemView, PUBLIC_OFFER } from './CatalogLayoutMarketplaceItemView';
|
||||
@ -11,9 +11,9 @@ import { IMarketplaceSearchOptions } from './common/IMarketplaceSearchOptions';
|
||||
import { MarketplaceOfferData } from './common/MarketplaceOfferData';
|
||||
import { MarketplaceSearchType } from './common/MarketplaceSearchType';
|
||||
|
||||
const SORT_TYPES_VALUE = [1, 2];
|
||||
const SORT_TYPES_ACTIVITY = [3, 4, 5, 6];
|
||||
const SORT_TYPES_ADVANCED = [1, 2, 3, 4, 5, 6];
|
||||
const SORT_TYPES_VALUE = [ 1, 2 ];
|
||||
const SORT_TYPES_ACTIVITY = [ 3, 4, 5, 6 ];
|
||||
const SORT_TYPES_ADVANCED = [ 1, 2, 3, 4, 5, 6 ];
|
||||
export interface CatalogLayoutMarketplacePublicItemsViewProps extends CatalogLayoutProps
|
||||
{
|
||||
|
||||
@ -44,7 +44,7 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
|
||||
return SORT_TYPES_ADVANCED;
|
||||
}
|
||||
return [];
|
||||
}, [searchType]);
|
||||
}, [ searchType ]);
|
||||
|
||||
const purchaseItem = useCallback((offerData: MarketplaceOfferData) =>
|
||||
{
|
||||
@ -75,12 +75,8 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
|
||||
latestOffers.set(entry.offerId, offerEntry);
|
||||
});
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setTotalItemsFound(parser.totalItemsFound);
|
||||
setOffers(latestOffers);
|
||||
});
|
||||
|
||||
}, []);
|
||||
|
||||
const onMarketplaceBuyOfferResultEvent = useCallback( (event: MarketplaceBuyOfferResultEvent) =>
|
||||
@ -124,7 +120,7 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
|
||||
});
|
||||
|
||||
NotificationUtilities.confirm(LocalizeText('catalog.marketplace.confirm_higher_header') +
|
||||
'\n' + LocalizeText('catalog.marketplace.confirm_price', ['price'], [parser.newPrice.toString()]), () =>
|
||||
'\n' + LocalizeText('catalog.marketplace.confirm_price', [ 'price' ], [ parser.newPrice.toString() ]), () =>
|
||||
{
|
||||
SendMessageComposer(new BuyMarketplaceOfferMessageComposer(parser.offerId));
|
||||
},
|
||||
@ -134,7 +130,7 @@ export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplac
|
||||
NotificationUtilities.simpleAlert(LocalizeText('catalog.alert.notenough.credits.description'), NotificationAlertType.DEFAULT, null, null, LocalizeText('catalog.alert.notenough.title'));
|
||||
break;
|
||||
}
|
||||
}, [lastSearch, requestOffers]);
|
||||
}, [ lastSearch, requestOffers ]);
|
||||
|
||||
UseMessageEventHook(MarketPlaceOffersEvent, onMarketPlaceOffersEvent);
|
||||
UseMessageEventHook(MarketplaceBuyOfferResultEvent, onMarketplaceBuyOfferResultEvent);
|
||||
|
@ -46,7 +46,7 @@ export const SearchFormView: FC<SearchFormViewProps> = props =>
|
||||
setSortType(sortType);
|
||||
|
||||
if(searchType === MarketplaceSearchType.BY_ACTIVITY || MarketplaceSearchType.BY_VALUE === searchType) onSearch({ minPrice: -1, maxPrice: -1, query: '', type: sortType });
|
||||
}, [onSearch, searchType, sortTypes]);
|
||||
}, [ onSearch, searchType, sortTypes ]);
|
||||
|
||||
return (
|
||||
<Column gap={ 1 }>
|
||||
|
@ -64,7 +64,10 @@ export const MarketplacePostOfferView : FC<{}> = props =>
|
||||
SendMessageComposer(new MakeOfferMessageComposer(askingPrice, item.isWallItem ? 2 : 1, item.id));
|
||||
setItem(null);
|
||||
},
|
||||
() => { setItem(null) }, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
|
||||
() =>
|
||||
{
|
||||
setItem(null)
|
||||
}, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
|
||||
}
|
||||
|
||||
return (
|
||||
@ -82,7 +85,7 @@ export const MarketplacePostOfferView : FC<{}> = props =>
|
||||
</Column>
|
||||
<Column overflow="auto">
|
||||
<Text italics>
|
||||
{ LocalizeText('inventory.marketplace.make_offer.expiration_info', ['time'], [marketplaceConfiguration.offerTime.toString()]) }
|
||||
{ LocalizeText('inventory.marketplace.make_offer.expiration_info', [ 'time' ], [ marketplaceConfiguration.offerTime.toString() ]) }
|
||||
</Text>
|
||||
<div className="input-group has-validation">
|
||||
<input className="form-control form-control-sm" type="number" min={ 0 } value={ askingPrice } onChange={ event => setAskingPrice(parseInt(event.target.value)) } placeholder={ LocalizeText('inventory.marketplace.make_offer.price_request') } />
|
||||
|
@ -4,7 +4,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { LocalizeText, SendMessageComposer } from '../../../../../../api';
|
||||
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, LayoutPetImageView, Text } from '../../../../../../common';
|
||||
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent, CatalogWidgetEvent } from '../../../../../../events';
|
||||
import { BatchUpdates, DispatchUiEvent, UseUiEvent } from '../../../../../../hooks';
|
||||
import { DispatchUiEvent, UseUiEvent } from '../../../../../../hooks';
|
||||
import { useCatalogContext } from '../../../../CatalogContext';
|
||||
import { GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../common/CatalogUtilities';
|
||||
import { CatalogAddOnBadgeWidgetView } from '../../widgets/CatalogAddOnBadgeWidgetView';
|
||||
@ -122,12 +122,9 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
|
||||
const offer = page.offers[0];
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCurrentOffer(offer);
|
||||
setPetIndex(GetPetIndexFromLocalization(offer.localizationId));
|
||||
setColorsShowing(false);
|
||||
});
|
||||
}, [ page, setCurrentOffer ]);
|
||||
|
||||
useEffect(() =>
|
||||
@ -153,21 +150,15 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
palettes.push(palette);
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSelectedPaletteIndex((palettes.length ? 0 : -1));
|
||||
setSellablePalettes(palettes);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSelectedPaletteIndex(-1);
|
||||
setSellablePalettes([]);
|
||||
});
|
||||
|
||||
SendMessageComposer(new GetSellablePetPalettesComposer(productData.type));
|
||||
}, [ currentOffer, petPalettes ]);
|
||||
@ -178,11 +169,8 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
|
||||
const colors = GetPetAvailableColors(petIndex, sellablePalettes);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setSelectedColorIndex((colors.length ? 0 : -1));
|
||||
setSellableColors(colors);
|
||||
});
|
||||
}, [ petIndex, sellablePalettes ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -21,7 +21,7 @@ export const VipGiftItem : FC<VipGiftItemViewProps> = props =>
|
||||
const productData = offer.products[0];
|
||||
|
||||
return ProductImageUtility.getProductImageUrl(productData.productType, productData.furniClassId, productData.extraParam);
|
||||
}, [offer]);
|
||||
}, [ offer ]);
|
||||
|
||||
const getItemTitle = useCallback(() =>
|
||||
{
|
||||
@ -32,7 +32,7 @@ export const VipGiftItem : FC<VipGiftItemViewProps> = props =>
|
||||
const localizationKey = ProductImageUtility.getProductCategory(productData.productType, productData.furniClassId) === 2 ? 'wallItem.name.' + productData.furniClassId : 'roomItem.name.' + productData.furniClassId;
|
||||
|
||||
return LocalizeText(localizationKey);
|
||||
}, [offer]);
|
||||
}, [ offer ]);
|
||||
|
||||
const getItemDesc = useCallback( () =>
|
||||
{
|
||||
@ -43,7 +43,7 @@ export const VipGiftItem : FC<VipGiftItemViewProps> = props =>
|
||||
const localizationKey = ProductImageUtility.getProductCategory(productData.productType, productData.furniClassId) === 2 ? 'wallItem.desc.' + productData.furniClassId : 'roomItem.desc.' + productData.furniClassId ;
|
||||
|
||||
return LocalizeText(localizationKey);
|
||||
}, [offer]);
|
||||
}, [ offer ]);
|
||||
|
||||
return (
|
||||
<LayoutGridItem center={ false } column={ false } alignItems="center" className="p-1">
|
||||
|
@ -14,9 +14,10 @@ interface CatalogBadgeSelectorWidgetViewProps extends AutoGridProps
|
||||
export const CatalogBadgeSelectorWidgetView: FC<CatalogBadgeSelectorWidgetViewProps> = props =>
|
||||
{
|
||||
const { columnCount = 5, ...rest } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ currentBadgeCode, setCurrentBadgeCode ] = useState<string>(null);
|
||||
const { currentOffer = null, setPurchaseOptions = null } = useCatalogContext();
|
||||
const { badgeCodes = [] } = useInventoryBadges();
|
||||
const { badgeCodes = [], activate = null, deactivate = null } = useInventoryBadges();
|
||||
|
||||
const previewStuffData = useMemo(() =>
|
||||
{
|
||||
@ -45,6 +46,22 @@ export const CatalogBadgeSelectorWidgetView: FC<CatalogBadgeSelectorWidgetViewPr
|
||||
});
|
||||
}, [ currentOffer, previewStuffData, setPurchaseOptions ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
const id = activate();
|
||||
|
||||
return () => deactivate(id);
|
||||
}, [ isVisible, activate, deactivate ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AutoGrid columnCount={ columnCount } { ...rest }>
|
||||
{ badgeCodes && (badgeCodes.length > 0) && badgeCodes.map((badgeCode, index) =>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, ProductTypeEnum } from '../../../../../api';
|
||||
import { AutoGrid, AutoGridProps, Button, ButtonGroup } from '../../../../../common';
|
||||
import { BatchUpdates } from '../../../../../hooks';
|
||||
import { useCatalogContext } from '../../../CatalogContext';
|
||||
import { IPurchasableOffer } from '../../../common/IPurchasableOffer';
|
||||
import { Offer } from '../../../common/Offer';
|
||||
@ -52,12 +51,9 @@ export const CatalogSpacesWidgetView: FC<CatalogSpacesWidgetViewProps> = props =
|
||||
}
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setGroupedOffers(groupedOffers);
|
||||
setSelectedGroupIndex(0);
|
||||
setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]);
|
||||
});
|
||||
}, [ currentPage ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -15,7 +15,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
const { chatHistoryState = null, roomHistoryState = null } = useChatHistoryContext();
|
||||
|
||||
const [needsRoomInsert, setNeedsRoomInsert ] = useState(false);
|
||||
const [ needsRoomInsert, setNeedsRoomInsert ] = useState(false);
|
||||
|
||||
const addChatEntry = useCallback((entry: IChatEntry) =>
|
||||
{
|
||||
@ -32,7 +32,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
|
||||
//dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED));
|
||||
|
||||
}, [chatHistoryState]);
|
||||
}, [ chatHistoryState ]);
|
||||
|
||||
const addRoomHistoryEntry = useCallback((entry: IRoomHistoryEntry) =>
|
||||
{
|
||||
@ -45,7 +45,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
}
|
||||
|
||||
roomHistoryState.notify();
|
||||
}, [roomHistoryState]);
|
||||
}, [ roomHistoryState ]);
|
||||
|
||||
const onChatEvent = useCallback((event: RoomSessionChatEvent) =>
|
||||
{
|
||||
@ -62,7 +62,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
const entry: IChatEntry = { id: -1, entityId: userData.webID, name: userData.name, look: userData.figure, entityType: userData.type, message: event.message, timestamp: timeString, type: ChatEntryType.TYPE_CHAT, roomId: roomSession.roomId };
|
||||
|
||||
addChatEntry(entry);
|
||||
}, [addChatEntry]);
|
||||
}, [ addChatEntry ]);
|
||||
|
||||
UseRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onChatEvent);
|
||||
|
||||
@ -104,7 +104,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
|
||||
setNeedsRoomInsert(false);
|
||||
}
|
||||
}, [addChatEntry, addRoomHistoryEntry, needsRoomInsert]);
|
||||
}, [ addChatEntry, addRoomHistoryEntry, needsRoomInsert ]);
|
||||
|
||||
UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);
|
||||
|
||||
|
@ -3,7 +3,6 @@ import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized';
|
||||
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
|
||||
import { BatchUpdates } from '../../hooks';
|
||||
import { ChatHistoryContextProvider } from './ChatHistoryContext';
|
||||
import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler';
|
||||
import { ChatEntryType } from './common/ChatEntryType';
|
||||
@ -91,11 +90,8 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1));
|
||||
roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1));
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setChatHistoryState(chatState);
|
||||
setRoomHistoryState(roomState);
|
||||
});
|
||||
|
||||
return () =>
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ export const FloorplanEditorView: FC<{}> = props =>
|
||||
const [ originalFloorplanSettings, setOriginalFloorplanSettings ] = useState<IFloorplanSettings>({
|
||||
tilemap: '',
|
||||
reservedTiles: [],
|
||||
entryPoint: [0, 0],
|
||||
entryPoint: [ 0, 0 ],
|
||||
entryPointDir: 2,
|
||||
wallHeight: -1,
|
||||
thicknessWall: 1,
|
||||
|
@ -151,7 +151,7 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
{
|
||||
if(this._isHolding)
|
||||
{
|
||||
const [realX, realY] = getTileFromScreenPosition(tileStartX, tileStartY);
|
||||
const [ realX, realY ] = getTileFromScreenPosition(tileStartX, tileStartY);
|
||||
|
||||
if(isClick)
|
||||
{
|
||||
@ -246,7 +246,7 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
if(tile.isBlocked) assetName = FloorplanEditor.TILE_BLOCKED;
|
||||
|
||||
//if((tile.height === 'x') || tile.height === 'X') continue;
|
||||
const [positionX, positionY] = getScreenPositionForTile(x, y);
|
||||
const [ positionX, positionY ] = getScreenPositionForTile(x, y);
|
||||
|
||||
this._tilemapRenderer.tile(this._assetCollection.getTexture(`floor_editor_${ assetName }`), positionX, positionY);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ export const getScreenPositionForTile = (x: number, y: number): [number , number
|
||||
|
||||
positionX = positionX + 1024; // center the map in the canvas
|
||||
|
||||
return [positionX, positionY];
|
||||
return [ positionX, positionY ];
|
||||
}
|
||||
|
||||
export const getTileFromScreenPosition = (x: number, y: number): [number, number] =>
|
||||
@ -17,7 +17,7 @@ export const getTileFromScreenPosition = (x: number, y: number): [number, number
|
||||
const realX = ((translatedX /(TILE_SIZE / 2)) + (y / (TILE_SIZE / 4))) / 2;
|
||||
const realY = ((y /(TILE_SIZE / 4)) - (translatedX / (TILE_SIZE / 2))) / 2;
|
||||
|
||||
return [realX, realY];
|
||||
return [ realX, realY ];
|
||||
}
|
||||
|
||||
export const convertNumbersForSaving = (value: number): number =>
|
||||
|
@ -2,7 +2,7 @@ import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } fr
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Column, Flex, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, Text, UserProfileIconView } from '../../../../common';
|
||||
import { BatchUpdates, useFriends, UseMessageEventHook } from '../../../../hooks';
|
||||
import { useFriends, UseMessageEventHook } from '../../../../hooks';
|
||||
|
||||
interface FriendsSearchViewProps extends NitroCardAccordionSetViewProps
|
||||
{
|
||||
@ -21,11 +21,8 @@ export const FriendsSearchView: FC<FriendsSearchViewProps> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setFriendResults(parser.friends);
|
||||
setOtherResults(parser.others);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(HabboSearchResultEvent, onHabboSearchResultEvent);
|
||||
|
@ -35,7 +35,7 @@ export const FriendsListView: FC<{}> = props =>
|
||||
}
|
||||
|
||||
return LocalizeText('friendlist.removefriendconfirm.userlist', [ 'user_names' ], [ userNames.join(', ') ]);
|
||||
}, [offlineFriends, onlineFriends, selectedFriendsIds]);
|
||||
}, [ offlineFriends, onlineFriends, selectedFriendsIds ]);
|
||||
|
||||
const selectFriend = useCallback((userId: number) =>
|
||||
{
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
@ -3,7 +3,7 @@ import { FollowFriendMessageComposer, ILinkEventTracker } from '@nitrots/nitro-r
|
||||
import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { BatchUpdates, useMessenger } from '../../../../hooks';
|
||||
import { useMessenger } from '../../../../hooks';
|
||||
import { FriendsMessengerThreadView } from './FriendsMessengerThreadView';
|
||||
|
||||
export const FriendsMessengerView: FC<{}> = props =>
|
||||
@ -54,11 +54,8 @@ export const FriendsMessengerView: FC<{}> = props =>
|
||||
|
||||
if(!thread) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setActiveThread(thread);
|
||||
setIsVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2,7 +2,7 @@ import { GroupBuyComposer, GroupBuyDataComposer, GroupBuyDataEvent } from '@nitr
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { HasHabboClub, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../hooks';
|
||||
import { IGroupData } from '../common/IGroupData';
|
||||
import { GroupTabBadgeView } from './tabs/GroupTabBadgeView';
|
||||
import { GroupTabColorsView } from './tabs/GroupTabColorsView';
|
||||
@ -94,18 +94,13 @@ export const GroupCreatorView: FC<GroupCreatorViewProps> = props =>
|
||||
|
||||
parser.availableRooms.forEach((name, id) => rooms.push({ id, name }));
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setAvailableRooms(rooms);
|
||||
setPurchaseCost(parser.groupCost);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(GroupBuyDataEvent, onGroupBuyDataEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setCurrentTab(1);
|
||||
|
||||
@ -119,7 +114,6 @@ export const GroupCreatorView: FC<GroupCreatorViewProps> = props =>
|
||||
groupColors: null,
|
||||
groupBadgeParts: null
|
||||
});
|
||||
});
|
||||
|
||||
SendMessageComposer(new GroupBuyDataComposer());
|
||||
}, [ setGroupData ]);
|
||||
|
@ -126,7 +126,7 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
|
||||
<i className="icon icon-group-decorate" title={ LocalizeText('group.memberscandecorate') } /> }
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Text small>{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }</Text>
|
||||
<Text small>{ LocalizeText('group.created', [ 'date', 'owner' ], [ groupInformation.createdAt, groupInformation.ownerName ]) }</Text>
|
||||
</Column>
|
||||
<Text small overflow="auto" className="group-description">{ groupInformation.description }</Text>
|
||||
</Column>
|
||||
|
@ -3,7 +3,7 @@ import { GroupAdminGiveComposer, GroupAdminTakeComposer, GroupConfirmMemberRemov
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetSessionDataManager, GetUserProfile, LocalizeText, NotificationUtilities, RemoveLinkEventTracker, SendMessageComposer } from '../../../api';
|
||||
import { Base, Button, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../hooks';
|
||||
|
||||
export const GroupMembersView: FC<{}> = props =>
|
||||
{
|
||||
@ -76,12 +76,9 @@ export const GroupMembersView: FC<{}> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setMembersData(parser);
|
||||
setLevelId(parser.level);
|
||||
setTotalPages(Math.ceil(parser.totalMembersCount / parser.pageSize));
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(GroupMembersEvent, onGroupMembersEvent);
|
||||
@ -111,11 +108,8 @@ export const GroupMembersView: FC<{}> = props =>
|
||||
const groupId = (parseInt(parts[1]) || -1);
|
||||
const levelId = (parseInt(parts[2]) || 3);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setGroupId(groupId);
|
||||
setLevelId(levelId);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
@ -146,21 +140,18 @@ export const GroupMembersView: FC<{}> = props =>
|
||||
{
|
||||
if(groupId === -1) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setLevelId(-1);
|
||||
setMembersData(null);
|
||||
setTotalPages(0);
|
||||
setSearchQuery('');
|
||||
setRemovingMemberName(null);
|
||||
})
|
||||
}, [ groupId ]);
|
||||
|
||||
if((groupId === -1) || !membersData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-group-members" theme="primary-slim">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('group.members.title', ['groupName'], [ membersData ? membersData.groupTitle : '' ]) } onCloseClick={ event => setGroupId(-1) } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText('group.members.title', [ 'groupName' ], [ membersData ? membersData.groupTitle : '' ]) } onCloseClick={ event => setGroupId(-1) } />
|
||||
<NitroCardContentView overflow="hidden">
|
||||
<Flex gap={ 2 }>
|
||||
<Flex center className="group-badge">
|
||||
@ -211,7 +202,7 @@ export const GroupMembersView: FC<{}> = props =>
|
||||
<FontAwesomeIcon icon="chevron-left" />
|
||||
</Button>
|
||||
<Text small>
|
||||
{ LocalizeText('group.members.pageinfo', ['amount', 'page', 'totalPages'], [membersData.totalMembersCount.toString(), (membersData.pageIndex + 1).toString(), totalPages.toString()]) }
|
||||
{ LocalizeText('group.members.pageinfo', [ 'amount', 'page', 'totalPages' ], [ membersData.totalMembersCount.toString(), (membersData.pageIndex + 1).toString(), totalPages.toString() ]) }
|
||||
</Text>
|
||||
<Button disabled={ (membersData.pageIndex === (totalPages - 1)) } onClick={ event => setPageId(prevValue => (prevValue + 1)) }>
|
||||
<FontAwesomeIcon icon="chevron-right" />
|
||||
|
@ -2,7 +2,6 @@ import { GroupDeleteComposer, GroupSaveInformationComposer } from '@nitrots/nitr
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
|
||||
interface GroupTabIdentityViewProps
|
||||
@ -64,13 +63,10 @@ export const GroupTabIdentityView: FC<GroupTabIdentityViewProps> = props =>
|
||||
}, [ groupData, groupName, groupDescription, groupHomeroomId, setGroupData ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setGroupName(groupData.groupName || '');
|
||||
setGroupDescription(groupData.groupDescription || '');
|
||||
setGroupHomeroomId(groupData.groupHomeroomId);
|
||||
});
|
||||
}, [ groupData ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -3,7 +3,6 @@ import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from '
|
||||
import { SendMessageComposer } from '../../../../api';
|
||||
import { LocalizeText } from '../../../../api/utils/LocalizeText';
|
||||
import { Column, Flex, HorizontalRule, Text } from '../../../../common';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
|
||||
const STATES: string[] = [ 'regular', 'exclusive', 'private' ];
|
||||
@ -48,12 +47,9 @@ export const GroupTabSettingsView: FC<GroupTabSettingsViewProps> = props =>
|
||||
}, [ groupData, groupState, groupDecorate, setGroupData ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setGroupState(groupData.groupState);
|
||||
setGroupDecorate(groupData.groupCanMembersDecorate);
|
||||
});
|
||||
}, [ groupData ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -55,7 +55,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
setNoCloseButton(true);
|
||||
break;
|
||||
case GuideSessionState.GUIDE_ONGOING:
|
||||
setHeaderText(LocalizeText('guide.help.request.guide.ongoing.title', ['name'], [replacement]));
|
||||
setHeaderText(LocalizeText('guide.help.request.guide.ongoing.title', [ 'name' ], [ replacement ]));
|
||||
setNoCloseButton(true);
|
||||
break;
|
||||
case GuideSessionState.USER_CREATE:
|
||||
@ -67,7 +67,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
setNoCloseButton(true);
|
||||
break;
|
||||
case GuideSessionState.USER_ONGOING:
|
||||
setHeaderText(LocalizeText('guide.help.request.user.ongoing.title', ['name'], [replacement]));
|
||||
setHeaderText(LocalizeText('guide.help.request.user.ongoing.title', [ 'name' ], [ replacement ]));
|
||||
setNoCloseButton(true);
|
||||
break;
|
||||
case GuideSessionState.USER_FEEDBACK:
|
||||
@ -183,7 +183,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const messageGroups = [...ongoingMessageGroups];
|
||||
const messageGroups = [ ...ongoingMessageGroups ];
|
||||
|
||||
let lastGroup = messageGroups[messageGroups.length - 1];
|
||||
|
||||
@ -203,7 +203,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const messageGroups = [...ongoingMessageGroups];
|
||||
const messageGroups = [ ...ongoingMessageGroups ];
|
||||
|
||||
let lastGroup = messageGroups[messageGroups.length - 1];
|
||||
|
||||
@ -217,7 +217,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
|
||||
lastGroup.addChat(new GuideToolMessage(parser.roomName, parser.roomId));
|
||||
setOngoingMessageGroups(messageGroups);
|
||||
}, [isOnDuty, ongoingMessageGroups, ongoingUserId]);
|
||||
}, [ isOnDuty, ongoingMessageGroups, ongoingUserId ]);
|
||||
|
||||
UseMessageEventHook(GuideSessionInvitedToGuideRoomMessageEvent, onGuideSessionInvitedToGuideRoomMessageEvent);
|
||||
|
||||
@ -299,7 +299,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
case 'toggle_duty':
|
||||
if(!isHandlingBullyReports && !isHandlingGuideRequests && !isHandlingHelpRequests)
|
||||
{
|
||||
DispatchUiEvent(new NotificationAlertEvent([LocalizeText('guide.help.guide.tool.noqueueselected.message')], null, null, null, LocalizeText('guide.help.guide.tool.noqueueselected.caption'), null));
|
||||
DispatchUiEvent(new NotificationAlertEvent([ LocalizeText('guide.help.guide.tool.noqueueselected.message') ], null, null, null, LocalizeText('guide.help.guide.tool.noqueueselected.caption'), null));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ export const GuideToolView: FC<{}> = props =>
|
||||
window.open(url);
|
||||
return;
|
||||
}
|
||||
}, [isHandlingBullyReports, isHandlingGuideRequests, isHandlingHelpRequests]);
|
||||
}, [ isHandlingBullyReports, isHandlingGuideRequests, isHandlingHelpRequests ]);
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
|
@ -85,7 +85,7 @@ export const GuideToolOngoingView: FC<GuideToolOngoingViewProps> = props =>
|
||||
{ messageGroups.map((group, index) =>
|
||||
{
|
||||
return (
|
||||
<Flex fullWidth justifyContent={ isOwnChat(group.userId) ? 'end' : 'start' } gap={ 2 }>
|
||||
<Flex key={ index } fullWidth justifyContent={ isOwnChat(group.userId) ? 'end' : 'start' } gap={ 2 }>
|
||||
<Base shrink className="message-avatar">
|
||||
{ (!isOwnChat(group.userId)) &&
|
||||
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } /> }
|
||||
|
@ -90,7 +90,7 @@ export const HcCenterView: FC<{}> = props =>
|
||||
setIsVisible(!isVisible);
|
||||
break;
|
||||
}
|
||||
}, [isVisible]);
|
||||
}, [ isVisible ]);
|
||||
|
||||
UseUiEvent(HcCenterEvent.TOGGLE_HC_CENTER, onHcCenterEvent);
|
||||
|
||||
@ -169,7 +169,7 @@ export const HcCenterView: FC<{}> = props =>
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived]);
|
||||
}, [ linkReceived ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -201,13 +201,16 @@ export const HcCenterView: FC<{}> = props =>
|
||||
<Popover id="popover-basic">
|
||||
<Popover.Body className="text-black py-2 px-3">
|
||||
<h5>{LocalizeText('hccenter.breakdown.title')}</h5>
|
||||
<div>{LocalizeText('hccenter.breakdown.creditsspent', ['credits'], [kickbackData.totalCreditsSpent.toString()])}</div>
|
||||
<div>{LocalizeText('hccenter.breakdown.paydayfactor.percent', ['percent'], [(kickbackData.kickbackPercentage * 100).toString()])}</div>
|
||||
<div>{LocalizeText('hccenter.breakdown.streakbonus', ['credits'], [kickbackData.creditRewardForStreakBonus.toString()])}</div>
|
||||
<div>{LocalizeText('hccenter.breakdown.creditsspent', [ 'credits' ], [ kickbackData.totalCreditsSpent.toString() ])}</div>
|
||||
<div>{LocalizeText('hccenter.breakdown.paydayfactor.percent', [ 'percent' ], [ (kickbackData.kickbackPercentage * 100).toString() ])}</div>
|
||||
<div>{LocalizeText('hccenter.breakdown.streakbonus', [ 'credits' ], [ kickbackData.creditRewardForStreakBonus.toString() ])}</div>
|
||||
<hr className="w-100 text-black my-1" />
|
||||
<div>{LocalizeText('hccenter.breakdown.total', ['credits', 'actual'], [getHcPaydayAmount(),
|
||||
((((kickbackData.kickbackPercentage * kickbackData.totalCreditsSpent) + kickbackData.creditRewardForStreakBonus) * 100) / 100).toString()])}</div>
|
||||
<div className="btn btn-link text-primary p-0" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{
|
||||
<div>{LocalizeText('hccenter.breakdown.total', [ 'credits', 'actual' ], [ getHcPaydayAmount(),
|
||||
((((kickbackData.kickbackPercentage * kickbackData.totalCreditsSpent) + kickbackData.creditRewardForStreakBonus) * 100) / 100).toString() ])}</div>
|
||||
<div className="btn btn-link text-primary p-0" onClick={() =>
|
||||
{
|
||||
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage'])
|
||||
}}>{
|
||||
LocalizeText('hccenter.special.infolink')}
|
||||
</div>
|
||||
</Popover.Body>
|
||||
@ -221,7 +224,10 @@ export const HcCenterView: FC<{}> = props =>
|
||||
<Column gap={ 1 }>
|
||||
<div className="hc-logo" />
|
||||
<Flex>
|
||||
<Button variant="success" onClick={ event => { CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.buy_hc']) } }>
|
||||
<Button variant="success" onClick={ event =>
|
||||
{
|
||||
CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.buy_hc'])
|
||||
} }>
|
||||
{ LocalizeText((clubStatus === ClubStatus.ACTIVE) ? 'hccenter.btn.extend' : 'hccenter.btn.buy') }
|
||||
</Button>
|
||||
</Flex>
|
||||
@ -243,7 +249,10 @@ export const HcCenterView: FC<{}> = props =>
|
||||
<Column className="rounded-start bg-primary p-2 payday-special mb-1">
|
||||
<h4 className="mb-1">{LocalizeText('hccenter.special.title')}</h4>
|
||||
<div>{LocalizeText('hccenter.special.info')}</div>
|
||||
<div className="btn btn-link text-white p-0 mt-auto align-self-baseline" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage']) }}>{LocalizeText('hccenter.special.infolink')}</div>
|
||||
<div className="btn btn-link text-white p-0 mt-auto align-self-baseline" onClick={() =>
|
||||
{
|
||||
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['payday.habbopage'])
|
||||
}}>{LocalizeText('hccenter.special.infolink')}</div>
|
||||
</Column>
|
||||
<div className="payday flex-shrink-0 p-2">
|
||||
<h5 className="mb-2 ms-2">{LocalizeText('hccenter.special.time.title')}</h5>
|
||||
@ -271,16 +280,22 @@ export const HcCenterView: FC<{}> = props =>
|
||||
<div className="rounded bg-success p-2 d-flex flex-row mb-0">
|
||||
<div>
|
||||
<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>
|
||||
<button className="btn btn-primary btn-lg align-self-center ms-auto" onClick={() => { CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.hc_gifts']) }}>{LocalizeText(clubStatus === ClubStatus.ACTIVE ? 'hccenter.btn.gifts.redeem' : 'hccenter.btn.gifts.view')}</button>
|
||||
<button className="btn btn-primary btn-lg align-self-center ms-auto" onClick={() =>
|
||||
{
|
||||
CreateLinkEvent('catalog/open/' + GetConfiguration('catalog.links')['hc.hc_gifts'])
|
||||
}}>{LocalizeText(clubStatus === ClubStatus.ACTIVE ? 'hccenter.btn.gifts.redeem' : 'hccenter.btn.gifts.view')}</button>
|
||||
</div>
|
||||
}
|
||||
{GetConfiguration('hc.center')['benefits.info'] &&
|
||||
<div className="benefits text-black py-2">
|
||||
<h5 className="mb-1 text-primary">{LocalizeText('hccenter.general.title')}</h5>
|
||||
<div className="mb-2" dangerouslySetInnerHTML={{ __html: LocalizeText('hccenter.general.info') }} />
|
||||
<button className="btn btn-link p-0 text-primary" onClick={() => { CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage']) }}>{LocalizeText('hccenter.general.infolink')}</button>
|
||||
<button className="btn btn-link p-0 text-primary" onClick={() =>
|
||||
{
|
||||
CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage'])
|
||||
}}>{LocalizeText('hccenter.general.infolink')}</button>
|
||||
</div>
|
||||
}
|
||||
</NitroCardContentView>
|
||||
|
@ -2,7 +2,7 @@
|
||||
export class BadgeResolver
|
||||
{
|
||||
public static default_badge: string = 'HC1';
|
||||
public static badges: string[] = ['ACH_VipHC1', 'ACH_VipHC2', 'ACH_VipHC3', 'ACH_VipHC4', 'ACH_VipHC5', 'HC1', 'HC2', 'HC3', 'HC4', 'HC5'];
|
||||
public static badges: string[] = [ 'ACH_VipHC1', 'ACH_VipHC2', 'ACH_VipHC3', 'ACH_VipHC4', 'ACH_VipHC5', 'HC1', 'HC2', 'HC3', 'HC4', 'HC5' ];
|
||||
|
||||
|
||||
public static getClubBadge(k: string[]): string
|
||||
|
@ -104,7 +104,7 @@ export const HelpView: FC<{}> = props =>
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [helpReportState.currentStep]);
|
||||
}, [ helpReportState.currentStep ]);
|
||||
|
||||
return (
|
||||
<HelpContextProvider value={ { helpReportState, setHelpReportState } }>
|
||||
|
@ -15,7 +15,7 @@ export const HelpIndexView: FC<{}> = props =>
|
||||
const reportState = Object.assign({}, helpReportState );
|
||||
reportState.currentStep = 1;
|
||||
setHelpReportState(reportState);
|
||||
},[helpReportState, setHelpReportState]);
|
||||
},[ helpReportState, setHelpReportState ]);
|
||||
|
||||
const onRequestMySanctionStatusClick = useCallback(() =>
|
||||
{
|
||||
|
@ -39,11 +39,11 @@ export const SanctionSatusView:FC<{}> = props =>
|
||||
if(length > 24)
|
||||
{
|
||||
localizationName = (localizationName + '.days');
|
||||
return LocalizeText(localizationName, ['days'], [(length / 24).toString()]);
|
||||
return LocalizeText(localizationName, [ 'days' ], [ (length / 24).toString() ]);
|
||||
}
|
||||
}
|
||||
|
||||
return LocalizeText(localizationName, ['hours'], [length.toString()]);
|
||||
return LocalizeText(localizationName, [ 'hours' ], [ length.toString() ]);
|
||||
}, []);
|
||||
|
||||
if(!sanctionInfo) return null;
|
||||
|
@ -9,7 +9,7 @@ export const NameChangeInitView:FC<NameChangeLayoutViewProps> = props =>
|
||||
return (
|
||||
<div className="d-flex flex-column gap-4 h-100">
|
||||
<div className="bg-muted rounded p-2 text-center">{ LocalizeText('tutorial.name_change.info.main') }</div>
|
||||
<div className="fw-bold d-flex align-items-center justify-content-center h-100 w-100">{ LocalizeText('tutorial.name_change.current', ['name'], [GetSessionDataManager().userName]) }</div>
|
||||
<div className="fw-bold d-flex align-items-center justify-content-center h-100 w-100">{ LocalizeText('tutorial.name_change.current', [ 'name' ], [ GetSessionDataManager().userName ]) }</div>
|
||||
<div className="d-flex gap-2">
|
||||
<button className="btn btn-success w-100" onClick={ () => onAction('start') }>{ LocalizeText('tutorial.name_change.change') }</button>
|
||||
<button className="btn btn-primary w-100" onClick={ () => onAction('confirmation', GetSessionDataManager().userName) }>{ LocalizeText('tutorial.name_change.keep') }</button>
|
||||
|
@ -83,8 +83,8 @@ export const NameChangeInputView:FC<NameChangeLayoutViewProps> = props =>
|
||||
<button className="btn btn-primary" disabled={ newUsername === '' || isChecking } onClick={ check }>{ LocalizeText('tutorial.name_change.check') }</button>
|
||||
</div>
|
||||
{ !errorCode && !canProceed && <div className="bg-muted rounded p-2 text-center">{ LocalizeText('help.tutorial.name.info') }</div> }
|
||||
{ errorCode && <div className="bg-danger rounded p-2 text-center text-white">{ LocalizeText(`help.tutorial.name.${errorCode}`, ['name'], [newUsername]) }</div> }
|
||||
{ canProceed && <div className="bg-success rounded p-2 text-center text-white">{ LocalizeText('help.tutorial.name.available', ['name'], [newUsername]) }</div> }
|
||||
{ errorCode && <div className="bg-danger rounded p-2 text-center text-white">{ LocalizeText(`help.tutorial.name.${errorCode}`, [ 'name' ], [ newUsername ]) }</div> }
|
||||
{ canProceed && <div className="bg-success rounded p-2 text-center text-white">{ LocalizeText('help.tutorial.name.available', [ 'name' ], [ newUsername ]) }</div> }
|
||||
{ suggestions && <div className="d-flex flex-column gap-2">
|
||||
{
|
||||
suggestions.map((suggestion, i) =>
|
||||
|
@ -51,7 +51,7 @@ export const NameChangeView:FC<{}> = props =>
|
||||
case INPUT: return 'tutorial.name_change.title.select';
|
||||
case CONFIRMATION: return 'tutorial.name_change.title.confirm';
|
||||
}
|
||||
}, [layout]);
|
||||
}, [ layout ]);
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
|
@ -2,11 +2,11 @@ import { FigureUpdateEvent, RoomSessionEvent, UserInfoDataParser, UserInfoEvent
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetConfiguration, GetConfigurationManager } from '../../api';
|
||||
import { LayoutAvatarImageView } from '../../common';
|
||||
import { BatchUpdates, UseMessageEventHook, UseRoomSessionManagerEvent } from '../../hooks';
|
||||
import { UseMessageEventHook, UseRoomSessionManagerEvent } from '../../hooks';
|
||||
import { WidgetSlotView } from './views/widgets/WidgetSlotView';
|
||||
export const HotelView: FC<{}> = props =>
|
||||
{
|
||||
const [isVisible, setIsVisible] = useState(true);
|
||||
const [ isVisible, setIsVisible ] = useState(true);
|
||||
const widgetSlotCount = 7;
|
||||
const [ userFigure, setUserFigure ] = useState<string>(null);
|
||||
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
||||
@ -16,11 +16,8 @@ export const HotelView: FC<{}> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setUserInfo(parser.userInfo);
|
||||
setUserFigure(parser.userInfo.figure);
|
||||
});
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
||||
|
@ -8,8 +8,8 @@ export interface PromoArticleWidgetViewProps
|
||||
|
||||
export const PromoArticleWidgetView: FC<PromoArticleWidgetViewProps> = props =>
|
||||
{
|
||||
const [articles, setArticles] = useState<PromoArticleData[]>(null);
|
||||
const [index, setIndex] = useState(0);
|
||||
const [ articles, setArticles ] = useState<PromoArticleData[]>(null);
|
||||
const [ index, setIndex ] = useState(0);
|
||||
|
||||
const handleSelect = (selectedIndex) =>
|
||||
{
|
||||
|
@ -4,11 +4,11 @@ import { AddEventLinkTracker, GetLocalization, GetRoomEngine, LocalizeText, Remo
|
||||
import { isObjectMoverRequested, setObjectMoverRequested } from '../../api/inventory/InventoryUtilities';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { useInventoryTrade, useInventoryUnseenTracker, UseMessageEventHook, UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../hooks';
|
||||
import { InventoryBadgeView } from './views/InventoryBadgeView';
|
||||
import { InventoryBotView } from './views/InventoryBotView';
|
||||
import { InventoryFurnitureView } from './views/InventoryFurnitureView';
|
||||
import { InventoryPetView } from './views/InventoryPetView';
|
||||
import { InventoryTradeView } from './views/InventoryTradeView';
|
||||
import { InventoryBadgeView } from './views/badge/InventoryBadgeView';
|
||||
import { InventoryBotView } from './views/bot/InventoryBotView';
|
||||
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
|
||||
import { InventoryTradeView } from './views/furniture/InventoryTradeView';
|
||||
import { InventoryPetView } from './views/pet/InventoryPetView';
|
||||
|
||||
const TAB_FURNITURE: string = 'inventory.furni';
|
||||
const TAB_BOTS: string = 'inventory.bots';
|
||||
@ -130,10 +130,8 @@ export const InventoryView: FC<{}> = props =>
|
||||
<NitroCardTabsView>
|
||||
{ TABS.map((name, index) =>
|
||||
{
|
||||
const unseenCount = getCount(UNSEEN_CATEGORIES[index]);
|
||||
|
||||
return (
|
||||
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) } count={ unseenCount }>
|
||||
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) } count={ getCount(UNSEEN_CATEGORIES[index]) }>
|
||||
{ LocalizeText(name) }
|
||||
</NitroCardTabsItemView>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
@ -1,47 +1,37 @@
|
||||
import { FC, useEffect } from 'react';
|
||||
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, LayoutGridItem, Text } from '../../../common';
|
||||
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../hooks';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Flex, Grid, LayoutBadgeImageView, Text } from '../../../../common';
|
||||
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InventoryBadgeItemView } from './InventoryBadgeItemView';
|
||||
|
||||
export const InventoryBadgeView: FC<{}> = props =>
|
||||
{
|
||||
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, selectBadge = null, getBadgeId = null } = useInventoryBadges();
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, getBadgeId = null, activate = null, deactivate = null } = useInventoryBadges();
|
||||
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!badgeCodes || !badgeCodes.length) return;
|
||||
if(!selectedBadgeCode || !isUnseen(UnseenItemCategory.BADGE, getBadgeId(selectedBadgeCode))) return;
|
||||
|
||||
return () =>
|
||||
removeUnseen(UnseenItemCategory.BADGE, getBadgeId(selectedBadgeCode));
|
||||
}, [ selectedBadgeCode, isUnseen, removeUnseen, getBadgeId ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const count = getCount(UnseenItemCategory.BADGE);
|
||||
if(!isVisible) return;
|
||||
|
||||
if(!count) return;
|
||||
const id = activate();
|
||||
|
||||
resetCategory(UnseenItemCategory.BADGE);
|
||||
}
|
||||
}, [ badgeCodes, getCount, resetCategory ]);
|
||||
return () => deactivate(id);
|
||||
}, [ isVisible, activate, deactivate ]);
|
||||
|
||||
const InventoryBadgeItemView: FC<{ badgeCode: string }> = props =>
|
||||
useEffect(() =>
|
||||
{
|
||||
const { badgeCode = null, children = null, ...rest } = props;
|
||||
const badgeId = getBadgeId(badgeCode);
|
||||
const unseen = isUnseen(UnseenItemCategory.BADGE, badgeId);
|
||||
setIsVisible(true);
|
||||
|
||||
const select = () =>
|
||||
{
|
||||
selectBadge(badgeCode);
|
||||
|
||||
if(unseen) removeUnseen(UnseenItemCategory.BADGE, badgeId);
|
||||
}
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onMouseDown={ select } { ...rest }>
|
||||
<LayoutBadgeImageView badgeCode={ badgeCode } />
|
||||
{ children }
|
||||
</LayoutGridItem>
|
||||
);
|
||||
}
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid>
|
40
src/components/inventory/views/bot/InventoryBotItemView.tsx
Normal file
40
src/components/inventory/views/bot/InventoryBotItemView.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, useEffect, useState } from 'react';
|
||||
import { attemptBotPlacement, GetRoomEngine, IBotItem, LocalizeText, UnseenItemCategory } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutAvatarImageView, LayoutGridItem, LayoutRoomPreviewerView, Text } from '../../../common';
|
||||
import { useInventoryBots, useInventoryUnseenTracker } from '../../../hooks';
|
||||
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
|
||||
import { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { attemptBotPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
|
||||
import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryBotItemView } from './InventoryBotItemView';
|
||||
|
||||
interface InventoryBotViewProps
|
||||
{
|
||||
@ -14,22 +15,9 @@ interface InventoryBotViewProps
|
||||
export const InventoryBotView: FC<InventoryBotViewProps> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const { botItems = [], selectedBot = null, selectBot = null } = useInventoryBots();
|
||||
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!botItems || !botItems.length) return;
|
||||
|
||||
return () =>
|
||||
{
|
||||
const count = getCount(UnseenItemCategory.BOT);
|
||||
|
||||
if(!count) return;
|
||||
|
||||
resetCategory(UnseenItemCategory.BOT);
|
||||
}
|
||||
}, [ botItems, getCount, resetCategory ]);
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const { botItems = [], selectedBot = null, activate = null, deactivate = null } = useInventoryBots();
|
||||
const { isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -53,44 +41,31 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
|
||||
roomPreviewer.addAvatarIntoRoom(botData.figure, 0);
|
||||
}, [ roomPreviewer, selectedBot ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!selectedBot || !isUnseen(UnseenItemCategory.BOT, selectedBot.botData.id)) return;
|
||||
|
||||
removeUnseen(UnseenItemCategory.BOT, selectedBot.botData.id);
|
||||
}, [ selectedBot, isUnseen, removeUnseen ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
const id = activate();
|
||||
|
||||
return () => deactivate(id);
|
||||
}, [ isVisible, activate, deactivate ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
if(!botItems || !botItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.bots.title') } desc={ LocalizeText('inventory.empty.bots.desc') } />;
|
||||
|
||||
const InventoryBotItemView: FC<{ botItem: IBotItem }> = props =>
|
||||
{
|
||||
const { botItem = null } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
const isActive = (botItem === selectedBot);
|
||||
const unseen = isUnseen(UnseenItemCategory.BOT, botItem.botData.id);
|
||||
|
||||
const onMouseEvent = (event: MouseEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case MouseEventType.MOUSE_DOWN:
|
||||
selectBot(botItem);
|
||||
|
||||
if(unseen) removeUnseen(UnseenItemCategory.BOT, botItem.botData.id);
|
||||
|
||||
setMouseDown(true);
|
||||
return;
|
||||
case MouseEventType.MOUSE_UP:
|
||||
setMouseDown(false);
|
||||
return;
|
||||
case MouseEventType.ROLL_OUT:
|
||||
if(!isMouseDown || !isActive) return;
|
||||
|
||||
attemptBotPlacement(botItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ isActive } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||
<LayoutAvatarImageView figure={ botItem.botData.figure } direction={ 3 } headOnly={ true } />
|
||||
</LayoutGridItem>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column size={ 7 } overflow="hidden">
|
@ -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 } />;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
|
||||
import { GroupItem, LocalizeText } from '../../../api';
|
||||
import { Button, Flex } from '../../../common';
|
||||
import { GroupItem, LocalizeText } from '../../../../api';
|
||||
import { Button, Flex } from '../../../../common';
|
||||
|
||||
export interface InventoryFurnitureSearchViewProps
|
||||
{
|
@ -1,10 +1,11 @@
|
||||
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, useEffect, useState } from 'react';
|
||||
import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../common';
|
||||
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../hooks';
|
||||
import { attemptPlaceMarketplaceOffer } from '../../../hooks/inventory/common';
|
||||
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
|
||||
import { IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../../common';
|
||||
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { attemptPlaceMarketplaceOffer } from '../../../../hooks/inventory/common';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryFurnitureItemView } from './InventoryFurnitureItemView';
|
||||
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
|
||||
|
||||
interface InventoryFurnitureViewProps
|
||||
@ -16,9 +17,10 @@ interface InventoryFurnitureViewProps
|
||||
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>([]);
|
||||
const { groupItems = [], selectedItem = null, selectItem = null, activate = null, deactivate = null } = useInventoryFurni();
|
||||
const { getCount = null, resetCategory = null } = useInventoryUnseenTracker();
|
||||
const { groupItems = [], selectedItem = null, activate = null, deactivate = null } = useInventoryFurni();
|
||||
const { resetItems = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -72,65 +74,30 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!groupItems || !groupItems.length) return;
|
||||
if(!selectedItem || !selectedItem.hasUnseenItems) return;
|
||||
|
||||
return () =>
|
||||
{
|
||||
const count = getCount(UnseenItemCategory.FURNI);
|
||||
resetItems(UnseenItemCategory.FURNI, selectedItem.items.map(item => item.id));
|
||||
|
||||
if(!count) return;
|
||||
|
||||
resetCategory(UnseenItemCategory.FURNI);
|
||||
|
||||
for(const groupItem of groupItems) groupItem.hasUnseenItems = false;
|
||||
}
|
||||
}, [ groupItems, getCount, resetCategory ]);
|
||||
selectedItem.hasUnseenItems = false;
|
||||
}, [ selectedItem, resetItems ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
const id = activate();
|
||||
|
||||
return () => deactivate(id);
|
||||
}, [ activate, deactivate ]);
|
||||
|
||||
if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.title') } desc={ LocalizeText('inventory.empty.desc') } />;
|
||||
|
||||
const InventoryFurnitureItemView: FC<{ groupItem: GroupItem }> = props =>
|
||||
{
|
||||
const { groupItem = null } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
const isActive = (groupItem === selectedItem);
|
||||
|
||||
const onMouseEvent = (event: MouseEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case MouseEventType.MOUSE_DOWN:
|
||||
selectItem(groupItem);
|
||||
setMouseDown(true);
|
||||
return;
|
||||
case MouseEventType.MOUSE_UP:
|
||||
setMouseDown(false);
|
||||
return;
|
||||
case MouseEventType.ROLL_OUT:
|
||||
if(!isMouseDown || !isActive) return;
|
||||
|
||||
attemptItemPlacement(groupItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [ isVisible, activate, deactivate ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isActive) return;
|
||||
setIsVisible(true);
|
||||
|
||||
groupItem.hasUnseenItems = false;
|
||||
}, [ isActive, groupItem ]);
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
const count = groupItem.getUnlockedCount();
|
||||
|
||||
return <LayoutGridItem className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
|
||||
}
|
||||
if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.title') } desc={ LocalizeText('inventory.empty.desc') } />;
|
||||
|
||||
return (
|
||||
<Grid>
|
@ -1,10 +1,10 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { IObjectData, TradingListAddItemComposer, TradingListAddItemsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../api';
|
||||
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../common';
|
||||
import { useInventoryTrade } from '../../../hooks';
|
||||
import { getGuildFurniType } from '../../../hooks/inventory/common/TradingUtilities';
|
||||
import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../../api';
|
||||
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../../common';
|
||||
import { useInventoryTrade } from '../../../../hooks';
|
||||
import { getGuildFurniType } from '../../../../hooks/inventory/common/TradingUtilities';
|
||||
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
|
||||
|
||||
interface InventoryTradeViewProps
|
40
src/components/inventory/views/pet/InventoryPetItemView.tsx
Normal file
40
src/components/inventory/views/pet/InventoryPetItemView.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
import { IRoomSession, MouseEventType, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, useEffect, useState } from 'react';
|
||||
import { attemptPetPlacement, GetRoomEngine, IPetItem, LocalizeText, UnseenItemCategory } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutGridItem, LayoutPetImageView, LayoutRoomPreviewerView, Text } from '../../../common';
|
||||
import { useInventoryPets, useInventoryUnseenTracker } from '../../../hooks';
|
||||
import { InventoryCategoryEmptyView } from './InventoryCategoryEmptyView';
|
||||
import { IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { attemptPetPlacement, GetRoomEngine, LocalizeText, UnseenItemCategory } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
|
||||
import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryPetItemView } from './InventoryPetItemView';
|
||||
|
||||
interface InventoryPetViewProps
|
||||
{
|
||||
@ -14,22 +15,9 @@ interface InventoryPetViewProps
|
||||
export const InventoryPetView: FC<InventoryPetViewProps> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const { petItems = null, selectedPet = null, selectPet = null } = useInventoryPets();
|
||||
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!petItems || !petItems.length) return;
|
||||
|
||||
return () =>
|
||||
{
|
||||
const count = getCount(UnseenItemCategory.PET);
|
||||
|
||||
if(!count) return;
|
||||
|
||||
resetCategory(UnseenItemCategory.PET);
|
||||
}
|
||||
}, [ petItems, getCount, resetCategory ]);
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const { petItems = null, selectedPet = null, activate = null, deactivate = null } = useInventoryPets();
|
||||
const { isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -52,44 +40,31 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
|
||||
roomPreviewer.addPetIntoRoom(petData.figureString);
|
||||
}, [ roomPreviewer, selectedPet ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!selectedPet || !isUnseen(UnseenItemCategory.PET, selectedPet.petData.id)) return;
|
||||
|
||||
removeUnseen(UnseenItemCategory.PET, selectedPet.petData.id);
|
||||
}, [ selectedPet, isUnseen, removeUnseen ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
const id = activate();
|
||||
|
||||
return () => deactivate(id);
|
||||
}, [ isVisible, activate, deactivate ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
if(!petItems || !petItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.pets.title') } desc={ LocalizeText('inventory.empty.pets.desc') } />;
|
||||
|
||||
const InventoryPetItemView: FC<{ petItem: IPetItem }> = props =>
|
||||
{
|
||||
const { petItem = null } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
const isActive = (petItem === selectedPet);
|
||||
const unseen = isUnseen(UnseenItemCategory.PET, petItem.petData.id);
|
||||
|
||||
const onMouseEvent = (event: MouseEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case MouseEventType.MOUSE_DOWN:
|
||||
selectPet(petItem);
|
||||
|
||||
if(unseen) removeUnseen(UnseenItemCategory.PET, petItem.petData.id);
|
||||
|
||||
setMouseDown(true);
|
||||
return;
|
||||
case MouseEventType.MOUSE_UP:
|
||||
setMouseDown(false);
|
||||
return;
|
||||
case MouseEventType.ROLL_OUT:
|
||||
if(!isMouseDown || !isActive) return;
|
||||
|
||||
attemptPetPlacement(petItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ isActive } itemUnseen={ unseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||
<LayoutPetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
|
||||
</LayoutGridItem>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column size={ 7 } overflow="hidden">
|
@ -90,7 +90,7 @@ export const MainView: FC<{}> = props =>
|
||||
{
|
||||
RemoveLinkEventTracker(linkTracker);
|
||||
}
|
||||
}, [onLinkReceived]);
|
||||
}, [ onLinkReceived ]);
|
||||
|
||||
return (
|
||||
<Base fit>
|
||||
|
@ -34,7 +34,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
}
|
||||
});
|
||||
|
||||
}, [dispatchModToolsState]);
|
||||
}, [ dispatchModToolsState ]);
|
||||
|
||||
const onIssueInfoMessageEvent = useCallback((event: IssueInfoMessageEvent) =>
|
||||
{
|
||||
@ -62,7 +62,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
}
|
||||
});
|
||||
|
||||
}, [dispatchModToolsState, tickets]);
|
||||
}, [ dispatchModToolsState, tickets ]);
|
||||
|
||||
const onModeratorToolPreferencesEvent = useCallback((event: ModeratorToolPreferencesEvent) =>
|
||||
{
|
||||
@ -100,7 +100,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
tickets: newTickets
|
||||
}
|
||||
});
|
||||
}, [dispatchModToolsState, tickets]);
|
||||
}, [ dispatchModToolsState, tickets ]);
|
||||
|
||||
const onModeratorActionResultMessageEvent = useCallback((event: ModeratorActionResultMessageEvent) =>
|
||||
{
|
||||
@ -135,7 +135,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
|
||||
SetCfhCategories(categories);
|
||||
|
||||
}, [dispatchModToolsState]);
|
||||
}, [ dispatchModToolsState ]);
|
||||
|
||||
const onCfhSanctionMessageEvent = useCallback((event: CfhSanctionMessageEvent) =>
|
||||
{
|
||||
@ -195,7 +195,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
dispatchModToolsState({
|
||||
type: ModToolsActions.SET_OPEN_ROOMS,
|
||||
payload: {
|
||||
openRooms: [...rooms, castedEvent.roomId]
|
||||
openRooms: [ ...rooms, castedEvent.roomId ]
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -210,7 +210,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
dispatchModToolsState({
|
||||
type: ModToolsActions.SET_OPEN_ROOM_CHATLOGS,
|
||||
payload: {
|
||||
openRoomChatlogs: [...chatlogs, castedEvent.roomId]
|
||||
openRoomChatlogs: [ ...chatlogs, castedEvent.roomId ]
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -225,7 +225,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
dispatchModToolsState({
|
||||
type: ModToolsActions.SET_OPEN_USERINFO,
|
||||
payload: {
|
||||
openUserInfo: [...userInfo, castedEvent.userId]
|
||||
openUserInfo: [ ...userInfo, castedEvent.userId ]
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -240,13 +240,13 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
||||
dispatchModToolsState({
|
||||
type: ModToolsActions.SET_OPEN_USER_CHATLOGS,
|
||||
payload: {
|
||||
openUserChatlogs: [...userChatlog, castedEvent.userId]
|
||||
openUserChatlogs: [ ...userChatlog, castedEvent.userId ]
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [openRooms, dispatchModToolsState, openRoomChatlogs, openUserInfo, openUserChatlogs]);
|
||||
}, [ openRooms, dispatchModToolsState, openRoomChatlogs, openUserInfo, openUserChatlogs ]);
|
||||
|
||||
UseUiEvent(ModToolsEvent.OPEN_ROOM_INFO, onModToolsEvent);
|
||||
UseUiEvent(ModToolsEvent.OPEN_ROOM_CHATLOG, onModToolsEvent);
|
||||
|
@ -17,7 +17,7 @@ import { ModToolsUserView } from './views/user/ModToolsUserView';
|
||||
export const ModToolsView: FC<{}> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ selectedUser, setSelectedUser] = useState<ISelectedUser>(null);
|
||||
const [ selectedUser, setSelectedUser ] = useState<ISelectedUser>(null);
|
||||
const [ isTicketsVisible, setIsTicketsVisible ] = useState(false);
|
||||
const [ modToolsState, dispatchModToolsState ] = useReducer(ModToolsReducer, initialModTools);
|
||||
const { currentRoomId = null, openRooms = null, openRoomChatlogs = null, openUserChatlogs = null, openUserInfo = null } = modToolsState;
|
||||
@ -179,7 +179,7 @@ export const ModToolsView: FC<{}> = props =>
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [openRooms, currentRoomId, openRoomChatlogs, selectedUser, openUserInfo, openUserChatlogs]);
|
||||
}, [ openRooms, currentRoomId, openRoomChatlogs, selectedUser, openUserInfo, openUserChatlogs ]);
|
||||
|
||||
return (
|
||||
<ModToolsContextProvider value={ { modToolsState, dispatchModToolsState } }>
|
||||
|
@ -98,7 +98,7 @@ export const ChatlogView: FC<ChatlogViewProps> = props =>
|
||||
}
|
||||
|
||||
return count;
|
||||
}, [records]);
|
||||
}, [ records ]);
|
||||
|
||||
const RoomInfo = (props: { roomId: number, roomName: string, uniqueKey: Key, style: CSSProperties }) =>
|
||||
{
|
||||
|
@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { SendMessageComposer, TryVisitRoom } from '../../../../api';
|
||||
import { Button, Column, DraggableWindowPosition, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { ModToolsOpenRoomChatlogEvent } from '../../../../events/mod-tools/ModToolsOpenRoomChatlogEvent';
|
||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
||||
import { DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
||||
|
||||
interface ModToolsRoomViewProps
|
||||
{
|
||||
@ -36,15 +36,12 @@ export const ModToolsRoomView: FC<ModToolsRoomViewProps> = props =>
|
||||
|
||||
if(!parser || parser.data.flatId !== roomId) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setLoadedRoomId(parser.data.flatId);
|
||||
setName(parser.data.room.name);
|
||||
setOwnerId(parser.data.ownerId);
|
||||
setOwnerName(parser.data.ownerName);
|
||||
setOwnerInRoom(parser.data.ownerInRoom);
|
||||
setUsersInRoom(parser.data.userCount);
|
||||
});
|
||||
}, [ roomId ]);
|
||||
|
||||
UseMessageEventHook(ModeratorRoomInfoEvent, onModtoolRoomInfoEvent);
|
||||
|
@ -19,7 +19,7 @@ export const CfhChatlogView: FC<CfhChatlogViewProps> = props =>
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new GetCfhChatlogMessageComposer(issueId));
|
||||
}, [issueId]);
|
||||
}, [ issueId ]);
|
||||
|
||||
const onCfhChatlogEvent = useCallback((event: CfhChatlogEvent) =>
|
||||
{
|
||||
@ -28,7 +28,7 @@ export const CfhChatlogView: FC<CfhChatlogViewProps> = props =>
|
||||
if(!parser || parser.data.issueId !== issueId) return;
|
||||
|
||||
setChatlogData(parser.data);
|
||||
}, [issueId]);
|
||||
}, [ issueId ]);
|
||||
|
||||
UseMessageEventHook(CfhChatlogEvent, onCfhChatlogEvent);
|
||||
|
||||
@ -36,7 +36,7 @@ export const CfhChatlogView: FC<CfhChatlogViewProps> = props =>
|
||||
<NitroCardView className="nitro-mod-tools-chatlog" theme="primary-slim">
|
||||
<NitroCardHeaderView headerText={'Issue Chatlog'} onCloseClick={onCloseClick} />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ chatlogData && <ChatlogView records={[chatlogData.chatRecord]} />}
|
||||
{ chatlogData && <ChatlogView records={[ chatlogData.chatRecord ]} />}
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -13,7 +13,7 @@ export const ModToolsMyIssuesTabView: FC<ModToolsMyIssuesTabViewProps> = props =
|
||||
{
|
||||
const { myIssues = null, onIssueHandleClick = null } = props;
|
||||
|
||||
const onReleaseIssue = (issueId: number) => SendMessageComposer(new ReleaseIssuesMessageComposer([issueId]));
|
||||
const onReleaseIssue = (issueId: number) => SendMessageComposer(new ReleaseIssuesMessageComposer([ issueId ]));
|
||||
|
||||
return (
|
||||
<Column gap={ 0 } overflow="hidden">
|
||||
|
@ -12,7 +12,7 @@ export const ModToolsOpenIssuesTabView: FC<ModToolsOpenIssuesTabViewProps> = pro
|
||||
{
|
||||
const { openIssues = null } = props;
|
||||
|
||||
const onPickIssue = (issueId: number) => SendMessageComposer(new PickIssuesMessageComposer([issueId], false, 0, 'pick issue button'));
|
||||
const onPickIssue = (issueId: number) => SendMessageComposer(new PickIssuesMessageComposer([ issueId ], false, 0, 'pick issue button'));
|
||||
|
||||
return (
|
||||
<Column gap={ 0 } overflow="hidden">
|
||||
|
@ -32,21 +32,21 @@ export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
|
||||
if(!tickets) return [];
|
||||
|
||||
return tickets.filter(issue => issue.state === IssueMessageData.STATE_OPEN);
|
||||
}, [tickets]);
|
||||
}, [ tickets ]);
|
||||
|
||||
const myIssues = useMemo(() =>
|
||||
{
|
||||
if(!tickets) return [];
|
||||
|
||||
return tickets.filter(issue => (issue.state === IssueMessageData.STATE_PICKED) && (issue.pickerUserId === GetSessionDataManager().userId));
|
||||
}, [tickets]);
|
||||
}, [ tickets ]);
|
||||
|
||||
const pickedIssues = useMemo(() =>
|
||||
{
|
||||
if(!tickets) return [];
|
||||
|
||||
return tickets.filter(issue => issue.state === IssueMessageData.STATE_PICKED);
|
||||
}, [tickets]);
|
||||
}, [ tickets ]);
|
||||
|
||||
const onIssueInfoClosed = useCallback((issueId: number) =>
|
||||
{
|
||||
@ -57,7 +57,7 @@ export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
|
||||
const newValues = Array.from(issueInfoWindows);
|
||||
newValues.splice(indexOfValue, 1);
|
||||
setIssueInfoWindows(newValues);
|
||||
}, [issueInfoWindows]);
|
||||
}, [ issueInfoWindows ]);
|
||||
|
||||
const onIssueHandleClicked = useCallback((issueId: number) =>
|
||||
{
|
||||
@ -71,7 +71,7 @@ export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
|
||||
{
|
||||
onIssueInfoClosed(issueId);
|
||||
}
|
||||
}, [issueInfoWindows, onIssueInfoClosed]);
|
||||
}, [ issueInfoWindows, onIssueInfoClosed ]);
|
||||
|
||||
const CurrentTabComponent = useCallback(() =>
|
||||
{
|
||||
@ -82,7 +82,7 @@ export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
|
||||
case 2: return <ModToolsPickedIssuesTabView pickedIssues={pickedIssues}/>;
|
||||
default: return null;
|
||||
}
|
||||
}, [currentTab, myIssues, onIssueHandleClicked, openIssues, pickedIssues]);
|
||||
}, [ currentTab, myIssues, onIssueHandleClicked, openIssues, pickedIssues ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -2,7 +2,7 @@ import { ChatRecordData, GetUserChatlogMessageComposer, UserChatlogEvent } from
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { SendMessageComposer } from '../../../../api';
|
||||
import { DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../../hooks';
|
||||
import { UseMessageEventHook } from '../../../../hooks';
|
||||
import { ChatlogView } from '../chatlog/ChatlogView';
|
||||
|
||||
interface ModToolsUserChatlogViewProps
|
||||
@ -23,11 +23,8 @@ export const ModToolsUserChatlogView: FC<ModToolsUserChatlogViewProps> = props =
|
||||
|
||||
if(!parser || parser.data.userId !== userId) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setUsername(parser.data.username);
|
||||
setUserChatlog(parser.data.roomChatlogs);
|
||||
});
|
||||
}, [ userId ]);
|
||||
|
||||
UseMessageEventHook(UserChatlogEvent, onModtoolUserChatlogEvent);
|
||||
|
@ -43,7 +43,7 @@ export const ModToolsUserRoomVisitsView: FC<ModToolsUserRoomVisitsViewProps> = p
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new GetRoomVisitsMessageComposer(userId));
|
||||
}, [userId]);
|
||||
}, [ userId ]);
|
||||
|
||||
if(!userId) return null;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { CanCreateRoomEventEvent, CantConnectMessageParser, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomResultEvent, HabboWebTools, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CreateLinkEvent, CreateRoomSession, DoorStateType, GetConfiguration, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../hooks';
|
||||
import { UseMessageEventHook } from '../../hooks';
|
||||
import { useNavigatorContext } from './NavigatorContext';
|
||||
|
||||
export const NavigatorMessageHandler: FC<{}> = props =>
|
||||
@ -271,19 +271,14 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setTopLevelContexts(parser.topLevelContexts);
|
||||
setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
|
||||
});
|
||||
}, [ setTopLevelContexts, setTopLevelContext ]);
|
||||
|
||||
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setTopLevelContext(prevValue =>
|
||||
{
|
||||
let newValue = prevValue;
|
||||
@ -313,7 +308,6 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
||||
});
|
||||
|
||||
setSearchResult(parser.result);
|
||||
});
|
||||
}, [ topLevelContexts, setTopLevelContext, setSearchResult ]);
|
||||
|
||||
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) =>
|
||||
|
@ -3,7 +3,7 @@ import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, L
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { AddEventLinkTracker, DoorStateType, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
|
||||
import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { BatchUpdates, UseRoomSessionManagerEvent, useSharedNavigatorData } from '../../hooks';
|
||||
import { UseRoomSessionManagerEvent, useSharedNavigatorData } from '../../hooks';
|
||||
import { NavigatorContextProvider } from './NavigatorContext';
|
||||
import { NavigatorMessageHandler } from './NavigatorMessageHandler';
|
||||
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
|
||||
@ -37,11 +37,8 @@ export const NavigatorView: FC<{}> = props =>
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomSessionEvent.CREATED:
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
setCreatorOpen(false);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
@ -96,11 +93,8 @@ export const NavigatorView: FC<{}> = props =>
|
||||
switch(parts[1])
|
||||
{
|
||||
case 'show': {
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'hide':
|
||||
@ -114,11 +108,8 @@ export const NavigatorView: FC<{}> = props =>
|
||||
return;
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'toggle-room-info':
|
||||
@ -145,11 +136,8 @@ export const NavigatorView: FC<{}> = props =>
|
||||
}
|
||||
return;
|
||||
case 'create':
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
setCreatorOpen(true);
|
||||
});
|
||||
return;
|
||||
case 'search':
|
||||
if(parts.length > 2)
|
||||
@ -162,11 +150,8 @@ export const NavigatorView: FC<{}> = props =>
|
||||
|
||||
pendingSearch.current = { value: searchValue, code: topLevelContextCode };
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import { HabboClubLevelEnum, RoomCreateComposer } from '@nitrots/nitro-renderer'
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { GetClubMemberLevel, GetConfiguration, IRoomModel, LocalizeText, RoomModels, SendMessageComposer } from '../../../api';
|
||||
import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, Text } from '../../../common';
|
||||
import { BatchUpdates } from '../../../hooks';
|
||||
import { useNavigatorContext } from '../NavigatorContext';
|
||||
|
||||
export const NavigatorRoomCreatorView: FC<{}> = props =>
|
||||
@ -39,11 +38,8 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
|
||||
|
||||
for(let i = 10; i <= 100; i = i + 10) list.push(i);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setMaxVisitorsList(list);
|
||||
setVisitorsCount(list[0]);
|
||||
});
|
||||
}
|
||||
}, [ maxVisitorsList ]);
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react';
|
||||
import { CreateLinkEvent, GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../common';
|
||||
import { FloorplanEditorEvent, RoomWidgetThumbnailEvent } from '../../../events';
|
||||
import { BatchUpdates, DispatchUiEvent } from '../../../hooks';
|
||||
import { DispatchUiEvent } from '../../../hooks';
|
||||
import { useNavigatorContext } from '../NavigatorContext';
|
||||
|
||||
export class NavigatorRoomInfoViewProps
|
||||
@ -85,11 +85,9 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{
|
||||
if(!navigatorData) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsRoomPicked(navigatorData.currentRoomIsStaffPick);
|
||||
|
||||
if(navigatorData.enteredGuestRoom) setIsRoomMuted(navigatorData.enteredGuestRoom.allInRoomMuted);
|
||||
});
|
||||
}, [ navigatorData ]);
|
||||
|
||||
if(!navigatorData.enteredGuestRoom) return null;
|
||||
@ -142,7 +140,7 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
<Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }>
|
||||
<LayoutBadgeImageView className="flex-none" badgeCode={ navigatorData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||
<Text underline>
|
||||
{ LocalizeText('navigator.guildbase', ['groupName'], [navigatorData.enteredGuestRoom.groupName]) }
|
||||
{ LocalizeText('navigator.guildbase', [ 'groupName' ], [ navigatorData.enteredGuestRoom.groupName ]) }
|
||||
</Text>
|
||||
</Flex> }
|
||||
</Column>
|
||||
|
@ -2,7 +2,6 @@ import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { IRoomData, LocalizeText } from '../../../../api';
|
||||
import { Column, Flex, Text } from '../../../../common';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
|
||||
interface NavigatorRoomSettingsTabViewProps
|
||||
{
|
||||
@ -25,13 +24,10 @@ export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabView
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setPassword('');
|
||||
setConfirmPassword('');
|
||||
setIsTryingPassword(false);
|
||||
});
|
||||
}, [ roomData ]);
|
||||
|
||||
return (
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user