diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index c51d7b9c..00000000 --- a/.eslintrc.js +++ /dev/null @@ -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' - ] - } - } diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..97926803 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,67 @@ +{ + "root": true, + "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" ], + "template-curly-spacing": [ "error", "always" ], + "no-multi-spaces": [ "error" ], + "jsx-quotes": [ "error" ], + "react/prop-types": [ "off" ], + "react/jsx-curly-spacing": [ "error", { "when": "always", "children": true } ], + "react/jsx-equals-spacing": [ "error" ], + "react/jsx-newline": [ "error", { "prevent": true } ], + "@typescript-eslint/object-curly-spacing": [ "error", "always", + { + "arraysInObjects": true, + "objectsInObjects": false + } + ], + "@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" ] + } +} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index b14d30ec..00000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -*.scss diff --git a/.vscode/settings.json b/.vscode/settings.json index abf4f847..0ac4ef4b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" ] } diff --git a/package.json b/package.json index 5a1e9a59..a5ea631c 100644 --- a/package.json +++ b/package.json @@ -3,28 +3,30 @@ "version": "2.0.0", "private": true, "scripts": { - "start": "cross-env BROWSER=none IMAGE_INLINE_SIZE_LIMIT=100000 craco start", - "build": "cross-env GENERATE_SOURCEMAP=false IMAGE_INLINE_SIZE_LIMIT=100000 craco build", + "start": "cross-env SKIP_PREFLIGHT_CHECK=true BROWSER=none IMAGE_INLINE_SIZE_LIMIT=100000 craco start", + "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", "@fortawesome/fontawesome-svg-core": "^6.1.0", "@fortawesome/free-solid-svg-icons": "^6.1.0", "@fortawesome/react-fontawesome": "^0.1.17", - "@nitrots/nitro-renderer": "^1.1.18", + "@nitrots/nitro-renderer": "^1.2.5", + "@types/react-transition-group": "^4.4.4", "animate.css": "^4.1.1", "classnames": "^2.3.1", "cross-env": "^7.0.3", "emoji-toolkit": "^6.6.0", "node-sass": "^6.0.1", - "react": "^17.0.2", - "react-bootstrap": "^2.0.0-alpha.2", - "react-dom": "^17.0.2", + "react": "^18.0.0", + "react-bootstrap": "^2.2.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", @@ -32,16 +34,23 @@ "use-between": "^1.3.1" }, "resolutions": { - "react-error-overlay": "6.0.9" + "react-error-overlay": "6.0.9", + "@types/react": "^18.0.8", + "@types/react-dom": "^18.0.3" }, "devDependencies": { "@types/node": "^12.20.19", - "@types/react": "^17.0.15", - "@types/react-dom": "^17.0.9", + "@types/react": "^18.0.8", + "@types/react-dom": "^18.0.3", "@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" } } diff --git a/public/ui-config.json.example b/public/ui-config.json.example index 75bc4a4a..1145a59a 100644 --- a/public/ui-config.json.example +++ b/public/ui-config.json.example @@ -1,8 +1,8 @@ { "image.library.notifications.url": "${image.library.url}notifications/%image%.png", "achievements.images.url": "${image.library.url}Quests/%image%.png", - "camera.url": "https://camera.com", - "thumbnails.url": "https://camera.com/thumbnail/%thumbnail%.png", + "camera.url": "https://camera.url", + "thumbnails.url": "https://camera.url/thumbnail/%thumbnail%.png", "url.prefix": "https://website.com", "habbopages.url": "${url.prefix}/", "group.homepage.url": "${url.prefix}/groups/%groupid%/id", @@ -16,6 +16,43 @@ "badge.descriptions.enabled": true, "motto.max.length": 38, "bot.name.max.length": 15, + "navigator.room.models": [ + { "clubLevel": 0, "tileSize": 104, "name": "a" }, + { "clubLevel": 0, "tileSize": 94, "name": "b" }, + { "clubLevel": 0, "tileSize": 36, "name": "c" }, + { "clubLevel": 0, "tileSize": 84, "name": "d" }, + { "clubLevel": 0, "tileSize": 80, "name": "e" }, + { "clubLevel": 0, "tileSize": 80, "name": "f" }, + { "clubLevel": 0, "tileSize": 416, "name": "i" }, + { "clubLevel": 0, "tileSize": 320, "name": "j" }, + { "clubLevel": 0, "tileSize": 448, "name": "k" }, + { "clubLevel": 0, "tileSize": 352, "name": "l" }, + { "clubLevel": 0, "tileSize": 384, "name": "m" }, + { "clubLevel": 0, "tileSize": 372, "name": "n" }, + { "clubLevel": 1, "tileSize": 80, "name": "g" }, + { "clubLevel": 1, "tileSize": 74, "name": "h" }, + { "clubLevel": 1, "tileSize": 416, "name": "o" }, + { "clubLevel": 1, "tileSize": 352, "name": "p" }, + { "clubLevel": 1, "tileSize": 304, "name": "q" }, + { "clubLevel": 1, "tileSize": 336, "name": "r" }, + { "clubLevel": 1, "tileSize": 748, "name": "u" }, + { "clubLevel": 1, "tileSize": 438, "name": "v" }, + { "clubLevel": 2, "tileSize": 540, "name": "t" }, + { "clubLevel": 2, "tileSize": 512, "name": "w" }, + { "clubLevel": 2, "tileSize": 396, "name": "x" }, + { "clubLevel": 2, "tileSize": 440, "name": "y" }, + { "clubLevel": 2, "tileSize": 456, "name": "z" }, + { "clubLevel": 2, "tileSize": 208, "name": "0" }, + { "clubLevel": 2, "tileSize": 1009, "name": "1" }, + { "clubLevel": 2, "tileSize": 1044, "name": "2" }, + { "clubLevel": 2, "tileSize": 183, "name": "3" }, + { "clubLevel": 2, "tileSize": 254, "name": "4" }, + { "clubLevel": 2, "tileSize": 1024, "name": "5" }, + { "clubLevel": 2, "tileSize": 801, "name": "6" }, + { "clubLevel": 2, "tileSize": 354, "name": "7" }, + { "clubLevel": 2, "tileSize": 888, "name": "8" }, + { "clubLevel": 2, "tileSize": 926, "name": "9" } + ], "hotelview": { "show.avatar": true, "widgets": { diff --git a/src/App.scss b/src/App.scss index 9dd4dcfd..9a3bd885 100644 --- a/src/App.scss +++ b/src/App.scss @@ -52,7 +52,7 @@ $friends-list-width: 250px; $friends-list-height: 300px; $help-width: 450px; -$help-height: 250px; +$help-height: 290px; $nitropedia-width: 400px; $nitropedia-height: 400px; diff --git a/src/App.tsx b/src/App.tsx index e2119242..104e858f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,12 @@ import { ConfigurationEvent, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent, WebGL } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useState } from 'react'; +import { FC, useCallback, useEffect, useState } from 'react'; import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api'; import { Base, TransitionAnimation, TransitionAnimationTypes } from './common'; import { LoadingView } from './components/loading/LoadingView'; import { MainView } from './components/main/MainView'; import { DispatchUiEvent, UseConfigurationEvent, UseLocalizationEvent, UseMainEvent, UseRoomEngineEvent } from './hooks'; +import IntervalWebWorker from './workers/IntervalWebWorker'; +import { WorkerBuilder } from './workers/WorkerBuilder'; NitroVersion.UI_VERSION = GetUIVersion(); @@ -12,28 +14,21 @@ 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); + const [ imageRendering, setImageRendering ] = useState(true); - //@ts-ignore - if(!NitroConfig) throw new Error('NitroConfig is not defined!'); - - if(!GetNitroInstance()) Nitro.bootstrap(); - - const getPreloadAssetUrls = useCallback(() => + if(!GetNitroInstance()) { - const urls: string[] = []; - const assetUrls = GetConfiguration('preload.assets.urls'); + //@ts-ignore + if(!NitroConfig) throw new Error('NitroConfig is not defined!'); - if(assetUrls && assetUrls.length) - { - for(const url of assetUrls) urls.push(GetNitroInstance().core.configuration.interpolate(url)); - } + Nitro.bootstrap(); - return urls; - }, []); + const worker = new WorkerBuilder(IntervalWebWorker); - const loadPercent = useCallback(() => setPercent(prevValue => (prevValue + 20)), []); + Nitro.instance.setWorker(worker); + } const handler = useCallback((event: NitroEvent) => { @@ -41,7 +36,7 @@ export const App: FC<{}> = props => { case ConfigurationEvent.LOADED: GetNitroInstance().localization.init(); - loadPercent(); + setPercent(prevValue => (prevValue + 20)); return; case ConfigurationEvent.FAILED: setIsError(true); @@ -58,44 +53,48 @@ export const App: FC<{}> = props => setTimeout(() => window.location.reload(), 1500); return; case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING: - loadPercent(); - return; - case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED: + setPercent(prevValue => (prevValue + 20)); + return; + case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED: setIsError(true); setMessage('Handshake Failed'); - return; - case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED: - loadPercent(); + return; + case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED: + setPercent(prevValue => (prevValue + 20)); GetNitroInstance().init(); if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'authentication', 'authok', []); - return; - case NitroCommunicationDemoEvent.CONNECTION_ERROR: + return; + case NitroCommunicationDemoEvent.CONNECTION_ERROR: setIsError(true); setMessage('Connection Error'); - return; - case NitroCommunicationDemoEvent.CONNECTION_CLOSED: + return; + case NitroCommunicationDemoEvent.CONNECTION_CLOSED: //if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose(); - //setIsError(true); setMessage('Connection Error'); HabboWebTools.send(-1, 'client.init.handshake.fail'); return; case RoomEngineEvent.ENGINE_INITIALIZED: - loadPercent(); + setPercent(prevValue => (prevValue + 20)); setTimeout(() => setIsReady(true), 300); return; - case NitroLocalizationEvent.LOADED: - GetNitroInstance().core.asset.downloadAssets(getPreloadAssetUrls(), (status: boolean) => + case NitroLocalizationEvent.LOADED: { + const assetUrls = GetConfiguration('preload.assets.urls'); + const urls: string[] = []; + + if(assetUrls && assetUrls.length) for(const url of assetUrls) urls.push(GetNitroInstance().core.configuration.interpolate(url)); + + GetNitroInstance().core.asset.downloadAssets(urls, (status: boolean) => { if(status) { GetCommunication().init(); - loadPercent(); + setPercent(prevValue => (prevValue + 20)) } else { @@ -104,8 +103,9 @@ export const App: FC<{}> = props => } }); return; + } } - }, [ getPreloadAssetUrls,loadPercent ]); + }, []); UseMainEvent(Nitro.WEBGL_UNAVAILABLE, handler); UseMainEvent(Nitro.WEBGL_CONTEXT_LOST, handler); @@ -119,19 +119,33 @@ export const App: FC<{}> = props => UseConfigurationEvent(ConfigurationEvent.LOADED, handler); UseConfigurationEvent(ConfigurationEvent.FAILED, handler); - if(!WebGL.isWebGLAvailable()) + useEffect(() => { - DispatchUiEvent(new NitroEvent(Nitro.WEBGL_UNAVAILABLE)); - } - else - { - GetNitroInstance().core.configuration.init(); - } + if(!WebGL.isWebGLAvailable()) + { + DispatchUiEvent(new NitroEvent(Nitro.WEBGL_UNAVAILABLE)); + } + else + { + GetNitroInstance().core.configuration.init(); + } + + const resize = (event: UIEvent) => setImageRendering(!(window.devicePixelRatio % 1)); + + window.addEventListener('resize', resize); + + resize(null); + + return () => + { + window.removeEventListener('resize', resize); + } + }, []); return ( - + { (!isReady || isError) && - } + } diff --git a/src/api/achievements/GetAchievementCategoryTotalUnseen.ts b/src/api/achievements/GetAchievementCategoryTotalUnseen.ts index 940b7023..a2771275 100644 --- a/src/api/achievements/GetAchievementCategoryTotalUnseen.ts +++ b/src/api/achievements/GetAchievementCategoryTotalUnseen.ts @@ -6,7 +6,7 @@ export const GetAchievementCategoryTotalUnseen = (category: IAchievementCategory let unseen = 0; - for(const achievement of category.achievements) unseen += achievement.unseen; + for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++); return unseen; } diff --git a/src/api/catalog/BuilderFurniPlaceableStatus.ts b/src/api/catalog/BuilderFurniPlaceableStatus.ts new file mode 100644 index 00000000..40eb6f65 --- /dev/null +++ b/src/api/catalog/BuilderFurniPlaceableStatus.ts @@ -0,0 +1,10 @@ +export class BuilderFurniPlaceableStatus +{ + public static OKAY: number = 0; + public static MISSING_OFFER: number = 1; + public static FURNI_LIMIT_REACHED: number = 2; + public static NOT_IN_ROOM: number = 3; + public static NOT_ROOM_OWNER: number = 4; + public static GUILD_ROOM: number = 5; + public static VISITORS_IN_ROOM: number = 6; +} diff --git a/src/components/catalog/common/CatalogNode.ts b/src/api/catalog/CatalogNode.ts similarity index 100% rename from src/components/catalog/common/CatalogNode.ts rename to src/api/catalog/CatalogNode.ts diff --git a/src/components/catalog/common/CatalogPage.ts b/src/api/catalog/CatalogPage.ts similarity index 100% rename from src/components/catalog/common/CatalogPage.ts rename to src/api/catalog/CatalogPage.ts diff --git a/src/components/catalog/common/CatalogPageName.ts b/src/api/catalog/CatalogPageName.ts similarity index 100% rename from src/components/catalog/common/CatalogPageName.ts rename to src/api/catalog/CatalogPageName.ts diff --git a/src/components/catalog/common/CatalogPetPalette.ts b/src/api/catalog/CatalogPetPalette.ts similarity index 93% rename from src/components/catalog/common/CatalogPetPalette.ts rename to src/api/catalog/CatalogPetPalette.ts index 7a7df4c2..d92c40dd 100644 --- a/src/components/catalog/common/CatalogPetPalette.ts +++ b/src/api/catalog/CatalogPetPalette.ts @@ -5,5 +5,6 @@ export class CatalogPetPalette constructor( public readonly breed: string, public readonly palettes: SellablePetPaletteData[] - ) {} + ) + {} } diff --git a/src/components/catalog/common/CatalogPurchaseState.ts b/src/api/catalog/CatalogPurchaseState.ts similarity index 100% rename from src/components/catalog/common/CatalogPurchaseState.ts rename to src/api/catalog/CatalogPurchaseState.ts diff --git a/src/components/catalog/common/CatalogType.ts b/src/api/catalog/CatalogType.ts similarity index 100% rename from src/components/catalog/common/CatalogType.ts rename to src/api/catalog/CatalogType.ts diff --git a/src/components/catalog/common/CatalogUtilities.ts b/src/api/catalog/CatalogUtilities.ts similarity index 59% rename from src/components/catalog/common/CatalogUtilities.ts rename to src/api/catalog/CatalogUtilities.ts index f2655688..5ca8fed5 100644 --- a/src/components/catalog/common/CatalogUtilities.ts +++ b/src/api/catalog/CatalogUtilities.ts @@ -1,5 +1,5 @@ import { SellablePetPaletteData } from '@nitrots/nitro-renderer'; -import { GetRoomEngine } from '../../../api'; +import { GetRoomEngine } from '../nitro'; import { ICatalogNode } from './ICatalogNode'; export const GetPixelEffectIcon = (id: number) => @@ -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[][] = []; diff --git a/src/components/catalog/common/FurnitureOffer.ts b/src/api/catalog/FurnitureOffer.ts similarity index 99% rename from src/components/catalog/common/FurnitureOffer.ts rename to src/api/catalog/FurnitureOffer.ts index b25c376f..4c9c9f94 100644 --- a/src/components/catalog/common/FurnitureOffer.ts +++ b/src/api/catalog/FurnitureOffer.ts @@ -1,5 +1,5 @@ import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer'; -import { GetProductDataForLocalization, SendMessageComposer } from '../../../api'; +import { GetProductDataForLocalization, SendMessageComposer } from '..'; import { ICatalogPage } from './ICatalogPage'; import { IProduct } from './IProduct'; import { IPurchasableOffer } from './IPurchasableOffer'; diff --git a/src/components/catalog/common/GiftWrappingConfiguration.ts b/src/api/catalog/GiftWrappingConfiguration.ts similarity index 100% rename from src/components/catalog/common/GiftWrappingConfiguration.ts rename to src/api/catalog/GiftWrappingConfiguration.ts diff --git a/src/components/catalog/common/ICatalogNode.ts b/src/api/catalog/ICatalogNode.ts similarity index 100% rename from src/components/catalog/common/ICatalogNode.ts rename to src/api/catalog/ICatalogNode.ts diff --git a/src/components/catalog/common/ICatalogOptions.ts b/src/api/catalog/ICatalogOptions.ts similarity index 85% rename from src/components/catalog/common/ICatalogOptions.ts rename to src/api/catalog/ICatalogOptions.ts index 49ed1737..20356947 100644 --- a/src/components/catalog/common/ICatalogOptions.ts +++ b/src/api/catalog/ICatalogOptions.ts @@ -1,7 +1,6 @@ import { ClubGiftInfoParser, ClubOfferData, HabboGroupEntryData, MarketplaceConfigurationMessageParser } from '@nitrots/nitro-renderer'; import { CatalogPetPalette } from './CatalogPetPalette'; import { GiftWrappingConfiguration } from './GiftWrappingConfiguration'; -import { SubscriptionInfo } from './SubscriptionInfo'; export interface ICatalogOptions { @@ -9,7 +8,6 @@ export interface ICatalogOptions petPalettes?: CatalogPetPalette[]; clubOffers?: ClubOfferData[]; clubGifts?: ClubGiftInfoParser; - subscriptionInfo?: SubscriptionInfo; giftConfiguration?: GiftWrappingConfiguration; marketplaceConfiguration?: MarketplaceConfigurationMessageParser; } diff --git a/src/components/catalog/common/ICatalogPage.ts b/src/api/catalog/ICatalogPage.ts similarity index 100% rename from src/components/catalog/common/ICatalogPage.ts rename to src/api/catalog/ICatalogPage.ts diff --git a/src/components/catalog/common/IPageLocalization.ts b/src/api/catalog/IPageLocalization.ts similarity index 100% rename from src/components/catalog/common/IPageLocalization.ts rename to src/api/catalog/IPageLocalization.ts diff --git a/src/components/catalog/common/IProduct.ts b/src/api/catalog/IProduct.ts similarity index 100% rename from src/components/catalog/common/IProduct.ts rename to src/api/catalog/IProduct.ts diff --git a/src/components/catalog/common/IPurchasableOffer.ts b/src/api/catalog/IPurchasableOffer.ts similarity index 100% rename from src/components/catalog/common/IPurchasableOffer.ts rename to src/api/catalog/IPurchasableOffer.ts diff --git a/src/components/catalog/common/IPurchaseOptions.ts b/src/api/catalog/IPurchaseOptions.ts similarity index 100% rename from src/components/catalog/common/IPurchaseOptions.ts rename to src/api/catalog/IPurchaseOptions.ts diff --git a/src/components/catalog/common/Offer.ts b/src/api/catalog/Offer.ts similarity index 98% rename from src/components/catalog/common/Offer.ts rename to src/api/catalog/Offer.ts index b39ed48f..c14d6ac1 100644 --- a/src/components/catalog/common/Offer.ts +++ b/src/api/catalog/Offer.ts @@ -1,9 +1,8 @@ -import { GetFurnitureData, GetProductDataForLocalization, LocalizeText } from '../../../api'; +import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, ProductTypeEnum } from '..'; import { ICatalogPage } from './ICatalogPage'; import { IProduct } from './IProduct'; import { IPurchasableOffer } from './IPurchasableOffer'; import { Product } from './Product'; -import { ProductTypeEnum } from './ProductTypeEnum'; export class Offer implements IPurchasableOffer { diff --git a/src/components/catalog/common/PageLocalization.ts b/src/api/catalog/PageLocalization.ts similarity index 94% rename from src/components/catalog/common/PageLocalization.ts rename to src/api/catalog/PageLocalization.ts index 6a51830d..91e3ce6f 100644 --- a/src/components/catalog/common/PageLocalization.ts +++ b/src/api/catalog/PageLocalization.ts @@ -1,4 +1,4 @@ -import { GetConfiguration } from '../../../api'; +import { GetConfiguration } from '../nitro'; import { IPageLocalization } from './IPageLocalization'; export class PageLocalization implements IPageLocalization diff --git a/src/api/catalog/PlacedObjectPurchaseData.ts b/src/api/catalog/PlacedObjectPurchaseData.ts new file mode 100644 index 00000000..84bad8cd --- /dev/null +++ b/src/api/catalog/PlacedObjectPurchaseData.ts @@ -0,0 +1,41 @@ +import { IFurnitureData, IProductData } from '@nitrots/nitro-renderer'; +import { IPurchasableOffer } from './IPurchasableOffer'; + +export class PlacedObjectPurchaseData +{ + constructor( + public readonly roomId: number, + public readonly objectId: number, + public readonly category: number, + public readonly wallLocation: string, + public readonly x: number, + public readonly y: number, + public readonly direction: number, + public readonly offer: IPurchasableOffer) + {} + + public get offerId(): number + { + return this.offer.offerId; + } + + public get productClassId(): number + { + return this.offer.product.productClassId; + } + + public get productData(): IProductData + { + return this.offer.product.productData; + } + + public get furniData(): IFurnitureData + { + return this.offer.product.furnitureData; + } + + public get extraParam(): string + { + return this.offer.product.extraParam; + } +} diff --git a/src/components/catalog/common/Product.ts b/src/api/catalog/Product.ts similarity index 99% rename from src/components/catalog/common/Product.ts rename to src/api/catalog/Product.ts index e0e8f079..bfb760fc 100644 --- a/src/components/catalog/common/Product.ts +++ b/src/api/catalog/Product.ts @@ -1,5 +1,5 @@ import { IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer'; -import { GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../../../api'; +import { GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../nitro'; import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities'; import { IProduct } from './IProduct'; import { IPurchasableOffer } from './IPurchasableOffer'; diff --git a/src/api/catalog/ProductTypeEnum.ts b/src/api/catalog/ProductTypeEnum.ts new file mode 100644 index 00000000..f2490816 --- /dev/null +++ b/src/api/catalog/ProductTypeEnum.ts @@ -0,0 +1,11 @@ +export class ProductTypeEnum +{ + public static WALL: string = 'i'; + public static FLOOR: string = 's'; + public static EFFECT: string = 'e'; + public static HABBO_CLUB: string = 'h'; + public static BADGE: string = 'b'; + public static GAME_TOKEN: string = 'GAME_TOKEN'; + public static PET: string = 'p'; + public static ROBOT: string = 'r'; +} diff --git a/src/components/catalog/common/RequestedPage.ts b/src/api/catalog/RequestedPage.ts similarity index 100% rename from src/components/catalog/common/RequestedPage.ts rename to src/api/catalog/RequestedPage.ts diff --git a/src/components/catalog/common/SearchResult.ts b/src/api/catalog/SearchResult.ts similarity index 79% rename from src/components/catalog/common/SearchResult.ts rename to src/api/catalog/SearchResult.ts index 4083c699..419f3cf4 100644 --- a/src/components/catalog/common/SearchResult.ts +++ b/src/api/catalog/SearchResult.ts @@ -6,6 +6,6 @@ export class SearchResult constructor( public readonly searchValue: string, public readonly offers: IPurchasableOffer[], - public readonly filteredNodes: ICatalogNode[] - ) {} + public readonly filteredNodes: ICatalogNode[]) + {} } diff --git a/src/api/catalog/index.ts b/src/api/catalog/index.ts new file mode 100644 index 00000000..ba084bc8 --- /dev/null +++ b/src/api/catalog/index.ts @@ -0,0 +1,24 @@ +export * from './BuilderFurniPlaceableStatus'; +export * from './CatalogNode'; +export * from './CatalogPage'; +export * from './CatalogPageName'; +export * from './CatalogPetPalette'; +export * from './CatalogPurchaseState'; +export * from './CatalogType'; +export * from './CatalogUtilities'; +export * from './FurnitureOffer'; +export * from './GiftWrappingConfiguration'; +export * from './ICatalogNode'; +export * from './ICatalogOptions'; +export * from './ICatalogPage'; +export * from './IPageLocalization'; +export * from './IProduct'; +export * from './IPurchasableOffer'; +export * from './IPurchaseOptions'; +export * from './Offer'; +export * from './PageLocalization'; +export * from './PlacedObjectPurchaseData'; +export * from './Product'; +export * from './ProductTypeEnum'; +export * from './RequestedPage'; +export * from './SearchResult'; diff --git a/src/api/common/index.ts b/src/api/common/index.ts deleted file mode 100644 index 8fa51bfb..00000000 --- a/src/api/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ProductImageUtility'; diff --git a/src/api/friends/GetGroupChatData.ts b/src/api/friends/GetGroupChatData.ts new file mode 100644 index 00000000..75df9629 --- /dev/null +++ b/src/api/friends/GetGroupChatData.ts @@ -0,0 +1,13 @@ +import { IGroupChatData } from './IGroupChatData'; + +export const GetGroupChatData = (extraData: string) => +{ + if(!extraData || !extraData.length) return null; + + const splitData = extraData.split('/'); + const username = splitData[0]; + const figure = splitData[1]; + const userId = parseInt(splitData[2]); + + return ({ username: username, figure: figure, userId: userId } as IGroupChatData); +} diff --git a/src/components/friends/common/GroupType.ts b/src/api/friends/GroupType.ts similarity index 100% rename from src/components/friends/common/GroupType.ts rename to src/api/friends/GroupType.ts diff --git a/src/api/friends/IGroupChatData.ts b/src/api/friends/IGroupChatData.ts new file mode 100644 index 00000000..24a3f9cf --- /dev/null +++ b/src/api/friends/IGroupChatData.ts @@ -0,0 +1,6 @@ +export interface IGroupChatData +{ + username: string; + figure: string; + userId: number; +} diff --git a/src/components/friends/common/MessengerFriend.ts b/src/api/friends/MessengerFriend.ts similarity index 96% rename from src/components/friends/common/MessengerFriend.ts rename to src/api/friends/MessengerFriend.ts index 2ed3c655..b5cfc887 100644 --- a/src/components/friends/common/MessengerFriend.ts +++ b/src/api/friends/MessengerFriend.ts @@ -2,7 +2,7 @@ import { FriendParser } from '@nitrots/nitro-renderer'; export class MessengerFriend { - public static RELATIONSHIP_NONE: number = 0; + public static RELATIONSHIP_NONE: number = 0; public static RELATIONSHIP_HEART: number = 1; public static RELATIONSHIP_SMILE: number = 2; public static RELATIONSHIP_BOBBA: number = 3; diff --git a/src/api/friends/MessengerIconState.ts b/src/api/friends/MessengerIconState.ts new file mode 100644 index 00000000..63f8c133 --- /dev/null +++ b/src/api/friends/MessengerIconState.ts @@ -0,0 +1,6 @@ +export class MessengerIconState +{ + public static HIDDEN: number = 0; + public static SHOW: number = 1; + public static UNREAD: number = 2; +} diff --git a/src/components/friends/common/MessengerRequest.ts b/src/api/friends/MessengerRequest.ts similarity index 75% rename from src/components/friends/common/MessengerRequest.ts rename to src/api/friends/MessengerRequest.ts index 2e7dbfa2..89ceec5b 100644 --- a/src/components/friends/common/MessengerRequest.ts +++ b/src/api/friends/MessengerRequest.ts @@ -11,10 +11,10 @@ export class MessengerRequest { if(!data) return false; - this._id = data.requestId; - this._name = data.requesterName; - this._figureString = data.figureString; - this._requesterUserId = data.requesterUserId; + this._id = data.requestId; + this._name = data.requesterName; + this._figureString = data.figureString; + this._requesterUserId = data.requesterUserId; return true; } diff --git a/src/components/friends/common/MessengerSettings.ts b/src/api/friends/MessengerSettings.ts similarity index 80% rename from src/components/friends/common/MessengerSettings.ts rename to src/api/friends/MessengerSettings.ts index bc9b6f4e..e0fc8c24 100644 --- a/src/components/friends/common/MessengerSettings.ts +++ b/src/api/friends/MessengerSettings.ts @@ -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[] = []) + {} } diff --git a/src/components/friends/common/MessengerThread.ts b/src/api/friends/MessengerThread.ts similarity index 84% rename from src/components/friends/common/MessengerThread.ts rename to src/api/friends/MessengerThread.ts index a1bfe0e7..e0b0ca85 100644 --- a/src/components/friends/common/MessengerThread.ts +++ b/src/api/friends/MessengerThread.ts @@ -1,14 +1,16 @@ -import { LocalizeText } from '../../../api'; +import { LocalizeText } from '../utils'; +import { GetGroupChatData } from './GetGroupChatData'; import { GroupType } from './GroupType'; import { MessengerFriend } from './MessengerFriend'; import { MessengerThreadChat } from './MessengerThreadChat'; import { MessengerThreadChatGroup } from './MessengerThreadChatGroup'; -import { getGroupChatData } from './Utils'; export class MessengerThread { public static MESSAGE_RECEIVED: string = 'MT_MESSAGE_RECEIVED'; + public static THREAD_ID: number = 0; + private _threadId: number; private _participant: MessengerFriend; private _groups: MessengerThreadChatGroup[]; private _lastUpdated: Date; @@ -16,6 +18,7 @@ export class MessengerThread constructor(participant: MessengerFriend, isNew: boolean = true) { + this._threadId = ++MessengerThread.THREAD_ID; this._participant = participant; this._groups = []; this._lastUpdated = new Date(); @@ -32,7 +35,7 @@ export class MessengerThread public addMessage(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0): MessengerThreadChat { const isGroupChat = (senderId < 0 && extraData); - const userId = isGroupChat ? getGroupChatData(extraData).userId : senderId; + const userId = isGroupChat ? GetGroupChatData(extraData).userId : senderId; const group = this.getLastGroup(userId); @@ -45,6 +48,7 @@ export class MessengerThread group.addChat(chat); this._lastUpdated = new Date(); + this._unreadCount++; return chat; @@ -68,6 +72,11 @@ export class MessengerThread this._unreadCount = 0; } + public get threadId(): number + { + return this._threadId; + } + public get participant(): MessengerFriend { return this._participant; @@ -90,6 +99,6 @@ export class MessengerThread public get unread(): boolean { - return this._unreadCount > 0; + return (this._unreadCount > 0); } } diff --git a/src/components/friends/common/MessengerThreadChat.ts b/src/api/friends/MessengerThreadChat.ts similarity index 100% rename from src/components/friends/common/MessengerThreadChat.ts rename to src/api/friends/MessengerThreadChat.ts diff --git a/src/components/friends/common/MessengerThreadChatGroup.ts b/src/api/friends/MessengerThreadChatGroup.ts similarity index 100% rename from src/components/friends/common/MessengerThreadChatGroup.ts rename to src/api/friends/MessengerThreadChatGroup.ts diff --git a/src/api/friends/OpenMessengerChat.ts b/src/api/friends/OpenMessengerChat.ts index 37e0bc3c..7573bafb 100644 --- a/src/api/friends/OpenMessengerChat.ts +++ b/src/api/friends/OpenMessengerChat.ts @@ -2,6 +2,6 @@ import { CreateLinkEvent } from '..'; export function OpenMessengerChat(friendId: number = 0): void { - if(friendId === 0) CreateLinkEvent('friends/messenger/open'); - else CreateLinkEvent(`friends/messenger/${friendId}`); + if(friendId === 0) CreateLinkEvent('friends-messenger/open'); + else CreateLinkEvent(`friends-messenger/${ friendId }`); } diff --git a/src/api/friends/index.ts b/src/api/friends/index.ts index ffb458ee..da3d2c64 100644 --- a/src/api/friends/index.ts +++ b/src/api/friends/index.ts @@ -1 +1,11 @@ +export * from './GetGroupChatData'; +export * from './GroupType'; +export * from './IGroupChatData'; +export * from './MessengerFriend'; +export * from './MessengerIconState'; +export * from './MessengerRequest'; +export * from './MessengerSettings'; +export * from './MessengerThread'; +export * from './MessengerThreadChat'; +export * from './MessengerThreadChatGroup'; export * from './OpenMessengerChat'; diff --git a/src/api/groups/GetGroupManager.ts b/src/api/groups/GetGroupManager.ts index bd5a6c70..d372ace2 100644 --- a/src/api/groups/GetGroupManager.ts +++ b/src/api/groups/GetGroupManager.ts @@ -2,5 +2,5 @@ import { CreateLinkEvent } from '..'; export function GetGroupManager(groupId: number): void { - CreateLinkEvent(`groups/manage/${groupId}`); + CreateLinkEvent(`groups/manage/${ groupId }`); } diff --git a/src/components/hc-center/common/ClubStatus.ts b/src/api/hc-center/ClubStatus.ts similarity index 100% rename from src/components/hc-center/common/ClubStatus.ts rename to src/api/hc-center/ClubStatus.ts diff --git a/src/api/hc-center/GetClubBadge.ts b/src/api/hc-center/GetClubBadge.ts new file mode 100644 index 00000000..6b779e0f --- /dev/null +++ b/src/api/hc-center/GetClubBadge.ts @@ -0,0 +1,11 @@ +const DEFAULT_BADGE: string = 'HC1'; +const BADGES: string[] = [ 'ACH_VipHC1', 'ACH_VipHC2', 'ACH_VipHC3', 'ACH_VipHC4', 'ACH_VipHC5', 'HC1', 'HC2', 'HC3', 'HC4', 'HC5' ]; + +export const GetClubBadge = (badgeCodes: string[]) => +{ + let badgeCode: string = null; + + BADGES.forEach(badge => ((badgeCodes.indexOf(badge) > -1) && (badgeCode = badge))); + + return (badgeCode || DEFAULT_BADGE); +} diff --git a/src/api/hc-center/index.ts b/src/api/hc-center/index.ts new file mode 100644 index 00000000..cee8f692 --- /dev/null +++ b/src/api/hc-center/index.ts @@ -0,0 +1,2 @@ +export * from './ClubStatus'; +export * from './GetClubBadge'; diff --git a/src/api/index.ts b/src/api/index.ts index 9ec673e9..d3473996 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,11 +1,14 @@ export * from './achievements'; export * from './campaign'; -export * from './common'; +export * from './catalog'; export * from './core'; export * from './friends'; export * from './GetRendererVersion'; export * from './GetUIVersion'; export * from './groups'; +export * from './hc-center'; +export * from './inventory'; +export * from './inventory/unseen'; export * from './navigator'; export * from './nitro'; export * from './nitro/avatar'; @@ -17,6 +20,7 @@ export * from './nitro/room/widgets/handlers'; export * from './nitro/room/widgets/messages'; export * from './nitro/session'; export * from './notification'; +export * from './purse'; export * from './user'; export * from './utils'; export * from './wired'; diff --git a/src/components/inventory/common/FurniCategory.ts b/src/api/inventory/FurniCategory.ts similarity index 100% rename from src/components/inventory/common/FurniCategory.ts rename to src/api/inventory/FurniCategory.ts diff --git a/src/components/inventory/common/FurnitureItem.ts b/src/api/inventory/FurnitureItem.ts similarity index 76% rename from src/components/inventory/common/FurnitureItem.ts rename to src/api/inventory/FurnitureItem.ts index 0cf0d457..dc055010 100644 --- a/src/components/inventory/common/FurnitureItem.ts +++ b/src/api/inventory/FurnitureItem.ts @@ -1,6 +1,6 @@ import { IFurnitureItemData, IObjectData } from '@nitrots/nitro-renderer'; -import { GetNitroInstance } from '../../../api'; -import { IFurnitureItem } from './IFurnitureItem'; +import { IFurnitureItem } from '.'; +import { GetNitroInstance } from '..'; export class FurnitureItem implements IFurnitureItem { @@ -31,28 +31,28 @@ export class FurnitureItem implements IFurnitureItem { if(!parser) return; - this._locked = false; - this._id = parser.itemId; - this._type = parser.spriteId; - this._ref = parser.ref; - this._category = parser.category; - this._groupable = ((parser.isGroupable) && (!(parser.rentable))); - this._tradeable = parser.tradable; - this._recyclable = parser.isRecycleable; - this._sellable = parser.sellable; - this._stuffData = parser.stuffData; - this._extra = parser.extra; - this._secondsToExpiration = parser.secondsToExpiration; - this._expirationTimeStamp = parser.expirationTimeStamp; - this._hasRentPeriodStarted = parser.hasRentPeriodStarted; - this._creationDay = parser.creationDay; - this._creationMonth = parser.creationMonth; - this._creationYear = parser.creationYear; - this._slotId = parser.slotId; - this._songId = parser.songId; - this._flatId = parser.flatId; - this._isRented = parser.rentable; - this._isWallItem = parser.isWallItem; + this._locked = false; + this._id = parser.itemId; + this._type = parser.spriteId; + this._ref = parser.ref; + this._category = parser.category; + this._groupable = ((parser.isGroupable) && (!(parser.rentable))); + this._tradeable = parser.tradable; + this._recyclable = parser.isRecycleable; + this._sellable = parser.sellable; + this._stuffData = parser.stuffData; + this._extra = parser.extra; + this._secondsToExpiration = parser.secondsToExpiration; + this._expirationTimeStamp = parser.expirationTimeStamp; + this._hasRentPeriodStarted = parser.hasRentPeriodStarted; + this._creationDay = parser.creationDay; + this._creationMonth = parser.creationMonth; + this._creationYear = parser.creationYear; + this._slotId = parser.slotId; + this._songId = parser.songId; + this._flatId = parser.flatId; + this._isRented = parser.rentable; + this._isWallItem = parser.isWallItem; } public get rentable(): boolean @@ -95,7 +95,7 @@ export class FurnitureItem implements IFurnitureItem return this._extra; } - public get _Str_16260(): boolean + public get recyclable(): boolean { return this._recyclable; } @@ -135,17 +135,17 @@ export class FurnitureItem implements IFurnitureItem return time; } - public get _Str_8932(): number + public get creationDay(): number { return this._creationDay; } - public get _Str_9050(): number + public get creationMonth(): number { return this._creationMonth; } - public get _Str_9408(): number + public get creationYear(): number { return this._creationYear; } @@ -155,7 +155,7 @@ export class FurnitureItem implements IFurnitureItem return this._slotId; } - public get _Str_3951(): number + public get songId(): number { return this._songId; } @@ -185,7 +185,7 @@ export class FurnitureItem implements IFurnitureItem return this._hasRentPeriodStarted; } - public get _Str_10616(): number + public get expirationTimeStamp(): number { return this._expirationTimeStamp; } diff --git a/src/api/inventory/FurnitureUtilities.ts b/src/api/inventory/FurnitureUtilities.ts new file mode 100644 index 00000000..741f1ea1 --- /dev/null +++ b/src/api/inventory/FurnitureUtilities.ts @@ -0,0 +1,172 @@ +import { FurnitureListItemParser, IObjectData } from '@nitrots/nitro-renderer'; +import { GetRoomEngine } from '../nitro'; +import { FurniCategory } from './FurniCategory'; +import { FurnitureItem } from './FurnitureItem'; +import { GroupItem } from './GroupItem'; + +export const createGroupItem = (type: number, category: number, stuffData: IObjectData, extra: number = NaN) => new GroupItem(type, category, GetRoomEngine(), stuffData, extra); + +const addSingleFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => +{ + const groupItems: GroupItem[] = []; + + for(const groupItem of set) + { + if(groupItem.type === item.type) groupItems.push(groupItem); + } + + for(const groupItem of groupItems) + { + if(groupItem.getItemById(item.id)) return groupItem; + } + + const groupItem = createGroupItem(item.type, item.category, item.stuffData, item.extra); + + groupItem.push(item); + + if(unseen) + { + groupItem.hasUnseenItems = true; + + set.unshift(groupItem); + } + else + { + set.push(groupItem); + } + + return groupItem; +} + +const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => +{ + let existingGroup: GroupItem = null; + + for(const groupItem of set) + { + if((groupItem.type === item.type) && (groupItem.isWallItem === item.isWallItem) && groupItem.isGroupable) + { + if(item.category === FurniCategory.POSTER) + { + if(groupItem.stuffData.getLegacyString() === item.stuffData.getLegacyString()) + { + existingGroup = groupItem; + + break; + } + } + + else if(item.category === FurniCategory.GUILD_FURNI) + { + if(item.stuffData.compare(groupItem.stuffData)) + { + existingGroup = groupItem; + + break; + } + } + + else + { + existingGroup = groupItem; + + break; + } + } + } + + if(existingGroup) + { + existingGroup.push(item); + + if(unseen) + { + existingGroup.hasUnseenItems = true; + + const index = set.indexOf(existingGroup); + + if(index >= 0) set.splice(index, 1); + + set.unshift(existingGroup); + } + + return existingGroup; + } + + existingGroup = createGroupItem(item.type, item.category, item.stuffData, item.extra); + + existingGroup.push(item); + + if(unseen) + { + existingGroup.hasUnseenItems = true; + + set.unshift(existingGroup); + } + else + { + set.push(existingGroup); + } + + return existingGroup; +} + +export const addFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => +{ + if(!item.isGroupable) + { + addSingleFurnitureItem(set, item, unseen); + } + else + { + addGroupableFurnitureItem(set, item, unseen); + } +} + +export const mergeFurniFragments = (fragment: Map, totalFragments: number, fragmentNumber: number, fragments: Map[]) => +{ + if(totalFragments === 1) return fragment; + + fragments[fragmentNumber] = fragment; + + for(const frag of fragments) + { + if(!frag) return null; + } + + const merged: Map = new Map(); + + for(const frag of fragments) + { + for(const [ key, value ] of frag) merged.set(key, value); + + frag.clear(); + } + + fragments = null; + + return merged; +} + +export const getAllItemIds = (groupItems: GroupItem[]) => +{ + const itemIds: number[] = []; + + for(const groupItem of groupItems) + { + let totalCount = groupItem.getTotalCount(); + + if(groupItem.category === FurniCategory.POST_IT) totalCount = 1; + + let i = 0; + + while(i < totalCount) + { + itemIds.push(groupItem.getItemByIndex(i).id); + + i++; + } + } + + return itemIds; +} diff --git a/src/components/inventory/common/GroupItem.ts b/src/api/inventory/GroupItem.ts similarity index 97% rename from src/components/inventory/common/GroupItem.ts rename to src/api/inventory/GroupItem.ts index 2b3598a4..96477f92 100644 --- a/src/components/inventory/common/GroupItem.ts +++ b/src/api/inventory/GroupItem.ts @@ -1,5 +1,5 @@ import { IObjectData, IRoomEngine } from '@nitrots/nitro-renderer'; -import { LocalizeText } from '../../../api'; +import { LocalizeText } from '..'; import { FurniCategory } from './FurniCategory'; import { FurnitureItem } from './FurnitureItem'; import { IFurnitureItem } from './IFurnitureItem'; @@ -95,8 +95,8 @@ export class GroupItem if(!furnitureItem) return items; - let found = 0; - let i = 0; + let found = 0; + let i = 0; while(i < this._items.length) { @@ -201,8 +201,8 @@ export class GroupItem { if(this._category === FurniCategory.POST_IT) { - let count = 0; - let index = 0; + let count = 0; + let index = 0; while(index < this._items.length) { @@ -281,8 +281,8 @@ export class GroupItem while(index < items.length) { - const item = items[index]; - const locked = (itemIds.indexOf(item.ref) >= 0); + const item = items[index]; + const locked = (itemIds.indexOf(item.ref) >= 0); if(item.locked !== locked) { diff --git a/src/api/inventory/IBotItem.ts b/src/api/inventory/IBotItem.ts new file mode 100644 index 00000000..0a370ba6 --- /dev/null +++ b/src/api/inventory/IBotItem.ts @@ -0,0 +1,6 @@ +import { BotData } from '@nitrots/nitro-renderer'; + +export interface IBotItem +{ + botData: BotData; +} diff --git a/src/components/inventory/common/IFurnitureItem.ts b/src/api/inventory/IFurnitureItem.ts similarity index 92% rename from src/components/inventory/common/IFurnitureItem.ts rename to src/api/inventory/IFurnitureItem.ts index 7e030c52..435597d2 100644 --- a/src/components/inventory/common/IFurnitureItem.ts +++ b/src/api/inventory/IFurnitureItem.ts @@ -8,7 +8,7 @@ export interface IFurnitureItem stuffData: IObjectData; extra: number; category: number; - _Str_16260: boolean; + recyclable: boolean; isTradable: boolean; isGroupable: boolean; sellable: boolean; diff --git a/src/api/inventory/IPetItem.ts b/src/api/inventory/IPetItem.ts new file mode 100644 index 00000000..910d5dff --- /dev/null +++ b/src/api/inventory/IPetItem.ts @@ -0,0 +1,6 @@ +import { PetData } from '@nitrots/nitro-renderer'; + +export interface IPetItem +{ + petData: PetData; +} diff --git a/src/api/inventory/InventoryUtilities.ts b/src/api/inventory/InventoryUtilities.ts new file mode 100644 index 00000000..2dae7d84 --- /dev/null +++ b/src/api/inventory/InventoryUtilities.ts @@ -0,0 +1,116 @@ +import { FurniturePlacePaintComposer, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer'; +import { FurniCategory, GroupItem } from '.'; +import { CreateLinkEvent, GetRoomEngine, GetRoomSessionManager, SendMessageComposer } from '..'; +import { IBotItem } from './IBotItem'; +import { IPetItem } from './IPetItem'; + +let objectMoverRequested = false; +let itemIdInPlacing = -1; + +export const isObjectMoverRequested = () => objectMoverRequested; + +export const setObjectMoverRequested = (flag: boolean) => objectMoverRequested = flag; + +export const getPlacingItemId = () => itemIdInPlacing; + +export const setPlacingItemId = (id: number) => (itemIdInPlacing = id); + +export const cancelRoomObjectPlacement = () => +{ + if(getPlacingItemId() === -1) return; + + GetRoomEngine().cancelRoomObjectPlacement(); + + setPlacingItemId(-1); + setObjectMoverRequested(false); +} + +export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) => +{ + const petData = petItem.petData; + + if(!petData) return false; + + const session = GetRoomSessionManager().getSession(1); + + if(!session) return false; + + if(!session.isRoomOwner && !session.allowPets) return false; + + CreateLinkEvent('inventory/hide'); + + if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, -(petData.id), RoomObjectCategory.UNIT, RoomObjectType.PET, petData.figureData.figuredata)) + { + setPlacingItemId(petData.id); + setObjectMoverRequested(true); + } + + return true; +} + +export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false) => +{ + if(!groupItem || !groupItem.getUnlockedCount()) return false; + + const item = groupItem.getLastItem(); + + if(!item) return false; + + if((item.category === FurniCategory.FLOOR) || (item.category === FurniCategory.WALL_PAPER) || (item.category === FurniCategory.LANDSCAPE)) + { + if(flag) return false; + + SendMessageComposer(new FurniturePlacePaintComposer(item.id)); + + return false; + } + else + { + CreateLinkEvent('inventory/hide'); + + let category = 0; + let isMoving = false; + + if(item.isWallItem) category = RoomObjectCategory.WALL; + else category = RoomObjectCategory.FLOOR; + + if((item.category === FurniCategory.POSTER)) // or external image from furnidata + { + isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.stuffData.getLegacyString()); + } + else + { + isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.extra.toString(), item.stuffData); + } + + if(isMoving) + { + setPlacingItemId(item.ref); + setObjectMoverRequested(true); + } + } + + return true; +} + + +export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) => +{ + const botData = botItem.botData; + + if(!botData) return false; + + const session = GetRoomSessionManager().getSession(1); + + if(!session || !session.isRoomOwner) return false; + + CreateLinkEvent('inventory/hide'); + + if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, -(botData.id), RoomObjectCategory.UNIT, RoomObjectType.RENTABLE_BOT, botData.figure)) + { + setPlacingItemId(botData.id); + setObjectMoverRequested(true); + } + + return true; +} diff --git a/src/api/inventory/PetUtilities.ts b/src/api/inventory/PetUtilities.ts new file mode 100644 index 00000000..871eb538 --- /dev/null +++ b/src/api/inventory/PetUtilities.ts @@ -0,0 +1,104 @@ +import { PetData } from '@nitrots/nitro-renderer'; +import { CreateLinkEvent } from '../nitro'; +import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities'; +import { IPetItem } from './IPetItem'; +import { UnseenItemCategory } from './unseen'; + +export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id); + +export const addSinglePetItem = (petData: PetData, set: IPetItem[], unseen: boolean = true) => +{ + const petItem = { petData }; + + if(unseen) + { + //petItem.isUnseen = true; + + set.unshift(petItem); + } + else + { + set.push(petItem); + } + + return petItem; +} + +export const removePetItemById = (id: number, set: IPetItem[]) => +{ + let index = 0; + + while(index < set.length) + { + const petItem = set[index]; + + if(petItem && (petItem.petData.id === id)) + { + if(getPlacingItemId() === petItem.petData.id) + { + cancelRoomObjectPlacement(); + + CreateLinkEvent('inventory/open'); + } + + set.splice(index, 1); + + return petItem; + } + + index++; + } + + return null; +} + +export const processPetFragment = (set: IPetItem[], fragment: Map, isUnseen: (category: number, itemId: number) => boolean) => +{ + const existingIds = getAllPetIds(set); + const addedIds: number[] = []; + const removedIds: number[] = []; + + for(const key of fragment.keys()) (existingIds.indexOf(key) === -1) && addedIds.push(key); + + for(const itemId of existingIds) (!fragment.get(itemId)) && removedIds.push(itemId); + + const emptyExistingSet = (existingIds.length === 0); + + for(const id of removedIds) removePetItemById(id, set); + + for(const id of addedIds) + { + const parser = fragment.get(id); + + if(!parser) continue; + + addSinglePetItem(parser, set, isUnseen(UnseenItemCategory.PET, parser.id)); + } + + return set; +} + +export const mergePetFragments = (fragment: Map, totalFragments: number, fragmentNumber: number, fragments: Map[]) => +{ + if(totalFragments === 1) return fragment; + + fragments[fragmentNumber] = fragment; + + for(const frag of fragments) + { + if(!frag) return null; + } + + const merged: Map = new Map(); + + for(const frag of fragments) + { + for(const [ key, value ] of frag) merged.set(key, value); + + frag.clear(); + } + + fragments = null; + + return merged; +} diff --git a/src/api/inventory/TradeState.ts b/src/api/inventory/TradeState.ts new file mode 100644 index 00000000..3df418ba --- /dev/null +++ b/src/api/inventory/TradeState.ts @@ -0,0 +1,10 @@ +export class TradeState +{ + public static TRADING_STATE_READY: number = 0; + public static TRADING_STATE_RUNNING: number = 1; + public static TRADING_STATE_COUNTDOWN: number = 2; + public static TRADING_STATE_CONFIRMING: number = 3; + public static TRADING_STATE_CONFIRMED: number = 4; + public static TRADING_STATE_COMPLETED: number = 5; + public static TRADING_STATE_CANCELLED: number = 6; +} diff --git a/src/components/inventory/common/TradeUserData.ts b/src/api/inventory/TradeUserData.ts similarity index 64% rename from src/components/inventory/common/TradeUserData.ts rename to src/api/inventory/TradeUserData.ts index b0b337b3..452c7ee5 100644 --- a/src/components/inventory/common/TradeUserData.ts +++ b/src/api/inventory/TradeUserData.ts @@ -6,10 +6,10 @@ export class TradeUserData constructor( public userId: number = -1, public userName: string = '', - public userItems: AdvancedMap = null, + public userItems: AdvancedMap = new AdvancedMap(), public itemCount: number = 0, public creditsCount: number = 0, public accepts: boolean = false, - public canTrade: boolean = false, - public items: AdvancedMap = new AdvancedMap()) {} + public canTrade: boolean = false) + {} } diff --git a/src/components/inventory/common/TradingNotificationMessage.ts b/src/api/inventory/TradingNotificationMessage.ts similarity index 51% rename from src/components/inventory/common/TradingNotificationMessage.ts rename to src/api/inventory/TradingNotificationMessage.ts index 4931fd5c..eb0ecfac 100644 --- a/src/components/inventory/common/TradingNotificationMessage.ts +++ b/src/api/inventory/TradingNotificationMessage.ts @@ -1,28 +1,26 @@ -import { LocalizeText, NotificationUtilities } from '../../../api'; +import { LocalizeText, NotificationUtilities } from '..'; import { TradingNotificationType } from './TradingNotificationType'; -export const TradingNotificationMessage = (type: number) => +export const TradingNotificationMessage = (type: number, otherUsername: string = '') => { switch(type) { case TradingNotificationType.ALERT_SCAM: NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.warning.other_not_offering'), null, null, null, LocalizeText('inventory.trading.notification.title')); return; - case TradingNotificationType.ALERT_OTHER_CANCELLED: - NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.info.closed'), null, null, null, LocalizeText('inventory.trading.notification.title')); - return; - case TradingNotificationType.ALERT_ALREADY_OPEN: - NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.info.already_open'), null, null, null, LocalizeText('inventory.trading.notification.title')); - return; - case TradingNotificationType.ALERT_OTHER_DISABLED: - NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.warning.others_account_disabled'), null, null, null, LocalizeText('inventory.trading.notification.title')); + case TradingNotificationType.HOTEL_TRADING_DISABLED: + case TradingNotificationType.YOU_NOT_ALLOWED: + case TradingNotificationType.THEY_NOT_ALLOWED: + case TradingNotificationType.ROOM_DISABLED: + case TradingNotificationType.YOU_OPEN: + case TradingNotificationType.THEY_OPEN: + NotificationUtilities.simpleAlert(LocalizeText(`inventory.trading.openfail.${ type }`, [ 'otherusername' ], [ otherUsername ]), null, null, null, LocalizeText('inventory.trading.openfail.title')); return; case TradingNotificationType.ERROR_WHILE_COMMIT: NotificationUtilities.simpleAlert(`${ LocalizeText('inventory.trading.notification.caption') }, ${ LocalizeText('inventory.trading.notification.commiterror.info') }`, null, null, null, LocalizeText('inventory.trading.notification.title')); return; - case TradingNotificationType.YOU_NOT_ALLOWED: - NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.warning.own_account_disabled'), null, null, null, LocalizeText('inventory.trading.notification.title')); + case TradingNotificationType.THEY_CANCELLED: + NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.info.closed'), null, null, null, LocalizeText('inventory.trading.notification.title')); return; - } } diff --git a/src/api/inventory/TradingNotificationType.ts b/src/api/inventory/TradingNotificationType.ts new file mode 100644 index 00000000..4aed4905 --- /dev/null +++ b/src/api/inventory/TradingNotificationType.ts @@ -0,0 +1,12 @@ +export class TradingNotificationType +{ + public static ALERT_SCAM: number = 0; + public static HOTEL_TRADING_DISABLED = 1; + public static YOU_NOT_ALLOWED: number = 2; + public static THEY_NOT_ALLOWED: number = 4; + public static ROOM_DISABLED: number = 6; + public static YOU_OPEN: number = 7; + public static THEY_OPEN: number = 8; + public static ERROR_WHILE_COMMIT: number = 9; + public static THEY_CANCELLED: number = 10; +} diff --git a/src/api/inventory/TradingUtilities.ts b/src/api/inventory/TradingUtilities.ts new file mode 100644 index 00000000..28ca8c88 --- /dev/null +++ b/src/api/inventory/TradingUtilities.ts @@ -0,0 +1,71 @@ +import { AdvancedMap, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer'; +import { GetSessionDataManager } from '../nitro'; +import { FurniCategory } from './FurniCategory'; +import { FurnitureItem } from './FurnitureItem'; +import { createGroupItem } from './FurnitureUtilities'; +import { GroupItem } from './GroupItem'; + +const isExternalImage = (spriteId: number) => GetSessionDataManager().getWallItemData(spriteId)?.isExternalImage || false; + +export const parseTradeItems = (items: ItemDataStructure[]) => +{ + const existingItems = new AdvancedMap(); + const totalItems = items.length; + + if(totalItems) + { + for(const item of items) + { + const spriteId = item.spriteId; + const category = item.category; + + let name = (item.furniType + spriteId); + + if(!item.isGroupable || isExternalImage(spriteId)) + { + name = ('itemid' + item.itemId); + } + + if(item.category === FurniCategory.POSTER) + { + name = (item.itemId + 'poster' + item.stuffData.getLegacyString()); + } + + else if(item.category === FurniCategory.GUILD_FURNI) + { + name = ''; + } + + let groupItem = ((item.isGroupable && !isExternalImage(item.spriteId)) ? existingItems.getValue(name) : null); + + if(!groupItem) + { + groupItem = createGroupItem(spriteId, category, item.stuffData); + + existingItems.add(name, groupItem); + } + + groupItem.push(new FurnitureItem(item)); + } + } + + return existingItems; +} + +export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) => +{ + let type = spriteId.toString(); + + if(!(stuffData instanceof StringDataType)) return type; + + let i = 1; + + while(i < 5) + { + type = (type + (',' + stuffData.getValue(i))); + + i++; + } + + return type; +} diff --git a/src/api/inventory/index.ts b/src/api/inventory/index.ts new file mode 100644 index 00000000..de840525 --- /dev/null +++ b/src/api/inventory/index.ts @@ -0,0 +1,15 @@ +export * from './FurniCategory'; +export * from './FurnitureItem'; +export * from './FurnitureUtilities'; +export * from './GroupItem'; +export * from './IBotItem'; +export * from './IFurnitureItem'; +export * from './InventoryUtilities'; +export * from './IPetItem'; +export * from './PetUtilities'; +export * from './TradeState'; +export * from './TradeUserData'; +export * from './TradingNotificationMessage'; +export * from './TradingNotificationType'; +export * from './TradingUtilities'; +export * from './unseen'; diff --git a/src/components/inventory/common/unseen/IUnseenItemTracker.ts b/src/api/inventory/unseen/IUnseenItemTracker.ts similarity index 89% rename from src/components/inventory/common/unseen/IUnseenItemTracker.ts rename to src/api/inventory/unseen/IUnseenItemTracker.ts index 51872a00..8a70a166 100644 --- a/src/components/inventory/common/unseen/IUnseenItemTracker.ts +++ b/src/api/inventory/unseen/IUnseenItemTracker.ts @@ -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[]; diff --git a/src/api/inventory/unseen/UnseenItemCategory.ts b/src/api/inventory/unseen/UnseenItemCategory.ts new file mode 100644 index 00000000..cbd7e9b7 --- /dev/null +++ b/src/api/inventory/unseen/UnseenItemCategory.ts @@ -0,0 +1,9 @@ +export class UnseenItemCategory +{ + public static FURNI: number = 1; + public static RENTABLE: number = 2; + public static PET: number = 3; + public static BADGE: number = 4; + public static BOT: number = 5; + public static GAMES: number = 6; +} diff --git a/src/api/inventory/unseen/index.ts b/src/api/inventory/unseen/index.ts new file mode 100644 index 00000000..31936cbd --- /dev/null +++ b/src/api/inventory/unseen/index.ts @@ -0,0 +1,2 @@ +export * from './IUnseenItemTracker'; +export * from './UnseenItemCategory'; diff --git a/src/api/navigator/IRoomChatSettings.ts b/src/api/navigator/IRoomChatSettings.ts new file mode 100644 index 00000000..aee426cb --- /dev/null +++ b/src/api/navigator/IRoomChatSettings.ts @@ -0,0 +1,8 @@ +export interface IRoomChatSettings +{ + mode: number; + weight: number; + speed: number; + distance: number; + protection: number; +} diff --git a/src/api/navigator/IRoomData.ts b/src/api/navigator/IRoomData.ts new file mode 100644 index 00000000..91463147 --- /dev/null +++ b/src/api/navigator/IRoomData.ts @@ -0,0 +1,23 @@ +import { IRoomChatSettings } from './IRoomChatSettings'; +import { IRoomModerationSettings } from './IRoomModerationSettings'; + +export interface IRoomData +{ + roomId: number; + roomName: string; + roomDescription: string; + categoryId: number; + userCount: number; + tags: string[]; + tradeState: number; + allowWalkthrough: boolean; + lockState: number; + password: string; + allowPets: boolean; + allowPetsEat: boolean; + hideWalls: boolean; + wallThickness: number; + floorThickness: number; + chatSettings: IRoomChatSettings; + moderationSettings: IRoomModerationSettings; +} diff --git a/src/api/navigator/IRoomModel.ts b/src/api/navigator/IRoomModel.ts new file mode 100644 index 00000000..73dfe278 --- /dev/null +++ b/src/api/navigator/IRoomModel.ts @@ -0,0 +1,6 @@ +export interface IRoomModel +{ + clubLevel: number; + tileSize: number; + name: string; +} diff --git a/src/api/navigator/IRoomModerationSettings.ts b/src/api/navigator/IRoomModerationSettings.ts new file mode 100644 index 00000000..266fe478 --- /dev/null +++ b/src/api/navigator/IRoomModerationSettings.ts @@ -0,0 +1,6 @@ +export interface IRoomModerationSettings +{ + allowMute: number; + allowKick: number; + allowBan: number; +} diff --git a/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts b/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts index 27069cfd..b532d1af 100644 --- a/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts +++ b/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts @@ -1,6 +1,6 @@ export class NavigatorSearchResultViewDisplayMode { - public static readonly LIST: number = 0; - public static readonly THUMBNAILS: number = 1; - public static readonly FORCED_THUMBNAILS: number = 2; + public static readonly LIST: number = 0; + public static readonly THUMBNAILS: number = 1; + public static readonly FORCED_THUMBNAILS: number = 2; } diff --git a/src/api/navigator/RoomModels.ts b/src/api/navigator/RoomModels.ts deleted file mode 100644 index c2b40066..00000000 --- a/src/api/navigator/RoomModels.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { HabboClubLevelEnum } from '@nitrots/nitro-renderer'; - -export interface IRoomModel -{ - clubLevel: number; - tileSize: number; - name: string; -} - -export const RoomModels: IRoomModel[] = [ - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 104, name: 'a' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 94, name: 'b' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 36, name: 'c' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 84, name: 'd' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 80, name: 'e' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 80, name: 'f' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 416, name: 'i' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 320, name: 'j' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 448, name: 'k' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 352, name: 'l' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 384, name: 'm' }, - { clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 372, name: 'n' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 80, name: 'g' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 74, name: 'h' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 416, name: 'o' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 352, name: 'p' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 304, name: 'q' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 336, name: 'r' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 748, name: 'u' }, - { clubLevel: HabboClubLevelEnum.CLUB, tileSize: 438, name: 'v' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 540, name: 't' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 512, name: 'w' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 396, name: 'x' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 440, name: 'y' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 456, name: 'z' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 208, name: '0' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 1009, name: '1' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 1044, name: '2' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 183, name: '3' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 254, name: '4' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 1024, name: '5' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 801, name: '6' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 354, name: '7' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 888, name: '8' }, - { clubLevel: HabboClubLevelEnum.VIP, tileSize: 926, name: '9' } -]; diff --git a/src/api/navigator/RoomSettingsData.ts b/src/api/navigator/RoomSettingsData.ts index cc6f7996..84cce5ae 100644 --- a/src/api/navigator/RoomSettingsData.ts +++ b/src/api/navigator/RoomSettingsData.ts @@ -40,37 +40,37 @@ export class RoomSettingsData { if(!parser) throw new Error('invalid_parser'); - this.roomId = parser.roomId; - this.roomName = parser.name; - this.roomOriginalName = parser.name; - this.roomDescription = parser.description; - this.categoryId = parser.categoryId; - this.userCount = parser.userCount; - this.tags = parser.tags; - this.tradeState = parser.tradeMode; - this.allowWalkthrough = parser.allowWalkthrough; + this.roomId = parser.roomId; + this.roomName = parser.name; + this.roomOriginalName = parser.name; + this.roomDescription = parser.description; + this.categoryId = parser.categoryId; + this.userCount = parser.userCount; + this.tags = parser.tags; + this.tradeState = parser.tradeMode; + this.allowWalkthrough = parser.allowWalkthrough; - this.lockState = parser.state; - this.originalLockState = parser.state; - this.password = null; - this.confirmPassword = null; - this.allowPets = parser.allowPets; - this.allowPetsEat = parser.allowPetsEat; + this.lockState = parser.state; + this.originalLockState = parser.state; + this.password = null; + this.confirmPassword = null; + this.allowPets = parser.allowPets; + this.allowPetsEat = parser.allowPetsEat; - this.usersWithRights = new Map(); + this.usersWithRights = new Map(); - this.hideWalls = parser.hideWalls; - this.wallThickness = parser.thicknessWall; - this.floorThickness = parser.thicknessFloor; - this.chatBubbleMode = parser.chatSettings.mode; - this.chatBubbleWeight = parser.chatSettings.weight; - this.chatBubbleSpeed = parser.chatSettings.speed; - this.chatFloodProtection = parser.chatSettings.protection; - this.chatDistance = parser.chatSettings.distance; + this.hideWalls = parser.hideWalls; + this.wallThickness = parser.thicknessWall; + this.floorThickness = parser.thicknessFloor; + this.chatBubbleMode = parser.chatSettings.mode; + this.chatBubbleWeight = parser.chatSettings.weight; + this.chatBubbleSpeed = parser.chatSettings.speed; + this.chatFloodProtection = parser.chatSettings.protection; + this.chatDistance = parser.chatSettings.distance; - this.muteState = parser.moderationSettings.allowMute; - this.kickState = parser.moderationSettings.allowKick; - this.banState = parser.moderationSettings.allowBan; - this.bannedUsers = []; + this.muteState = parser.moderationSettings.allowMute; + this.kickState = parser.moderationSettings.allowKick; + this.banState = parser.moderationSettings.allowBan; + this.bannedUsers = []; } } diff --git a/src/api/navigator/index.ts b/src/api/navigator/index.ts index f913250d..77b0a417 100644 --- a/src/api/navigator/index.ts +++ b/src/api/navigator/index.ts @@ -1,9 +1,12 @@ export * from './DoorStateType'; export * from './INavigatorData'; export * from './INavigatorSearchFilter'; +export * from './IRoomChatSettings'; +export * from './IRoomData'; +export * from './IRoomModel'; +export * from './IRoomModerationSettings'; export * from './NavigatorSearchResultViewDisplayMode'; export * from './RoomInfoData'; -export * from './RoomModels'; export * from './RoomSettingsData'; export * from './RoomSettingsUtils'; export * from './SearchFilterOptions'; diff --git a/src/api/nitro/AddWorkerEventTracker.ts b/src/api/nitro/AddWorkerEventTracker.ts new file mode 100644 index 00000000..0d81670b --- /dev/null +++ b/src/api/nitro/AddWorkerEventTracker.ts @@ -0,0 +1,7 @@ +import { IWorkerEventTracker } from '@nitrots/nitro-renderer'; +import { GetNitroInstance } from './GetNitroInstance'; + +export const AddWorkerEventTracker = (tracker: IWorkerEventTracker) => +{ + GetNitroInstance().addWorkerEventTracker(tracker); +} diff --git a/src/api/nitro/RemoveWorkerEventTracker.ts b/src/api/nitro/RemoveWorkerEventTracker.ts new file mode 100644 index 00000000..a1307118 --- /dev/null +++ b/src/api/nitro/RemoveWorkerEventTracker.ts @@ -0,0 +1,7 @@ +import { IWorkerEventTracker } from '@nitrots/nitro-renderer'; +import { GetNitroInstance } from './GetNitroInstance'; + +export const RemoveWorkerEventTracker = (tracker: IWorkerEventTracker) => +{ + GetNitroInstance().removeWorkerEventTracker(tracker); +} diff --git a/src/api/nitro/SendWorkerEvent.ts b/src/api/nitro/SendWorkerEvent.ts new file mode 100644 index 00000000..b0e32740 --- /dev/null +++ b/src/api/nitro/SendWorkerEvent.ts @@ -0,0 +1,6 @@ +import { GetNitroInstance } from './GetNitroInstance'; + +export const SendWorkerEvent = (message: { [index: string]: any }) => +{ + GetNitroInstance().sendWorkerEvent(message); +} diff --git a/src/api/nitro/index.ts b/src/api/nitro/index.ts index 18b2de0c..3e371d5d 100644 --- a/src/api/nitro/index.ts +++ b/src/api/nitro/index.ts @@ -1,4 +1,5 @@ export * from './AddLinkEventTracker'; +export * from './AddWorkerEventTracker'; export * from './avatar'; export * from './camera'; export * from './CreateLinkEvent'; @@ -9,10 +10,12 @@ export * from './GetLocalization'; export * from './GetNitroInstance'; export * from './GetTicker'; export * from './RemoveLinkEventTracker'; +export * from './RemoveWorkerEventTracker'; export * from './room'; export * from './room/widgets'; export * from './room/widgets/events'; export * from './room/widgets/handlers'; export * from './room/widgets/messages'; export * from './SendMessageComposer'; +export * from './SendWorkerEvent'; export * from './session'; diff --git a/src/api/nitro/room/DispatchMouseEvent.ts b/src/api/nitro/room/DispatchMouseEvent.ts index 6d18f2e8..51111aca 100644 --- a/src/api/nitro/room/DispatchMouseEvent.ts +++ b/src/api/nitro/room/DispatchMouseEvent.ts @@ -1,12 +1,11 @@ import { MouseEventType } from '@nitrots/nitro-renderer'; import { GetRoomEngine } from './GetRoomEngine'; -import { SetActiveRoomId } from './SetActiveRoomId'; let didMouseMove = false; let lastClick = 0; let clickCount = 0; -export function DispatchMouseEvent(roomId: number, canvasId: number, event: MouseEvent) +export const DispatchMouseEvent = (event: MouseEvent, canvasId: number = 1) => { const x = event.clientX; const y = event.clientY; @@ -28,8 +27,8 @@ export function DispatchMouseEvent(roomId: number, canvasId: number, event: Mous { if(!didMouseMove) eventType = MouseEventType.DOUBLE_CLICK; - clickCount = 0; - lastClick = null; + clickCount = 0; + lastClick = null; } } @@ -51,7 +50,6 @@ export function DispatchMouseEvent(roomId: number, canvasId: number, event: Mous break; default: return; } - - SetActiveRoomId(roomId); + GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, event.altKey, (event.ctrlKey || event.metaKey), event.shiftKey, false); } diff --git a/src/api/nitro/room/DispatchTouchEvent.ts b/src/api/nitro/room/DispatchTouchEvent.ts index 7053318e..669fa089 100644 --- a/src/api/nitro/room/DispatchTouchEvent.ts +++ b/src/api/nitro/room/DispatchTouchEvent.ts @@ -6,7 +6,7 @@ let lastClick = 0; let clickCount = 0; let touchTimer: ReturnType = null; -export function DispatchTouchEvent(roomId: number, canvasId: number, event: TouchEvent, longTouch: boolean = false, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false) +export const DispatchTouchEvent = (event: TouchEvent, canvasId: number = 1, longTouch: boolean = false, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false) => { let eventType = event.type; @@ -29,8 +29,8 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc { eventType = MouseEventType.DOUBLE_CLICK; - clickCount = 0; - lastClick = null; + clickCount = 0; + lastClick = null; } } @@ -51,8 +51,6 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc y = event.changedTouches[0].clientY; } - GetRoomEngine().setActiveRoomId(roomId); - switch(eventType) { case MouseEventType.MOUSE_CLICK: @@ -64,7 +62,7 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc { if(didMouseMove) return; - DispatchTouchEvent(roomId, canvasId, event, true); + DispatchTouchEvent(event, canvasId, true); }, 300); eventType = MouseEventType.MOUSE_DOWN; diff --git a/src/api/nitro/room/GetRoomObjectBounds.ts b/src/api/nitro/room/GetRoomObjectBounds.ts index 1b149ce0..0a42ad65 100644 --- a/src/api/nitro/room/GetRoomObjectBounds.ts +++ b/src/api/nitro/room/GetRoomObjectBounds.ts @@ -1,7 +1,13 @@ -import { NitroRectangle } from '@nitrots/nitro-renderer'; import { GetRoomEngine } from './GetRoomEngine'; -export function GetRoomObjectBounds(roomId: number, objectId: number, category: number, canvasId = 1): NitroRectangle +export const GetRoomObjectBounds = (roomId: number, objectId: number, category: number, canvasId = 1) => { - return GetRoomEngine().getRoomObjectBoundingRectangle(roomId, objectId, category, canvasId); + const rectangle = GetRoomEngine().getRoomObjectBoundingRectangle(roomId, objectId, category, canvasId); + + if(!rectangle) return null; + + rectangle.x = Math.round(rectangle.x); + rectangle.y = Math.round(rectangle.y); + + return rectangle; } diff --git a/src/api/nitro/room/GetRoomObjectScreenLocation.ts b/src/api/nitro/room/GetRoomObjectScreenLocation.ts new file mode 100644 index 00000000..1a8d973d --- /dev/null +++ b/src/api/nitro/room/GetRoomObjectScreenLocation.ts @@ -0,0 +1,13 @@ +import { GetRoomEngine } from './GetRoomEngine'; + +export const GetRoomObjectScreenLocation = (roomId: number, objectId: number, category: number, canvasId = 1) => +{ + const point = GetRoomEngine().getRoomObjectScreenLocation(roomId, objectId, category, canvasId); + + if(!point) return null; + + point.x = Math.round(point.x); + point.y = Math.round(point.y); + + return point; +} diff --git a/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts b/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts index 342e4985..d85d739c 100644 --- a/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts +++ b/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts @@ -1,6 +1,9 @@ import { GetRoomEngine } from './GetRoomEngine'; -export function InitializeRoomInstanceRenderingCanvas(roomId: number, canvasId: number, width: number, height: number): void +export const InitializeRoomInstanceRenderingCanvas = (width: number, height: number, canvasId: number = 1) => { - GetRoomEngine().initializeRoomInstanceRenderingCanvas(roomId, canvasId, width, height); + const roomEngine = GetRoomEngine(); + const roomId = roomEngine.activeRoomId; + + roomEngine.initializeRoomInstanceRenderingCanvas(roomId, canvasId, width, height); } diff --git a/src/api/nitro/room/index.ts b/src/api/nitro/room/index.ts index 0c633afa..dace0981 100644 --- a/src/api/nitro/room/index.ts +++ b/src/api/nitro/room/index.ts @@ -3,6 +3,7 @@ export * from './DispatchTouchEvent'; export * from './GetOwnRoomObject'; export * from './GetRoomEngine'; export * from './GetRoomObjectBounds'; +export * from './GetRoomObjectScreenLocation'; export * from './InitializeRoomInstanceRenderingCanvas'; export * from './IsFurnitureSelectionDisabled'; export * from './ProcessRoomObjectOperation'; diff --git a/src/api/nitro/room/widgets/events/RoomWidgetDoorbellEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetDoorbellEvent.ts deleted file mode 100644 index 9bad7fa4..00000000 --- a/src/api/nitro/room/widgets/events/RoomWidgetDoorbellEvent.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetDoorbellEvent extends RoomWidgetUpdateEvent -{ - public static RINGING: string = 'RWDE_RINGING'; - public static REJECTED: string = 'RWDE_REJECTED'; - public static ACCEPTED: string = 'RWDE_ACCEPTED'; - - private _userName: string = ''; - - constructor(type: string, userName: string) - { - super(type); - - this._userName = userName; - } - - public get userName(): string - { - return this._userName; - } -} diff --git a/src/api/nitro/room/widgets/events/RoomWidgetUpdateDimmerStateEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetUpdateDimmerStateEvent.ts index 27e9fd13..80dea562 100644 --- a/src/api/nitro/room/widgets/events/RoomWidgetUpdateDimmerStateEvent.ts +++ b/src/api/nitro/room/widgets/events/RoomWidgetUpdateDimmerStateEvent.ts @@ -14,11 +14,11 @@ export class RoomWidgetUpdateDimmerStateEvent extends RoomWidgetUpdateEvent { super(RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE); - this._state = state; - this._presetId = presetId; - this._effectId = effectId; - this._color = color; - this._brightness = brightness; + this._state = state; + this._presetId = presetId; + this._effectId = effectId; + this._color = color; + this._brightness = brightness; } public get state(): number diff --git a/src/api/nitro/room/widgets/events/RoomWidgetUpdateFriendRequestEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetUpdateFriendRequestEvent.ts deleted file mode 100644 index b60ac2d4..00000000 --- a/src/api/nitro/room/widgets/events/RoomWidgetUpdateFriendRequestEvent.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateFriendRequestEvent extends RoomWidgetUpdateEvent -{ - public static SHOW_FRIEND_REQUEST: string = 'RWFRUE_SHOW_FRIEND_REQUEST'; - public static HIDE_FRIEND_REQUEST: string = 'RWFRUE_HIDE_FRIEND_REQUEST'; - - private _requestId: number; - private _userId: number; - private _userName: string; - - constructor(type: string, requestId: number = -1, userId: number = -1, userName: string = null) - { - super(type); - - this._requestId = requestId; - this._userId = userId; - this._userName = userName; - } - - public get requestId(): number - { - return this._requestId; - } - - public get userId(): number - { - return this._userId; - } - - public get userName(): string - { - return this._userName; - } -} diff --git a/src/api/nitro/room/widgets/events/RoomWidgetUpdateInfostandUserEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetUpdateInfostandUserEvent.ts index f54ecc9a..32640c75 100644 --- a/src/api/nitro/room/widgets/events/RoomWidgetUpdateInfostandUserEvent.ts +++ b/src/api/nitro/room/widgets/events/RoomWidgetUpdateInfostandUserEvent.ts @@ -24,12 +24,10 @@ export class RoomWidgetUpdateInfostandUserEvent extends RoomWidgetUpdateInfostan public carryItem: number = 0; public roomIndex: number = 0; public isSpectatorMode: boolean = false; - public realName: string = ''; public allowNameChange: boolean = false; public amIOwner: boolean = false; public amIAnyRoomController: boolean = false; public roomControllerLevel: number = 0; - public canBeAskedAsFriend: boolean = false; public canBeKicked: boolean = false; public canBeBanned: boolean = false; public canBeMuted: boolean = false; @@ -39,7 +37,6 @@ export class RoomWidgetUpdateInfostandUserEvent extends RoomWidgetUpdateInfostan public canTrade: boolean = false; public canTradeReason: number = 0; public targetRoomControllerLevel: number = 0; - public isFriend: boolean = false; public isAmbassador: boolean = false; public get isOwnUser(): boolean diff --git a/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomObjectEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomObjectEvent.ts index cbc1d9c9..aa9b7258 100644 --- a/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomObjectEvent.ts +++ b/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomObjectEvent.ts @@ -2,15 +2,15 @@ import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; export class RoomWidgetUpdateRoomObjectEvent extends RoomWidgetUpdateEvent { - public static OBJECT_SELECTED: string = 'RWUROE_OBJECT_SELECTED'; - public static OBJECT_DESELECTED: string = 'RWUROE_OBJECT_DESELECTED'; - public static USER_REMOVED: string = 'RWUROE_USER_REMOVED'; - public static FURNI_REMOVED: string = 'RWUROE_FURNI_REMOVED'; - public static FURNI_ADDED: string = 'RWUROE_FURNI_ADDED'; - public static USER_ADDED: string = 'RWUROE_USER_ADDED'; - public static OBJECT_ROLL_OVER: string = 'RWUROE_OBJECT_ROLL_OVER'; - public static OBJECT_ROLL_OUT: string = 'RWUROE_OBJECT_ROLL_OUT'; - public static OBJECT_REQUEST_MANIPULATION: string = 'RWUROE_OBJECT_REQUEST_MANIPULATION'; + public static OBJECT_SELECTED: string = 'RWUROE_OBJECT_SELECTED'; + public static OBJECT_DESELECTED: string = 'RWUROE_OBJECT_DESELECTED'; + public static USER_REMOVED: string = 'RWUROE_USER_REMOVED'; + public static FURNI_REMOVED: string = 'RWUROE_FURNI_REMOVED'; + public static FURNI_ADDED: string = 'RWUROE_FURNI_ADDED'; + public static USER_ADDED: string = 'RWUROE_USER_ADDED'; + public static OBJECT_ROLL_OVER: string = 'RWUROE_OBJECT_ROLL_OVER'; + public static OBJECT_ROLL_OUT: string = 'RWUROE_OBJECT_ROLL_OUT'; + public static OBJECT_REQUEST_MANIPULATION: string = 'RWUROE_OBJECT_REQUEST_MANIPULATION'; private _id: number; private _category: number; @@ -20,9 +20,9 @@ export class RoomWidgetUpdateRoomObjectEvent extends RoomWidgetUpdateEvent { super(type); - this._id = id; - this._category = category; - this._roomId = roomId; + this._id = id; + this._category = category; + this._roomId = roomId; } public get id(): number diff --git a/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomViewEvent.ts b/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomViewEvent.ts deleted file mode 100644 index fce35aaf..00000000 --- a/src/api/nitro/room/widgets/events/RoomWidgetUpdateRoomViewEvent.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NitroRectangle } from '@nitrots/nitro-renderer'; -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateRoomViewEvent extends RoomWidgetUpdateEvent -{ - public static SIZE_CHANGED: string = 'RWURVE_SIZE_CHANGED'; - - private _roomViewRectangle: NitroRectangle; - - constructor(type: string, view: NitroRectangle) - { - super(type); - - this._roomViewRectangle = view; - } - - public get roomViewRectangle(): NitroRectangle - { - return this._roomViewRectangle; - } -} diff --git a/src/api/nitro/room/widgets/events/index.ts b/src/api/nitro/room/widgets/events/index.ts index be6a6ae5..ca4183f4 100644 --- a/src/api/nitro/room/widgets/events/index.ts +++ b/src/api/nitro/room/widgets/events/index.ts @@ -3,7 +3,6 @@ export * from './RoomDimmerPreset'; export * from './RoomObjectItem'; export * from './RoomWidgetAvatarInfoEvent'; export * from './RoomWidgetChooserContentEvent'; -export * from './RoomWidgetDoorbellEvent'; export * from './RoomWidgetFloodControlEvent'; export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetPollUpdateEvent'; @@ -18,7 +17,6 @@ export * from './RoomWidgetUpdateDimmerEvent'; export * from './RoomWidgetUpdateDimmerStateEvent'; export * from './RoomWidgetUpdateEvent'; export * from './RoomWidgetUpdateExternalImageEvent'; -export * from './RoomWidgetUpdateFriendRequestEvent'; export * from './RoomWidgetUpdateInfostandEvent'; export * from './RoomWidgetUpdateInfostandFurniEvent'; export * from './RoomWidgetUpdateInfostandPetEvent'; @@ -29,7 +27,6 @@ export * from './RoomWidgetUpdatePresentDataEvent'; export * from './RoomWidgetUpdateRentableBotChatEvent'; export * from './RoomWidgetUpdateRoomEngineEvent'; export * from './RoomWidgetUpdateRoomObjectEvent'; -export * from './RoomWidgetUpdateRoomViewEvent'; export * from './RoomWidgetUpdateSongEvent'; export * from './RoomWidgetUpdateTrophyEvent'; export * from './RoomWidgetUpdateUserDataEvent'; diff --git a/src/api/nitro/room/widgets/handlers/DoorbellWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/DoorbellWidgetHandler.ts deleted file mode 100644 index b2b69ee9..00000000 --- a/src/api/nitro/room/widgets/handlers/DoorbellWidgetHandler.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { NitroEvent, RoomSessionDoorbellEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer'; -import { RoomWidgetDoorbellEvent, RoomWidgetUpdateEvent } from '../events'; -import { RoomWidgetLetUserInMessage, RoomWidgetMessage } from '../messages'; -import { RoomWidgetHandler } from './RoomWidgetHandler'; - -export class DoorbellWidgetHandler extends RoomWidgetHandler -{ - public processEvent(event: NitroEvent): void - { - const doorbellEvent = (event as RoomSessionDoorbellEvent); - - switch(event.type) - { - case RoomSessionDoorbellEvent.DOORBELL: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.RINGING, doorbellEvent.userName)); - return; - case RoomSessionDoorbellEvent.RSDE_REJECTED: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.REJECTED, doorbellEvent.userName)); - return; - case RoomSessionDoorbellEvent.RSDE_ACCEPTED: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.ACCEPTED, doorbellEvent.userName)); - return; - } - } - - public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent - { - switch(message.type) - { - case RoomWidgetLetUserInMessage.LET_USER_IN: - const letUserInMessage = (message as RoomWidgetLetUserInMessage); - - this.container.roomSession.sendDoorbellApprovalMessage(letUserInMessage.userName, letUserInMessage.canEnter); - break; - } - - return null; - } - - public get type(): string - { - return RoomWidgetEnum.DOORBELL; - } - - public get eventTypes(): string[] - { - return [ - RoomSessionDoorbellEvent.DOORBELL, - RoomSessionDoorbellEvent.RSDE_REJECTED, - RoomSessionDoorbellEvent.RSDE_ACCEPTED - ]; - } - - public get messageTypes(): string[] - { - return [ - RoomWidgetLetUserInMessage.LET_USER_IN - ]; - } -} diff --git a/src/api/nitro/room/widgets/handlers/FriendRequestHandler.ts b/src/api/nitro/room/widgets/handlers/FriendRequestHandler.ts deleted file mode 100644 index 5269341c..00000000 --- a/src/api/nitro/room/widgets/handlers/FriendRequestHandler.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { NitroEvent, RoomSessionFriendRequestEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer'; -import { FriendRequestEvent, FriendsAcceptFriendRequestEvent, FriendsDeclineFriendRequestEvent } from '../../../../../events'; -import { DispatchUiEvent } from '../../../../../hooks'; -import { RoomWidgetUpdateEvent, RoomWidgetUpdateFriendRequestEvent } from '../events'; -import { RoomWidgetFriendRequestMessage, RoomWidgetMessage } from '../messages'; -import { RoomWidgetHandler } from './RoomWidgetHandler'; - -export class FriendRequestHandler extends RoomWidgetHandler -{ - public processEvent(event: NitroEvent): void - { - const friendRequestEvent = (event as RoomSessionFriendRequestEvent); - - switch(event.type) - { - case RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateFriendRequestEvent(RoomWidgetUpdateFriendRequestEvent.SHOW_FRIEND_REQUEST, friendRequestEvent.requestId, friendRequestEvent.userId, friendRequestEvent.userName)); - return; - case FriendRequestEvent.ACCEPTED: - case FriendRequestEvent.DECLINED: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateFriendRequestEvent(RoomWidgetUpdateFriendRequestEvent.HIDE_FRIEND_REQUEST, friendRequestEvent.requestId)); - return; - } - } - - public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent - { - const friendMessage = (message as RoomWidgetFriendRequestMessage); - - switch(message.type) - { - case RoomWidgetFriendRequestMessage.ACCEPT: - DispatchUiEvent(new FriendsAcceptFriendRequestEvent(friendMessage.requestId)); - break; - case RoomWidgetFriendRequestMessage.DECLINE: - DispatchUiEvent(new FriendsDeclineFriendRequestEvent(friendMessage.requestId)); - break; - - } - - return null; - } - - public get type(): string - { - return RoomWidgetEnum.FRIEND_REQUEST; - } - - public get eventTypes(): string[] - { - return [ - RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST, - FriendRequestEvent.ACCEPTED, - FriendRequestEvent.DECLINED - ]; - } - - public get messageTypes(): string[] - { - return [ - RoomWidgetFriendRequestMessage.ACCEPT, - RoomWidgetFriendRequestMessage.DECLINE - ]; - } -} diff --git a/src/api/nitro/room/widgets/handlers/FurniChooserWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/FurniChooserWidgetHandler.ts index f08406e8..46c3f502 100644 --- a/src/api/nitro/room/widgets/handlers/FurniChooserWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/FurniChooserWidgetHandler.ts @@ -37,40 +37,40 @@ export class FurniChooserWidgetHandler extends RoomWidgetHandler const floorItems = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.FLOOR); wallItems.forEach(roomObject => + { + let name = roomObject.type; + + if(name.startsWith('poster')) { - let name = roomObject.type; - - if(name.startsWith('poster')) - { - name = LocalizeText(`poster_${ name.replace('poster', '') }_name`); - } - else - { - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = GetSessionDataManager().getWallItemData(typeId); - - if(furniData && furniData.name.length) name = furniData.name; - } - - items.push(new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name)); - }); - - floorItems.forEach(roomObject => + name = LocalizeText(`poster_${ name.replace('poster', '') }_name`); + } + else { - let name = roomObject.type; - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = GetSessionDataManager().getFloorItemData(typeId); + const furniData = GetSessionDataManager().getWallItemData(typeId); if(furniData && furniData.name.length) name = furniData.name; + } - items.push(new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name)); - }); + items.push(new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name)); + }); + + floorItems.forEach(roomObject => + { + let name = roomObject.type; + + const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); + const furniData = GetSessionDataManager().getFloorItemData(typeId); + + if(furniData && furniData.name.length) name = furniData.name; + + items.push(new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name)); + }); items.sort((a, b) => - { - return (a.name < b.name) ? -1 : 1; - }); + { + return (a.name < b.name) ? -1 : 1; + }); this.container.eventDispatcher.dispatchEvent(new RoomWidgetChooserContentEvent(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, items)); } diff --git a/src/api/nitro/room/widgets/handlers/FurnitureInternalLinkHandler.ts b/src/api/nitro/room/widgets/handlers/FurnitureInternalLinkHandler.ts index 493f7052..8996cf38 100644 --- a/src/api/nitro/room/widgets/handlers/FurnitureInternalLinkHandler.ts +++ b/src/api/nitro/room/widgets/handlers/FurnitureInternalLinkHandler.ts @@ -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[] diff --git a/src/api/nitro/room/widgets/handlers/FurniturePresentWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/FurniturePresentWidgetHandler.ts index 2b1f3ed2..6de7aa2f 100644 --- a/src/api/nitro/room/widgets/handlers/FurniturePresentWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/FurniturePresentWidgetHandler.ts @@ -1,7 +1,7 @@ import { IFurnitureData, IGetImageListener, NitroEvent, NitroRenderTexture, PetFigureData, RoomObjectCategory, RoomObjectVariable, RoomSessionPresentEvent, RoomWidgetEnum, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; import { GetSessionDataManager, IsOwnerOfFurniture } from '../../..'; import { GetRoomEngine, LocalizeText } from '../../../..'; -import { ProductTypeEnum } from '../../../../../components/catalog/common/ProductTypeEnum'; +import { ProductTypeEnum } from '../../../../catalog'; import { RoomWidgetUpdateEvent, RoomWidgetUpdatePresentDataEvent } from '../events'; import { RoomWidgetFurniToWidgetMessage, RoomWidgetPresentOpenMessage } from '../messages'; import { RoomWidgetMessage } from '../messages/RoomWidgetMessage'; @@ -9,10 +9,10 @@ import { RoomWidgetHandler } from './RoomWidgetHandler'; export class FurniturePresentWidgetHandler extends RoomWidgetHandler implements IGetImageListener { - private static FLOOR: string = 'floor'; - private static WALLPAPER: string = 'wallpaper'; - private static LANDSCAPE: string = 'landscape'; - private static POSTER: string = 'poster'; + private static FLOOR: string = 'floor'; + private static WALLPAPER: string = 'wallpaper'; + private static LANDSCAPE: string = 'landscape'; + private static POSTER: string = 'poster'; private _lastFurniId: number = -1; private _name: string = null; diff --git a/src/api/nitro/room/widgets/handlers/FurnitureRoomLinkHandler.ts b/src/api/nitro/room/widgets/handlers/FurnitureRoomLinkHandler.ts index 9396ba27..2f0a74d1 100644 --- a/src/api/nitro/room/widgets/handlers/FurnitureRoomLinkHandler.ts +++ b/src/api/nitro/room/widgets/handlers/FurnitureRoomLinkHandler.ts @@ -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[] diff --git a/src/api/nitro/room/widgets/handlers/FurnitureTrophyWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/FurnitureTrophyWidgetHandler.ts index 9b345109..8554977a 100644 --- a/src/api/nitro/room/widgets/handlers/FurnitureTrophyWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/FurnitureTrophyWidgetHandler.ts @@ -24,7 +24,7 @@ export class FurnitureTrophyWidgetHandler extends RoomWidgetHandler const color = roomObject.model.getValue(RoomObjectVariable.FURNITURE_COLOR); const extra = parseInt(roomObject.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS)); - let data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); + let data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); const ownerName = data.substring(0, data.indexOf('\t')); diff --git a/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts index 65330784..99639167 100644 --- a/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts @@ -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 ]; } } diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetAvatarInfoHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetAvatarInfoHandler.ts index 5ec47a95..2c979b4c 100644 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetAvatarInfoHandler.ts +++ b/src/api/nitro/room/widgets/handlers/RoomWidgetAvatarInfoHandler.ts @@ -1,8 +1,8 @@ import { NitroEvent, RoomEngineUseProductEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionDanceEvent, RoomSessionPetStatusUpdateEvent, RoomSessionUserDataUpdateEvent, RoomWidgetEnum, SetRelationshipStatusComposer } from '@nitrots/nitro-renderer'; import { SendMessageComposer } from '../../..'; import { GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../..'; -import { MessengerFriend } from '../../../../../components/friends/common/MessengerFriend'; -import { FurniCategory } from '../../../../../components/inventory/common/FurniCategory'; +import { MessengerFriend } from '../../../../friends/MessengerFriend'; +import { FurniCategory } from '../../../../inventory/FurniCategory'; import { RoomWidgetAvatarInfoEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateUserDataEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../events'; import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUseProductMessage, RoomWidgetUserActionMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -50,7 +50,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler this.processOwnCharacterInfo(); break; case RoomWidgetUserActionMessage.START_NAME_CHANGE: - // habbo help - start name change + // habbo help - start name change break; case RoomWidgetUserActionMessage.REQUEST_PET_UPDATE: break; diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetChatHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetChatHandler.ts index 45f895b8..29c7d371 100644 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetChatHandler.ts +++ b/src/api/nitro/room/widgets/handlers/RoomWidgetChatHandler.ts @@ -1,6 +1,7 @@ -import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, IAvatarImageListener, INitroPoint, IVector3D, NitroEvent, NitroPoint, PetFigureData, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, RoomWidgetEnum, SystemChatStyleEnum, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; +import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, IAvatarImageListener, NitroEvent, PetFigureData, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, RoomWidgetEnum, SystemChatStyleEnum, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; import { GetAvatarRenderManager, GetConfigurationManager, GetRoomEngine, PlaySound } from '../../../..'; import { LocalizeText } from '../../../../utils/LocalizeText'; +import { GetRoomObjectScreenLocation } from '../../GetRoomObjectScreenLocation'; import { RoomWidgetUpdateChatEvent, RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -21,7 +22,7 @@ export class RoomWidgetChatHandler extends RoomWidgetHandler implements IAvatarI const roomObject = GetRoomEngine().getRoomObject(chatEvent.session.roomId, chatEvent.objectId, RoomObjectCategory.UNIT); const objectLocation = roomObject ? roomObject.getLocation() : new Vector3d(); - const bubbleLocation = this.getBubbleLocation(chatEvent.session.roomId, objectLocation); + const bubbleLocation = GetRoomObjectScreenLocation(chatEvent.session.roomId, roomObject?.id, RoomObjectCategory.UNIT); const userData = roomObject ? this.container.roomSession.userDataManager.getUserDataByIndex(chatEvent.objectId) : new RoomUserData(-1); let username = ''; @@ -101,7 +102,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(); @@ -125,36 +126,6 @@ export class RoomWidgetChatHandler extends RoomWidgetHandler implements IAvatarI return null; } - private getBubbleLocation(roomId: number, userLocation: IVector3D, canvasId = 1): INitroPoint - { - const geometry = GetRoomEngine().getRoomInstanceGeometry(roomId, canvasId); - const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomId, canvasId); - - let x = ((document.body.offsetWidth * scale) / 2); - let y = ((document.body.offsetHeight * scale) / 2); - - if(geometry && userLocation) - { - const screenPoint = geometry.getScreenPoint(userLocation); - - if(screenPoint) - { - x = (x + (screenPoint.x * scale)); - y = (y + (screenPoint.y * scale)); - - const offsetPoint = GetRoomEngine().getRoomInstanceRenderingCanvasOffset(roomId, canvasId); - - if(offsetPoint) - { - x = (x + offsetPoint.x); - y = (y + offsetPoint.y); - } - } - } - - return new NitroPoint(x, y); - } - public getUserImage(figure: string): string { let existing = this._avatarImageCache.get(figure); diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts index 55a9c5ff..997eb4b4 100644 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts +++ b/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts @@ -1,8 +1,7 @@ import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomRotatingEffect, RoomSessionChatEvent, RoomSettingsComposer, RoomShakingEffect, RoomWidgetEnum, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer'; import { GetClubMemberLevel, GetConfiguration, GetNitroInstance, SendMessageComposer } from '../../..'; import { GetRoomEngine, GetSessionDataManager, LocalizeText, NotificationUtilities } from '../../../..'; -import { FloorplanEditorEvent } from '../../../../../events/floorplan-editor/FloorplanEditorEvent'; -import { DispatchUiEvent } from '../../../../../hooks'; +import { CreateLinkEvent } from '../../../CreateLinkEvent'; import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -124,7 +123,7 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler return null; case ':zoom': - GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(this.container.roomSession.roomId, parseInt(secondPart), false)); + GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(this.container.roomSession.roomId, parseFloat(secondPart), false)); return null; case ':screenshot': @@ -141,10 +140,10 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler if(this.container.roomSession.isRoomOwner || GetSessionDataManager().isModerator) { NotificationUtilities.confirm(LocalizeText('room.confirm.pick_all'), () => - { - GetSessionDataManager().sendSpecialCommandMessage(':pickall'); - }, - null, null, null, LocalizeText('generic.alert.title')); + { + GetSessionDataManager().sendSpecialCommandMessage(':pickall'); + }, + null, null, null, LocalizeText('generic.alert.title')); } return null; @@ -158,12 +157,8 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler return null; case ':floor': case ':bcfloor': - if(this.container.roomSession.controllerLevel >= RoomControllerLevel.ROOM_OWNER) - { - //this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FLOOR_EDITOR)); - DispatchUiEvent(new FloorplanEditorEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR)); - } - + if(this.container.roomSession.controllerLevel >= RoomControllerLevel.ROOM_OWNER) CreateLinkEvent('floor-editor/show'); + return null; case ':togglefps': { if(GetNitroInstance().ticker.maxFPS > 0) GetNitroInstance().ticker.maxFPS = 0; diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetInfostandHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetInfostandHandler.ts index 3928ed64..1b620f2b 100644 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetInfostandHandler.ts +++ b/src/api/nitro/room/widgets/handlers/RoomWidgetInfostandHandler.ts @@ -1,9 +1,8 @@ -import { IFurnitureData, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, Vector3d } from '@nitrots/nitro-renderer'; +import { IFurnitureData, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, TradingOpenComposer, Vector3d } from '@nitrots/nitro-renderer'; import { SendMessageComposer } from '../../..'; import { GetNitroInstance, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../..'; -import { FriendsHelper } from '../../../../../components/friends/common/FriendsHelper'; import { PetSupplementEnum } from '../../../../../components/room/widgets/avatar-info/common/PetSupplementEnum'; -import { FriendsSendFriendRequestEvent, HelpReportUserEvent, InventoryTradeRequestEvent, WiredSelectObjectEvent } from '../../../../../events'; +import { HelpReportUserEvent, WiredSelectObjectEvent } from '../../../../../events'; import { DispatchUiEvent } from '../../../../../hooks'; import { LocalizeText } from '../../../../utils/LocalizeText'; import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events'; @@ -81,9 +80,6 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler return this.processObjectNameMessage((message as RoomWidgetRoomObjectMessage)); case RoomWidgetRoomObjectMessage.GET_OBJECT_INFO: return this.processObjectInfoMessage((message as RoomWidgetRoomObjectMessage)); - case RoomWidgetUserActionMessage.SEND_FRIEND_REQUEST: - DispatchUiEvent(new FriendsSendFriendRequestEvent(userData.webID, userData.name)); - break; case RoomWidgetUserActionMessage.RESPECT_USER: GetSessionDataManager().giveRespect(userId); break; @@ -123,7 +119,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId); break; case RoomWidgetUserActionMessage.START_TRADING: - DispatchUiEvent(new InventoryTradeRequestEvent(userData.roomIndex, userData.name)); + SendMessageComposer(new TradingOpenComposer(userData.roomIndex)); break; // case RoomWidgetUserActionMessage.RWUAM_OPEN_HOME_PAGE: // this._container.sessionDataManager._Str_21275((message as RoomWidgetUserActionMessage).userId, _local_3.name); @@ -452,11 +448,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler if(roomObject) event.carryItem = (roomObject.model.getValue(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); - if(eventType === RoomWidgetUpdateInfostandUserEvent.OWN_USER) - { - event.realName = GetSessionDataManager().realName; - event.allowNameChange = GetSessionDataManager().canChangeName; - } + if(eventType === RoomWidgetUpdateInfostandUserEvent.OWN_USER) event.allowNameChange = GetSessionDataManager().canChangeName; event.amIOwner = this.container.roomSession.isRoomOwner; event.isGuildRoom = this.container.roomSession.isGuildRoom; @@ -466,19 +458,6 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler if(eventType === RoomWidgetUpdateInfostandUserEvent.PEER) { - event.canBeAskedAsFriend = FriendsHelper.canRequestFriend(userData.webID); - - if(!event.canBeAskedAsFriend) - { - const friend = FriendsHelper.getFriend(userData.webID); - - if(friend) - { - event.realName = friend.realName; - event.isFriend = true; - } - } - if(roomObject) { const flatControl = roomObject.model.getValue(RoomObjectVariable.FIGURE_FLAT_CONTROL); @@ -755,7 +734,6 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler return [ RoomWidgetRoomObjectMessage.GET_OBJECT_INFO, RoomWidgetRoomObjectMessage.GET_OBJECT_NAME, - RoomWidgetUserActionMessage.SEND_FRIEND_REQUEST, RoomWidgetUserActionMessage.RESPECT_USER, RoomWidgetUserActionMessage.WHISPER_USER, RoomWidgetUserActionMessage.IGNORE_USER, diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetRoomToolsHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetRoomToolsHandler.ts deleted file mode 100644 index c99518da..00000000 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetRoomToolsHandler.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { NitroEvent, RoomWidgetEnum, RoomZoomEvent } from '@nitrots/nitro-renderer'; -import { GetRoomEngine } from '../../../..'; -import { RoomWidgetUpdateEvent } from '../events'; -import { RoomWidgetMessage, RoomWidgetZoomToggleMessage } from '../messages'; -import { RoomWidgetHandler } from './RoomWidgetHandler'; - -export class RoomWidgetRoomToolsHandler extends RoomWidgetHandler -{ - public processEvent(event: NitroEvent): void - {} - - public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent - { - if(message instanceof RoomWidgetZoomToggleMessage) - { - GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(GetRoomEngine().activeRoomId, message.zoomedIn ? 0 : 1, false)); - } - - return null; - } - - public get type(): string - { - return RoomWidgetEnum.ROOM_TOOLS; - } - - public get eventTypes(): string[] - { - return []; - } - - public get messageTypes(): string[] - { - return [ - RoomWidgetZoomToggleMessage.ZOOM_TOGGLE - ]; - } -} diff --git a/src/api/nitro/room/widgets/handlers/UserChooserWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/UserChooserWidgetHandler.ts index 67b00e06..44b2141b 100644 --- a/src/api/nitro/room/widgets/handlers/UserChooserWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/UserChooserWidgetHandler.ts @@ -35,13 +35,13 @@ export class UserChooserWidgetHandler extends RoomWidgetHandler const userItems = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.UNIT); userItems.forEach(roomObject => - { - const userData = this.container.roomSession.userDataManager.getUserDataByIndex(roomObject.id); + { + const userData = this.container.roomSession.userDataManager.getUserDataByIndex(roomObject.id); - if(!userData) return; + if(!userData) return; - items.push(new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name)); - }); + items.push(new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name)); + }); items.sort((a, b) => { diff --git a/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts index df24b06e..d0ce01b0 100644 --- a/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts @@ -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[] diff --git a/src/api/nitro/room/widgets/handlers/index.ts b/src/api/nitro/room/widgets/handlers/index.ts index 40fadc00..67260528 100644 --- a/src/api/nitro/room/widgets/handlers/index.ts +++ b/src/api/nitro/room/widgets/handlers/index.ts @@ -1,5 +1,3 @@ -export * from './DoorbellWidgetHandler'; -export * from './FriendRequestHandler'; export * from './FurniChooserWidgetHandler'; export * from './FurnitureContextMenuWidgetHandler'; export * from './FurnitureCreditWidgetHandler'; @@ -21,6 +19,5 @@ export * from './RoomWidgetChatInputHandler'; export * from './RoomWidgetHandler'; export * from './RoomWidgetHandlerManager'; export * from './RoomWidgetInfostandHandler'; -export * from './RoomWidgetRoomToolsHandler'; export * from './UserChooserWidgetHandler'; export * from './WordQuizWidgetHandler'; diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetDanceMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetDanceMessage.ts index 72f5c0eb..7ed703bb 100644 --- a/src/api/nitro/room/widgets/messages/RoomWidgetDanceMessage.ts +++ b/src/api/nitro/room/widgets/messages/RoomWidgetDanceMessage.ts @@ -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; diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetFriendRequestMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetFriendRequestMessage.ts deleted file mode 100644 index 898a042d..00000000 --- a/src/api/nitro/room/widgets/messages/RoomWidgetFriendRequestMessage.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { RoomWidgetMessage } from './RoomWidgetMessage'; - -export class RoomWidgetFriendRequestMessage extends RoomWidgetMessage -{ - public static ACCEPT: string = 'RWFRM_ACCEPT'; - public static DECLINE: string = 'RMFRM_DECLINE'; - - private _requestId: number; - - constructor(type: string, requestId: number) - { - super(type); - - this._requestId = requestId; - } - - public get requestId(): number - { - return this._requestId; - } -} diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetFurniActionMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetFurniActionMessage.ts index d658d7d9..678f9e56 100644 --- a/src/api/nitro/room/widgets/messages/RoomWidgetFurniActionMessage.ts +++ b/src/api/nitro/room/widgets/messages/RoomWidgetFurniActionMessage.ts @@ -19,10 +19,10 @@ export class RoomWidgetFurniActionMessage extends RoomWidgetMessage { super(type); - this._furniId = id; + this._furniId = id; this._furniCategory = category; - this._offerId = offerId; - this._objectData = objectData; + this._offerId = offerId; + this._objectData = objectData; } public get furniId(): number diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetFurniToWidgetMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetFurniToWidgetMessage.ts index 59054ff2..959d7f2b 100644 --- a/src/api/nitro/room/widgets/messages/RoomWidgetFurniToWidgetMessage.ts +++ b/src/api/nitro/room/widgets/messages/RoomWidgetFurniToWidgetMessage.ts @@ -24,9 +24,9 @@ export class RoomWidgetFurniToWidgetMessage extends RoomWidgetMessage { super(type); - this._objectId = objectId; - this._category = category; - this._roomId = roomId; + this._objectId = objectId; + this._category = category; + this._roomId = roomId; } public get objectId(): number diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetLetUserInMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetLetUserInMessage.ts deleted file mode 100644 index 9001fe2a..00000000 --- a/src/api/nitro/room/widgets/messages/RoomWidgetLetUserInMessage.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RoomWidgetMessage } from './RoomWidgetMessage'; - -export class RoomWidgetLetUserInMessage extends RoomWidgetMessage -{ - public static LET_USER_IN: string = 'RWLUIM_LET_USER_IN'; - - private _userName: string; - private _canEnter: boolean; - - constructor(userName: string, canEnter: boolean) - { - super(RoomWidgetLetUserInMessage.LET_USER_IN); - - this._userName = userName; - this._canEnter = canEnter; - } - - public get userName(): string - { - return this._userName; - } - - public get canEnter(): boolean - { - return this._canEnter; - } -} diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetRoomObjectMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetRoomObjectMessage.ts index cc82b85c..98ce28dd 100644 --- a/src/api/nitro/room/widgets/messages/RoomWidgetRoomObjectMessage.ts +++ b/src/api/nitro/room/widgets/messages/RoomWidgetRoomObjectMessage.ts @@ -15,8 +15,8 @@ export class RoomWidgetRoomObjectMessage extends RoomWidgetMessage { super(type); - this._id = id; - this._category = category; + this._id = id; + this._category = category; } public get id(): number diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetUserActionMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetUserActionMessage.ts index 56fd89c7..964572f3 100644 --- a/src/api/nitro/room/widgets/messages/RoomWidgetUserActionMessage.ts +++ b/src/api/nitro/room/widgets/messages/RoomWidgetUserActionMessage.ts @@ -13,7 +13,6 @@ export class RoomWidgetUserActionMessage extends RoomWidgetMessage public static MUTE_USER_2MIN: string = 'RWUAM_MUTE_USER_2MIN'; public static MUTE_USER_5MIN: string = 'RWUAM_MUTE_USER_5MIN'; public static MUTE_USER_10MIN: string = 'RWUAM_MUTE_USER_10MIN'; - public static SEND_FRIEND_REQUEST: string = 'RWUAM_SEND_FRIEND_REQUEST'; public static RESPECT_USER: string = 'RWUAM_RESPECT_USER'; public static GIVE_RIGHTS: string = 'RWUAM_GIVE_RIGHTS'; public static TAKE_RIGHTS: string = 'RWUAM_TAKE_RIGHTS'; diff --git a/src/api/nitro/room/widgets/messages/RoomWidgetZoomToggleMessage.ts b/src/api/nitro/room/widgets/messages/RoomWidgetZoomToggleMessage.ts deleted file mode 100644 index dae47e5b..00000000 --- a/src/api/nitro/room/widgets/messages/RoomWidgetZoomToggleMessage.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RoomWidgetMessage } from '.'; - -export class RoomWidgetZoomToggleMessage extends RoomWidgetMessage -{ - public static ZOOM_TOGGLE: string = 'RWZTM_ZOOM_TOGGLE'; - private _zoomedIn: boolean; - - constructor(zoomedIn: boolean) - { - super(RoomWidgetZoomToggleMessage.ZOOM_TOGGLE); - this._zoomedIn = zoomedIn; - } - - public get zoomedIn(): boolean - { - return this._zoomedIn; - } -} diff --git a/src/api/nitro/room/widgets/messages/index.ts b/src/api/nitro/room/widgets/messages/index.ts index 9fdaba24..f7a371e6 100644 --- a/src/api/nitro/room/widgets/messages/index.ts +++ b/src/api/nitro/room/widgets/messages/index.ts @@ -9,10 +9,8 @@ export * from './RoomWidgetDanceMessage'; export * from './RoomWidgetDimmerChangeStateMessage'; export * from './RoomWidgetDimmerPreviewMessage'; export * from './RoomWidgetDimmerSavePresetMessage'; -export * from './RoomWidgetFriendRequestMessage'; export * from './RoomWidgetFurniActionMessage'; export * from './RoomWidgetFurniToWidgetMessage'; -export * from './RoomWidgetLetUserInMessage'; export * from './RoomWidgetMessage'; export * from './RoomWidgetPollMessage'; export * from './RoomWidgetPresentOpenMessage'; @@ -20,4 +18,3 @@ export * from './RoomWidgetRequestWidgetMessage'; export * from './RoomWidgetRoomObjectMessage'; export * from './RoomWidgetUseProductMessage'; export * from './RoomWidgetUserActionMessage'; -export * from './RoomWidgetZoomToggleMessage'; diff --git a/src/api/nitro/session/GetFurnitureData.ts b/src/api/nitro/session/GetFurnitureData.ts index 4272dbd3..71afef86 100644 --- a/src/api/nitro/session/GetFurnitureData.ts +++ b/src/api/nitro/session/GetFurnitureData.ts @@ -1,6 +1,6 @@ import { IFurnitureData } from '@nitrots/nitro-renderer'; import { GetSessionDataManager } from '.'; -import { ProductTypeEnum } from '../../../components/catalog/common/ProductTypeEnum'; +import { ProductTypeEnum } from '../../catalog'; export function GetFurnitureData(furniClassId: number, productType: string): IFurnitureData { diff --git a/src/api/nitro/session/IsOwnerOfFurniture.ts b/src/api/nitro/session/IsOwnerOfFurniture.ts index 20c70f3e..56b7fc34 100644 --- a/src/api/nitro/session/IsOwnerOfFurniture.ts +++ b/src/api/nitro/session/IsOwnerOfFurniture.ts @@ -5,7 +5,7 @@ export function IsOwnerOfFurniture(roomObject: IRoomObject): boolean { if(!roomObject || !roomObject.model) return false; - const userId = GetSessionDataManager().userId; + const userId = GetSessionDataManager().userId; const objectOwnerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); return (userId === objectOwnerId); diff --git a/src/api/notification/NotificationAlertItem.ts b/src/api/notification/NotificationAlertItem.ts index cbbf8f4a..2d7702c7 100644 --- a/src/api/notification/NotificationAlertItem.ts +++ b/src/api/notification/NotificationAlertItem.ts @@ -35,6 +35,11 @@ export class NotificationAlertItem return this._messages; } + public set alertType(alertType: string) + { + this._alertType = alertType; + } + public get alertType(): string { return this._alertType; diff --git a/src/api/notification/NotificationAlertType.ts b/src/api/notification/NotificationAlertType.ts index 6732c598..ad804e80 100644 --- a/src/api/notification/NotificationAlertType.ts +++ b/src/api/notification/NotificationAlertType.ts @@ -6,4 +6,5 @@ export class NotificationAlertType public static EVENT: string = 'event'; public static NITRO: string = 'nitro'; public static SEARCH: string = 'search'; + public static ALERT: string = 'alert'; } diff --git a/src/api/notification/NotificationUtilities.ts b/src/api/notification/NotificationUtilities.ts index 48c3082f..1c6c9fdd 100644 --- a/src/api/notification/NotificationUtilities.ts +++ b/src/api/notification/NotificationUtilities.ts @@ -137,7 +137,7 @@ export class NotificationUtilities public static showModeratorMessage(message: string, url: string = null, showHabboWay: boolean = true): void { - this.simpleAlert(message, NotificationAlertType.MODERATION, url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title')); + this.simpleAlert(message, NotificationAlertType.DEFAULT, url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title')); } public static handleModeratorCaution(message: string, url: string = null): void @@ -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 diff --git a/src/components/purse/common/IPurse.ts b/src/api/purse/IPurse.ts similarity index 100% rename from src/components/purse/common/IPurse.ts rename to src/api/purse/IPurse.ts diff --git a/src/components/purse/common/Purse.ts b/src/api/purse/Purse.ts similarity index 98% rename from src/components/purse/common/Purse.ts rename to src/api/purse/Purse.ts index f9ea045a..a0a54b4c 100644 --- a/src/components/purse/common/Purse.ts +++ b/src/api/purse/Purse.ts @@ -1,5 +1,5 @@ import { HabboClubLevelEnum } from '@nitrots/nitro-renderer'; -import { GetNitroInstance } from '../../../api'; +import { GetNitroInstance } from '..'; import { IPurse } from './IPurse'; export class Purse implements IPurse diff --git a/src/api/purse/index.ts b/src/api/purse/index.ts new file mode 100644 index 00000000..ed344804 --- /dev/null +++ b/src/api/purse/index.ts @@ -0,0 +1,2 @@ +export * from './IPurse'; +export * from './Purse'; diff --git a/src/api/utils/ColorUtils.ts b/src/api/utils/ColorUtils.ts index 126d271d..9377255e 100644 --- a/src/api/utils/ColorUtils.ts +++ b/src/api/utils/ColorUtils.ts @@ -13,7 +13,7 @@ export class ColorUtils const diff = 6 - val.length; for(let i = 0; i < diff; i++) { - val = '0' + val; + val = '0' + val; } } return ( '#' + val); diff --git a/src/api/utils/LocalStorageKeys.ts b/src/api/utils/LocalStorageKeys.ts new file mode 100644 index 00000000..6c922790 --- /dev/null +++ b/src/api/utils/LocalStorageKeys.ts @@ -0,0 +1,5 @@ +export class LocalStorageKeys +{ + public static CATALOG_PLACE_MULTIPLE_OBJECTS: string = 'catalogPlaceMultipleObjects'; + public static CATALOG_SKIP_PURCHASE_CONFIRMATION: string = 'catalogSkipPurchaseConfirmation'; +} diff --git a/src/api/common/ProductImageUtility.ts b/src/api/utils/ProductImageUtility.ts similarity index 91% rename from src/api/common/ProductImageUtility.ts rename to src/api/utils/ProductImageUtility.ts index 3dfd5ef7..59c8c4f4 100644 --- a/src/api/common/ProductImageUtility.ts +++ b/src/api/utils/ProductImageUtility.ts @@ -1,6 +1,6 @@ import { CatalogPageMessageProductData } from '@nitrots/nitro-renderer'; -import { GetRoomEngine } from '..'; -import { FurniCategory } from '../../components/catalog/common/FurniCategory'; +import { FurniCategory } from '../inventory'; +import { GetRoomEngine } from '../nitro'; export class ProductImageUtility { @@ -34,7 +34,7 @@ export class ProductImageUtility } break; case CatalogPageMessageProductData.E: - // fx_icon_furniClassId_png + // fx_icon_furniClassId_png break; } diff --git a/src/api/utils/RoomChatFormatter.ts b/src/api/utils/RoomChatFormatter.ts index c20aa344..9c80de72 100644 --- a/src/api/utils/RoomChatFormatter.ts +++ b/src/api/utils/RoomChatFormatter.ts @@ -26,16 +26,16 @@ 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) + ';'; + { + if(char !== '&' || next !== '#') + { + if(/[\u00A0-\u9999<>&]/.test(next)) + next = '&#' + next.charCodeAt(0) + ';'; - return '&#' + char.charCodeAt(0) + ';' + next; - } + return '&#' + char.charCodeAt(0) + ';' + next; + } - return full; + return full; }); } diff --git a/src/api/utils/index.ts b/src/api/utils/index.ts index 398758cb..eeb74fce 100644 --- a/src/api/utils/index.ts +++ b/src/api/utils/index.ts @@ -5,7 +5,9 @@ export * from './LocalizeBageName'; export * from './LocalizeFormattedNumber'; export * from './LocalizeShortNumber'; export * from './LocalizeText'; +export * from './LocalStorageKeys'; export * from './PlaySound'; +export * from './ProductImageUtility'; export * from './Randomizer'; export * from './RoomChatFormatter'; export * from './SoundNames'; diff --git a/src/api/wired/WiredSelectionFilter.ts b/src/api/wired/WiredSelectionFilter.ts index b0b5ae32..d661bcf7 100644 --- a/src/api/wired/WiredSelectionFilter.ts +++ b/src/api/wired/WiredSelectionFilter.ts @@ -38,9 +38,9 @@ export class WiredSelectionFilter extends NitroFilter super(vertex, fragment); this.uniforms.lineColor = new Float32Array(3); - this.uniforms.color = new Float32Array(3); - this.lineColor = lineColor; - this.color = color; + this.uniforms.color = new Float32Array(3); + this.lineColor = lineColor; + this.color = color; } public get lineColor(): number | number[] diff --git a/src/assets/images/room-spectator/room_spectator_bottom_left.png b/src/assets/images/room-spectator/room_spectator_bottom_left.png new file mode 100644 index 00000000..01688cb2 Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_bottom_left.png differ diff --git a/src/assets/images/room-spectator/room_spectator_bottom_right.png b/src/assets/images/room-spectator/room_spectator_bottom_right.png new file mode 100644 index 00000000..59c8ef2c Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_bottom_right.png differ diff --git a/src/assets/images/room-spectator/room_spectator_middle_bottom.png b/src/assets/images/room-spectator/room_spectator_middle_bottom.png new file mode 100644 index 00000000..ba6fdecc Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_middle_bottom.png differ diff --git a/src/assets/images/room-spectator/room_spectator_middle_left.png b/src/assets/images/room-spectator/room_spectator_middle_left.png new file mode 100644 index 00000000..6d9aaa79 Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_middle_left.png differ diff --git a/src/assets/images/room-spectator/room_spectator_middle_right.png b/src/assets/images/room-spectator/room_spectator_middle_right.png new file mode 100644 index 00000000..9d963b3d Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_middle_right.png differ diff --git a/src/assets/images/room-spectator/room_spectator_middle_top.png b/src/assets/images/room-spectator/room_spectator_middle_top.png new file mode 100644 index 00000000..f6559cee Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_middle_top.png differ diff --git a/src/assets/images/room-spectator/room_spectator_top_left.png b/src/assets/images/room-spectator/room_spectator_top_left.png new file mode 100644 index 00000000..5e62a3c9 Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_top_left.png differ diff --git a/src/assets/images/room-spectator/room_spectator_top_right.png b/src/assets/images/room-spectator/room_spectator_top_right.png new file mode 100644 index 00000000..825f3fb1 Binary files /dev/null and b/src/assets/images/room-spectator/room_spectator_top_right.png differ diff --git a/src/common/Base.tsx b/src/common/Base.tsx index 8bffe170..8ba38fc3 100644 --- a/src/common/Base.tsx +++ b/src/common/Base.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, DetailedHTMLProps, FC, HTMLAttributes, MutableRefObject, useMemo } from 'react'; +import { CSSProperties, DetailedHTMLProps, FC, HTMLAttributes, MutableRefObject, ReactNode, useMemo } from 'react'; import { ColorVariantType, DisplayType, FloatType, OverflowType, PositionType } from './types'; export interface BaseProps extends DetailedHTMLProps, T> @@ -17,11 +17,12 @@ export interface BaseProps extends DetailedHTMLProps> = props => { - const { ref = null, innerRef = null, display = null, fit = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, visible = null, textColor = null, classNames = [], className = '', style = {}, ...rest } = props; + const { ref = null, innerRef = null, display = null, fit = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, visible = null, textColor = null, classNames = [], className = '', style = {}, children = null, ...rest } = props; const getClassNames = useMemo(() => { @@ -72,5 +73,9 @@ export const Base: FC> = props => return newStyle; }, [ style ]); - return
; + return ( +
+ { children } +
+ ); } diff --git a/src/common/card/accordion/NitroCardAccordionSetView.tsx b/src/common/card/accordion/NitroCardAccordionSetView.tsx index 05dde76b..0be64d08 100644 --- a/src/common/card/accordion/NitroCardAccordionSetView.tsx +++ b/src/common/card/accordion/NitroCardAccordionSetView.tsx @@ -45,26 +45,26 @@ export const NitroCardAccordionSetView: FC = pro const closeFunction = close; setClosers(prevValue => - { - const newClosers = [ ...prevValue ]; + { + const newClosers = [ ...prevValue ]; - newClosers.push(closeFunction); + newClosers.push(closeFunction); - return newClosers; - }); + return newClosers; + }); return () => { setClosers(prevValue => - { - const newClosers = [ ...prevValue ]; + { + const newClosers = [ ...prevValue ]; - const index = newClosers.indexOf(closeFunction); + const index = newClosers.indexOf(closeFunction); - if(index >= 0) newClosers.splice(index, 1); + if(index >= 0) newClosers.splice(index, 1); - return newClosers; - }); + return newClosers; + }); } }, [ close, setClosers ]); diff --git a/src/common/draggable-window/DraggableWindow.tsx b/src/common/draggable-window/DraggableWindow.tsx index 498c5878..05813e42 100644 --- a/src/common/draggable-window/DraggableWindow.tsx +++ b/src/common/draggable-window/DraggableWindow.tsx @@ -1,8 +1,7 @@ import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer'; -import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react'; +import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, ReactNode, 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[] = []; @@ -19,6 +18,7 @@ export interface DraggableWindowProps dragStyle?: CSSProperties; offsetLeft?: number; offsetTop?: number; + children?: ReactNode; } export const DraggableWindow: FC = props => @@ -108,8 +108,8 @@ export const DraggableWindow: FC = props => { if(!elementRef.current || !dragHandler) return; - let offsetX = (offset.x + delta.x); - let offsetY = (offset.y + delta.y); + let offsetX = (offset.x + delta.x); + let offsetY = (offset.y + delta.y); const left = elementRef.current.offsetLeft + offsetX; const top = elementRef.current.offsetTop + offsetY; @@ -134,12 +134,9 @@ export const DraggableWindow: FC = props => offsetX = (document.body.offsetWidth - elementRef.current.offsetWidth) - elementRef.current.offsetLeft; } - BatchUpdates(() => - { - setDelta({ x: 0, y: 0 }); - setOffset({ x: offsetX, y: offsetY }); - setIsDragging(false); - }); + 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 +198,8 @@ export const DraggableWindow: FC = props => } } - BatchUpdates(() => - { - setDelta({ x: 0, y: 0 }); - setOffset({ x: offsetX, y: offsetY }); - }); + setDelta({ x: 0, y: 0 }); + setOffset({ x: offsetX, y: offsetY }); return () => { @@ -213,7 +207,7 @@ export const DraggableWindow: FC = props => if(index >= 0) CURRENT_WINDOWS.splice(index, 1); } - }, [ handleSelector, windowPosition, uniqueKey, disableDrag, bringToTop ]); + }, [ handleSelector, windowPosition, uniqueKey, disableDrag, offsetLeft, offsetTop, bringToTop ]); useEffect(() => { @@ -261,8 +255,8 @@ export const DraggableWindow: FC = props => return ( createPortal( - - { children } - , document.getElementById('draggable-windows-container')) + + { children } + , document.getElementById('draggable-windows-container')) ); } diff --git a/src/common/index.scss b/src/common/index.scss index 983d207d..3a08bf3c 100644 --- a/src/common/index.scss +++ b/src/common/index.scss @@ -16,7 +16,7 @@ cursor: not-allowed; img { - opacity: .5; + opacity: 0.5; filter: grayscale(1); } } @@ -30,9 +30,8 @@ } &.has-highlight { - &:after { - content: ''; + content: ""; z-index: 2; position: absolute; top: 0; @@ -48,7 +47,7 @@ .nitro-room-thumbnail-camera { width: 132px; height: 192px; - background-image: url('../assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png'); + background-image: url("../assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png"); .camera-frame { position: absolute; @@ -65,10 +64,10 @@ height: 173px; color: black; pointer-events: all; - + background-position: 0px 0px; - background-image: url('../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png'); - + background-image: url("../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png"); + &.trophy-2 { background-position: 0px 173px; } @@ -103,7 +102,7 @@ .nitro-gift-card { width: 306px; height: 159px; - background: url('../assets/images/gift/gift_tag.png') center no-repeat; + background: url("../assets/images/gift/gift_tag.png") center no-repeat; .gift-face { width: 65px; @@ -111,7 +110,8 @@ .gift-incognito { width: 37px; height: 48px; - background: url('../assets/images/gift/incognito.png') center no-repeat; + background: url("../assets/images/gift/incognito.png") center + no-repeat; } .gift-avatar { @@ -168,17 +168,26 @@ } @-webkit-keyframes sk-bouncedelay { - 0%, 80%, 100% { -webkit-transform: scale(0) } - 40% { -webkit-transform: scale(1.0) } + 0%, + 80%, + 100% { + -webkit-transform: scale(0); + } + 40% { + -webkit-transform: scale(1); + } } - + @keyframes sk-bouncedelay { - 0%, 80%, 100% { - -webkit-transform: scale(0); - transform: scale(0); - } 40% { - -webkit-transform: scale(1.0); - transform: scale(1.0); + 0%, + 80%, + 100% { + -webkit-transform: scale(0); + transform: scale(0); + } + 40% { + -webkit-transform: scale(1); + transform: scale(1); } } @@ -186,27 +195,9 @@ position: relative; width: 110px; height: 110px; - background: url('../assets/images/navigator/thumbnail_placeholder.png') no-repeat center; - background-color: rgba($black, .125); -} - -.nitro-alert { - min-width: 350px; - min-height: 150px; - max-height: 350px; -} - -.nitro-notification-bubble { - pointer-events: all; - padding: 6px 5px; - background-color: rgba($dark,.95); - box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); - font-size: $font-size-sm; - - .bubble-image-container { - width: 50px; - height: 50px; - } + background: url("../assets/images/navigator/thumbnail_placeholder.png") + no-repeat center; + background-color: rgba($black, 0.125); } #draggable-windows-container { @@ -242,7 +233,7 @@ top: 2px; right: 2px; font-size: 9.5px; - padding:2px 3px; + padding: 2px 3px; z-index: 1; } @@ -253,16 +244,6 @@ background-repeat: no-repeat; background-position: center; - &.group-badge { - width: 39px; - height: 39px; - - &.scale-2 { - width: 80px; - height: 80px; - } - } - .badge-information { display: none; } @@ -282,10 +263,10 @@ background: $white; left: -220px; z-index: 100; - + &:before { position: absolute; - content: ' '; + content: " "; width: 0; height: 0; border-left: 10px solid $white; @@ -308,7 +289,7 @@ .nitro-rarity-level { width: 36px; height: 28px; - background: url('../assets/images/infostand/rarity-level.png'); + background: url("../assets/images/infostand/rarity-level.png"); div { line-height: 28px; @@ -325,12 +306,6 @@ background-repeat: no-repeat; background-position: center -8px; pointer-events: none; - image-rendering: pixelated; - - &.scale-0-5, - &.scale-0-75 { - image-rendering: -webkit-optimize-contrast; - } } .pet-image { @@ -356,7 +331,7 @@ background-repeat: no-repeat; background-position: center; overflow: hidden; - + &.border-0 { &::after { content: none; @@ -365,7 +340,7 @@ &::after { position: absolute; - content: ''; + content: ""; top: 0; bottom: 0; left: 0; @@ -373,13 +348,13 @@ border-radius: $border-radius; border-bottom: 2px solid white; border-right: 2px solid white; - box-shadow: -2px -2px rgba(0, 0, 0, .4), inset 3px 3px rgba(0, 0, 0, .2); + box-shadow: -2px -2px rgba(0, 0, 0, 0.4), + inset 3px 3px rgba(0, 0, 0, 0.2); } } } .unique-item { - .unique-bg-override { background-position: center; background-repeat: no-repeat; @@ -388,26 +363,28 @@ &:before { position: absolute; - content: ''; + content: ""; width: 100%; height: 100%; - background: url('../assets/images/unique/grid-bg.png') center no-repeat; + background: url("../assets/images/unique/grid-bg.png") center no-repeat; z-index: 1; } &:after { position: absolute; - content: ''; + content: ""; width: 100%; height: 100%; - background: url('../assets/images/unique/grid-bg-glass.png') center no-repeat; + background: url("../assets/images/unique/grid-bg-glass.png") center + no-repeat; bottom: 0; z-index: 4; } &.sold-out:after { - background: url('../assets/images/unique/grid-bg-sold-out.png') center no-repeat, - url('../assets/images/unique/grid-bg-glass.png') center no-repeat; + background: url("../assets/images/unique/grid-bg-sold-out.png") center + no-repeat, + url("../assets/images/unique/grid-bg-glass.png") center no-repeat; } .unique-item-counter { @@ -418,7 +395,8 @@ bottom: 1px; width: 100%; height: 9px; - background: url('../assets/images/unique/grid-count-bg.png') center no-repeat; + background: url("../assets/images/unique/grid-count-bg.png") center + no-repeat; z-index: 3; } } @@ -426,7 +404,7 @@ .unique-sold-out-blocker { width: 364px; height: 30px; - background: url('../assets/images/unique/catalog-info-sold-out.png'); + background: url("../assets/images/unique/catalog-info-sold-out.png"); div { float: right; @@ -447,7 +425,7 @@ right: 16px; width: 34px; height: 37px; - background: url('../assets/images/unique/inventory-info-amount-bg.png'); + background: url("../assets/images/unique/inventory-info-amount-bg.png"); div { display: flex; @@ -460,7 +438,8 @@ .unique-complete-plate { width: 170px; height: 29px; - background: url('../assets/images/unique/catalog-info-amount-bg.png') no-repeat center; + background: url("../assets/images/unique/catalog-info-amount-bg.png") + no-repeat center; z-index: 1; padding-top: 3px; @@ -481,7 +460,7 @@ outline: 0; height: 5px; margin-right: 1px; - background-image: url('../assets/images/unique/numbers.png'); + background-image: url("../assets/images/unique/numbers.png"); background-repeat: no-repeat; &:last-child { @@ -556,7 +535,12 @@ z-index: 1; transition: all 1s; border-radius: calc(#{$border-radius} / 2); - background: repeating-linear-gradient($tertiary, $tertiary 50%, $quaternary 50%, $quaternary 100%); + background: repeating-linear-gradient( + $tertiary, + $tertiary 50%, + $quaternary 50%, + $quaternary 100% + ); } .nitro-progress-bar-text { @@ -565,4 +549,4 @@ } } -@import './card/NitroCardView'; +@import "./card/NitroCardView"; diff --git a/src/common/layout/LayoutAvatarImageView.tsx b/src/common/layout/LayoutAvatarImageView.tsx index 814b201e..d127bd99 100644 --- a/src/common/layout/LayoutAvatarImageView.tsx +++ b/src/common/layout/LayoutAvatarImageView.tsx @@ -23,29 +23,10 @@ export const LayoutAvatarImageView: FC = props => { const newClassNames: string[] = [ 'avatar-image' ]; - switch(scale) - { - case .5: - newClassNames.push('scale-0-5'); - break; - case .75: - newClassNames.push('scale-0-75'); - break; - case 1.25: - newClassNames.push('scale-1-25'); - break; - case 1.50: - newClassNames.push('scale-1-50'); - break; - default: - newClassNames.push(`scale-${ scale }`); - break; - } - if(classNames.length) newClassNames.push(...classNames); return newClassNames; - }, [ scale, classNames ]); + }, [ classNames ]); const getStyle = useMemo(() => { @@ -53,10 +34,17 @@ export const LayoutAvatarImageView: FC = props => if(avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`; + if(scale !== 1) + { + newStyle.transform = `scale(${ scale })`; + + if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; + } + if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; return newStyle; - }, [ avatarUrl, style ]); + }, [ avatarUrl, scale, style ]); useEffect(() => { @@ -67,7 +55,8 @@ export const LayoutAvatarImageView: FC = props => setRandomValue(Math.random()); }, - dispose: () => {}, + dispose: () => + {}, disposed: false }, null); diff --git a/src/common/layout/LayoutBadgeImageView.tsx b/src/common/layout/LayoutBadgeImageView.tsx index f5b4fadc..3445abc4 100644 --- a/src/common/layout/LayoutBadgeImageView.tsx +++ b/src/common/layout/LayoutBadgeImageView.tsx @@ -16,22 +16,7 @@ export interface LayoutBadgeImageViewProps extends BaseProps export const LayoutBadgeImageView: FC = props => { const { badgeCode = null, isGroup = false, showInfo = false, customTitle = null, isGrayscale = false, scale = 1, classNames = [], style = {}, children = null, ...rest } = props; - const [ badgeUrl, setBadgeUrl ] = useState(''); - - const getScaleClass = useMemo(() => - { - let scaleName = scale.toString(); - - if(scale === .5) scaleName = '0-5'; - - else if(scale === .75) scaleName = '0-75'; - - else if(scale === 1.25) scaleName = '1-25'; - - else if(scale === 1.50) scaleName = '1-50'; - - return `scale-${ scaleName }`; - }, [ scale ]); + const [ imageElement, setImageElement ] = useState(null); const getClassNames = useMemo(() => { @@ -41,23 +26,36 @@ export const LayoutBadgeImageView: FC = props => if(isGrayscale) newClassNames.push('grayscale'); - if((scale !== 1) && getScaleClass.length) newClassNames.push(getScaleClass); - if(classNames.length) newClassNames.push(...classNames); return newClassNames; - }, [ classNames, isGroup, isGrayscale, scale, getScaleClass ]); + }, [ classNames, isGroup, isGrayscale ]); const getStyle = useMemo(() => { let newStyle: CSSProperties = {}; - if(badgeUrl && badgeUrl.length) newStyle.backgroundImage = `url(${ badgeUrl })`; + if(imageElement) + { + newStyle.backgroundImage = `url('${ imageElement.src }')`; + newStyle.width = imageElement.width; + newStyle.height = imageElement.height; + + if(scale !== 1) + { + newStyle.transform = `scale(${ scale })`; + + if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; + + newStyle.width = (imageElement.width * scale); + newStyle.height = (imageElement.height * scale); + } + } if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; return newStyle; - }, [ style, badgeUrl ]); + }, [ imageElement, scale, style ]); useEffect(() => { @@ -69,7 +67,9 @@ export const LayoutBadgeImageView: FC = props => { if(event.badgeId !== badgeCode) return; - setBadgeUrl(TextureUtils.generateImageUrl(new NitroSprite(event.image))); + const element = TextureUtils.generateImage(new NitroSprite(event.image)); + + element.onload = () => setImageElement(element); didSetBadge = true; @@ -80,29 +80,23 @@ export const LayoutBadgeImageView: FC = props => const texture = isGroup ? GetSessionDataManager().getGroupBadgeImage(badgeCode) : GetSessionDataManager().getBadgeImage(badgeCode); - if(texture && !didSetBadge) setBadgeUrl(TextureUtils.generateImageUrl(new NitroSprite(texture))); + if(texture && !didSetBadge) + { + const element = TextureUtils.generateImage(new NitroSprite(texture)); + + element.onload = () => setImageElement(element); + } return () => GetSessionDataManager().events.removeEventListener(BadgeImageReadyEvent.IMAGE_READY, onBadgeImageReadyEvent); }, [ badgeCode, isGroup ]); - const BadgeInformationView = (props: { title: string, description: string }) => - { - const { title = null, description = null } = props; - - if(!GetConfiguration('badge.descriptions.enabled', true)) return null; - - return ( - -
{ title }
-
{ description }
- - ); - }; - return ( - { showInfo && - } + { (showInfo && GetConfiguration('badge.descriptions.enabled', true)) && + +
{ isGroup ? customTitle : LocalizeBadgeName(badgeCode) }
+
{ isGroup ? LocalizeText('group.badgepopup.body') : LocalizeBadgeDescription(badgeCode) }
+ } { children } ); diff --git a/src/common/layout/LayoutFurniIconImageView.tsx b/src/common/layout/LayoutFurniIconImageView.tsx index c961d66f..21bb7601 100644 --- a/src/common/layout/LayoutFurniIconImageView.tsx +++ b/src/common/layout/LayoutFurniIconImageView.tsx @@ -1,7 +1,6 @@ import { FC } from 'react'; import { LayoutImage, LayoutImageProps } from '.'; -import { GetRoomEngine } from '../../api'; -import { ProductTypeEnum } from '../../components/catalog/common/ProductTypeEnum'; +import { GetRoomEngine, ProductTypeEnum } from '../../api'; interface LayoutFurniIconImageViewProps extends LayoutImageProps { @@ -31,5 +30,5 @@ export const LayoutFurniIconImageView: FC = props return imageUrl; } - return ; + return ; } diff --git a/src/common/layout/LayoutFurniImageView.tsx b/src/common/layout/LayoutFurniImageView.tsx index a9d81772..ed14d0af 100644 --- a/src/common/layout/LayoutFurniImageView.tsx +++ b/src/common/layout/LayoutFurniImageView.tsx @@ -1,10 +1,10 @@ import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { GetRoomEngine } from '../../api'; -import { ProductTypeEnum } from '../../components/catalog/common/ProductTypeEnum'; +import { CSSProperties, FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { BaseProps } from '..'; +import { GetRoomEngine, ProductTypeEnum } from '../../api'; import { Base } from '../Base'; -interface LayoutFurniImageViewProps +interface LayoutFurniImageViewProps extends BaseProps { productType: string; productClassId: number; @@ -15,9 +15,32 @@ interface LayoutFurniImageViewProps export const LayoutFurniImageView: FC = props => { - const { productType = 's', productClassId = -1, direction = 0, extraData = '', scale = 1 } = props; + const { productType = 's', productClassId = -1, direction = 2, extraData = '', scale = 1, style = {}, ...rest } = props; const [ imageElement, setImageElement ] = useState(null); + const getStyle = useMemo(() => + { + let newStyle: CSSProperties = {}; + + if(imageElement?.src?.length) + { + newStyle.backgroundImage = `url('${ imageElement.src }')`; + newStyle.width = imageElement.width; + newStyle.height = imageElement.height; + } + + if(scale !== 1) + { + newStyle.transform = `scale(${ scale })`; + + if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; + } + + if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; + + return newStyle; + }, [ imageElement, scale, style ]); + const buildImage = useCallback(() => { let imageResult: ImageResult = null; @@ -60,7 +83,5 @@ export const LayoutFurniImageView: FC = props => if(!imageElement) return null; - const imageUrl = `url('${ imageElement.src }')`; - - return ; + return ; } diff --git a/src/common/layout/LayoutGiftTagView.tsx b/src/common/layout/LayoutGiftTagView.tsx index 0db589b0..8fcc405f 100644 --- a/src/common/layout/LayoutGiftTagView.tsx +++ b/src/common/layout/LayoutGiftTagView.tsx @@ -31,7 +31,7 @@ export const LayoutGiftTagView: FC = props => { editable && (onChange !== null) && } { userName && - { LocalizeText('catalog.gift_wrapping_new.message_from', ['name'], [userName]) } } + { LocalizeText('catalog.gift_wrapping_new.message_from', [ 'name' ], [ userName ]) } } diff --git a/src/common/layout/LayoutNotificationAlertView.tsx b/src/common/layout/LayoutNotificationAlertView.tsx index 4f1a11a0..d4e56d82 100644 --- a/src/common/layout/LayoutNotificationAlertView.tsx +++ b/src/common/layout/LayoutNotificationAlertView.tsx @@ -1,29 +1,33 @@ import { FC, useMemo } from 'react'; +import { NotificationAlertType } from '../../api'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroCardViewProps } from '../card'; export interface LayoutNotificationAlertViewProps extends NitroCardViewProps { title?: string; + type?: string; close: () => void; } export const LayoutNotificationAlertView: FC = props => { - const { title = '', close = null, classNames = [], children = null, ...rest } = props; + const { title = '', close = null, classNames = [], children = null,type = NotificationAlertType.DEFAULT, ...rest } = props; const getClassNames = useMemo(() => { const newClassNames: string[] = [ 'nitro-alert' ]; + + newClassNames.push('nitro-alert-' + type); if(classNames.length) newClassNames.push(...classNames); return newClassNames; - }, [ classNames ]); + }, [ classNames, type ]); return ( - + { children } diff --git a/src/common/layout/LayoutNotificationBubbleView.tsx b/src/common/layout/LayoutNotificationBubbleView.tsx index 59771e7e..5e5fdd9f 100644 --- a/src/common/layout/LayoutNotificationBubbleView.tsx +++ b/src/common/layout/LayoutNotificationBubbleView.tsx @@ -35,11 +35,11 @@ export const LayoutNotificationBubbleView: FC if(!fadesOut) return; const timeout = setTimeout(() => - { - setIsVisible(false); + { + setIsVisible(false); - setTimeout(() => close(), 300); - }, timeoutMs); + setTimeout(() => close(), 300); + }, timeoutMs); return () => clearTimeout(timeout); }, [ fadesOut, timeoutMs, close ]); diff --git a/src/common/layout/LayoutPetImageView.tsx b/src/common/layout/LayoutPetImageView.tsx index ffe6c2d4..6d4677be 100644 --- a/src/common/layout/LayoutPetImageView.tsx +++ b/src/common/layout/LayoutPetImageView.tsx @@ -1,13 +1,14 @@ import { PetCustomPart, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useRef, useState } from 'react'; +import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react'; import { GetRoomEngine } from '../../api'; +import { Base, BaseProps } from '../Base'; -interface LayoutPetImageViewProps +interface LayoutPetImageViewProps extends BaseProps { figure?: string; typeId?: number; paletteId?: number; - color?: number; + petColor?: number; customParts?: PetCustomPart[]; posture?: string; headOnly?: boolean; @@ -17,17 +18,35 @@ interface LayoutPetImageViewProps export const LayoutPetImageView: FC = props => { - const { figure = '', typeId = -1, paletteId = -1, color = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1 } = props; + const { figure = '', typeId = -1, paletteId = -1, petColor = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1, style = {}, ...rest } = props; const [ petUrl, setPetUrl ] = useState(null); const isDisposed = useRef(false); + const getStyle = useMemo(() => + { + let newStyle: CSSProperties = {}; + + if(petUrl && petUrl.length) newStyle.backgroundImage = `url(${ petUrl })`; + + if(scale !== 1) + { + newStyle.transform = `scale(${ scale })`; + + if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; + } + + if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; + + return newStyle; + }, [ petUrl, scale, style ]); + useEffect(() => { let url = null; let petTypeId = typeId; let petPaletteId = paletteId; - let petColor = color; + let petColor1 = petColor; let petCustomParts = customParts; let petHeadOnly = headOnly; @@ -37,13 +56,13 @@ export const LayoutPetImageView: FC = props => petTypeId = petFigureData.typeId; petPaletteId = petFigureData.paletteId; - petColor = petFigureData.color; + petColor1 = petFigureData.color; petCustomParts = petFigureData.customParts; } if(petTypeId === 16) petHeadOnly = false; - const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor, new Vector3d((direction * 45)), 64, { + const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor1, new Vector3d((direction * 45)), 64, { imageReady: (id, texture, image) => { if(isDisposed.current) return; @@ -65,7 +84,7 @@ export const LayoutPetImageView: FC = props => } - }, [ figure, typeId, paletteId, color, customParts, posture, headOnly, direction ]); + }, [ figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction ]); useEffect(() => { @@ -78,6 +97,6 @@ export const LayoutPetImageView: FC = props => }, []); const url = `url('${ petUrl }')`; - - return
; + + return ; } diff --git a/src/common/layout/LayoutProgressBar.tsx b/src/common/layout/LayoutProgressBar.tsx index a8114b75..8f821717 100644 --- a/src/common/layout/LayoutProgressBar.tsx +++ b/src/common/layout/LayoutProgressBar.tsx @@ -25,7 +25,7 @@ export const LayoutProgressBar: FC = props => { text && (text.length > 0) && { text } } - + { children } ); diff --git a/src/common/layout/LayoutRoomPreviewerView.tsx b/src/common/layout/LayoutRoomPreviewerView.tsx index ff2caeb6..a45ca522 100644 --- a/src/common/layout/LayoutRoomPreviewerView.tsx +++ b/src/common/layout/LayoutRoomPreviewerView.tsx @@ -1,16 +1,17 @@ import { ColorConverter, IRoomRenderingCanvas, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer'; -import { FC, MouseEvent, useCallback, useEffect, useRef, useState } from 'react'; +import { FC, MouseEvent, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; import { GetNitroInstance } from '../../api'; export interface LayoutRoomPreviewerViewProps { roomPreviewer: RoomPreviewer; height?: number; + children?: ReactNode; } export const LayoutRoomPreviewerView: FC = props => { - const { roomPreviewer = null, height = 0 } = props; + const { roomPreviewer = null, height = 0, children = null } = props; const [ renderingCanvas, setRenderingCanvas ] = useState(null); const elementRef = useRef(); @@ -74,15 +75,15 @@ export const LayoutRoomPreviewerView: FC = props = GetNitroInstance().ticker.add(update); const resizeObserver = new ResizeObserver(() => - { - if(!roomPreviewer || !elementRef.current) return; + { + if(!roomPreviewer || !elementRef.current) return; - const width = elementRef.current.parentElement.offsetWidth; + const width = elementRef.current.parentElement.offsetWidth; - roomPreviewer.modifyRoomCanvas(width, height); + roomPreviewer.modifyRoomCanvas(width, height); - update(-1); - }); + update(-1); + }); resizeObserver.observe(elementRef.current); @@ -98,7 +99,7 @@ export const LayoutRoomPreviewerView: FC = props = return (
- { props.children } + { children }
); } diff --git a/src/common/layout/UserProfileIconView.tsx b/src/common/layout/UserProfileIconView.tsx index 769cf625..d31fa66b 100644 --- a/src/common/layout/UserProfileIconView.tsx +++ b/src/common/layout/UserProfileIconView.tsx @@ -10,7 +10,7 @@ export interface UserProfileIconViewProps extends BaseProps export const UserProfileIconView: FC = props => { - const { userId = 0, userName = null, classNames = [], pointer = true, children = null, ...rest } = props; + const { userId = 0, userName = null, classNames = [], pointer = true, children = null, ...rest } = props; const getClassNames = useMemo(() => { diff --git a/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx b/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx index 92e939d2..fe34ba41 100644 --- a/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx +++ b/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx @@ -8,15 +8,11 @@ interface LayoutLimitedEditionStyledNumberViewProps export const LayoutLimitedEditionStyledNumberView: FC = props => { const { value = 0 } = props; - const numbers = value.toString().split(''); return ( <> - { numbers.map((number, index) => - { - return ; - })} + { numbers.map((number, index) => ) } ); } diff --git a/src/common/transitions/TransitionAnimation.tsx b/src/common/transitions/TransitionAnimation.tsx index cc3c3d8d..6eefd2df 100644 --- a/src/common/transitions/TransitionAnimation.tsx +++ b/src/common/transitions/TransitionAnimation.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useState } from 'react'; +import { FC, ReactNode, useEffect, useState } from 'react'; import { Transition } from 'react-transition-group'; import { getTransitionAnimationStyle } from './TransitionAnimationStyles'; @@ -8,6 +8,7 @@ interface TransitionAnimationProps inProp: boolean; timeout?: number; className?: string; + children?: ReactNode; } export const TransitionAnimation: FC = props => @@ -45,7 +46,7 @@ export const TransitionAnimation: FC = props =>
{ isChildrenVisible && children }
- )} + ) } ); } diff --git a/src/components/achievements/AchievementsView.tsx b/src/components/achievements/AchievementsView.tsx index 71776720..4b2c38d6 100644 --- a/src/components/achievements/AchievementsView.tsx +++ b/src/components/achievements/AchievementsView.tsx @@ -1,237 +1,69 @@ -import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, ILinkEventTracker, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { AchievementCategory, AddEventLinkTracker, GetAchievementCategoryImageUrl, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api'; +import { ILinkEventTracker } from '@nitrots/nitro-renderer'; +import { FC, useEffect, useMemo, useState } from 'react'; +import { AddEventLinkTracker, GetAchievementCategoryImageUrl, LocalizeText, RemoveLinkEventTracker } 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 { useAchievements } from '../../hooks'; import { AchievementCategoryView } from './views/AchievementCategoryView'; import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView'; export const AchievementsView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); - const [ isInitalized, setIsInitalized ] = useState(false); - const [ achievementCategories, setAchievementCategories ] = useState([]); - const [ selectedCategoryCode, setSelectedCategoryCode ] = useState(null); - const [ achievementScore, setAchievementScore ] = useState(0); + const { achievementCategories = [], selectedCategoryCode = null, setSelectedCategoryCode = null, selectedAchievementId = -1, setSelectedAchievementId = null, achievementScore = 0, getProgress = 0, getMaxProgress = 0, setAchievementSeen = null } = useAchievements(); - const onAchievementEvent = useCallback((event: AchievementEvent) => + const selectedCategory = useMemo(() => { - const parser = event.getParser(); - const achievement = parser.achievement; - const categoryName = achievement.category; + if(selectedCategoryCode === null) return null; - setAchievementCategories(prevValue => - { - const newValue = [ ...prevValue ]; - const categoryIndex = newValue.findIndex(existing => (existing.code === categoryName)); - - if(categoryIndex === -1) - { - const category = new AchievementCategory(categoryName); - - category.achievements.push(achievement); - - newValue.push(category); - } - else - { - const category = newValue[categoryIndex]; - const newAchievements = [ ...category.achievements ]; - const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId)); - let previousAchievement: AchievementData = null; - - if(achievementIndex === -1) - { - newAchievements.push(achievement); - } - else - { - previousAchievement = newAchievements[achievementIndex]; - - newAchievements[achievementIndex] = achievement; - } - - if(!GetAchievementIsIgnored(achievement)) - { - achievement.unseen++; - - if(previousAchievement) achievement.unseen += previousAchievement.unseen; - } - - category.achievements = newAchievements; - } - - return newValue; - }); - }, []); - - UseMessageEventHook(AchievementEvent, onAchievementEvent); - - const onAchievementsEvent = useCallback((event: AchievementsEvent) => - { - const parser = event.getParser(); - - const categories: AchievementCategory[] = []; - - for(const achievement of parser.achievements) - { - const categoryName = achievement.category; - - let existing = categories.find(category => (category.code === categoryName)); - - if(!existing) - { - existing = new AchievementCategory(categoryName); - - categories.push(existing); - } - - existing.achievements.push(achievement); - } - - BatchUpdates(() => - { - setAchievementCategories(categories); - setIsInitalized(true); - }); - }, []); - - UseMessageEventHook(AchievementsEvent, onAchievementsEvent); - - const onAchievementsScoreEvent = useCallback((event: AchievementsScoreEvent) => - { - const parser = event.getParser(); - - setAchievementScore(parser.score); - }, []); - - UseMessageEventHook(AchievementsScoreEvent, onAchievementsScoreEvent); - - const getTotalUnseen = useMemo(() => - { - let unseen = 0; - - for(const category of achievementCategories) - { - for(const achievement of category.achievements) unseen += achievement.unseen; - } - - return unseen; - }, [ achievementCategories ]); - - const getProgress = useMemo(() => - { - let progress = 0; - - for(const category of achievementCategories) progress += category.getProgress(); - - return progress; - }, [ achievementCategories ]); - - const getMaxProgress = useMemo(() => - { - let progress = 0; - - for(const category of achievementCategories) progress += category.getMaxProgress(); - - return progress; - }, [ achievementCategories ]); - - const scaledProgressPercent = useMemo(() => - { - return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0); - }, [ getProgress, getMaxProgress ]); - - const getSelectedCategory = useMemo(() => - { - if(!achievementCategories || !achievementCategories.length) return null; - - return achievementCategories.find(existing => (existing.code === selectedCategoryCode)); + return achievementCategories.find(category => (category.code === selectedCategoryCode)); }, [ achievementCategories, selectedCategoryCode ]); - const setAchievementSeen = useCallback((code: string, achievementId: number) => - { - setAchievementCategories(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const category of newValue) - { - if(category.code !== code) continue; - - for(const achievement of category.achievements) - { - if(achievement.achievementId !== achievementId) continue; - - achievement.unseen = 0; - } - } - - return newValue; - }); - }, []); - - const linkReceived = useCallback((url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, []); - useEffect(() => { const linkTracker: ILinkEventTracker = { - linkReceived, + linkReceived: (url: string) => + { + const parts = url.split('/'); + + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'show': + setIsVisible(true); + return; + case 'hide': + setIsVisible(false); + return; + case 'toggle': + setIsVisible(prevValue => !prevValue); + return; + } + }, eventUrlPrefix: 'achievements/' }; AddEventLinkTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); - }, [ linkReceived ]); + }, []); - useEffect(() => - { - if(!isVisible || isInitalized) return; - - SendMessageComposer(new RequestAchievementsMessageComposer()); - }, [ isVisible, isInitalized ]); - - useEffect(() => - { - DispatchUiEvent(new AchievementsUIUnseenCountEvent(getTotalUnseen)); - }, [ getTotalUnseen ]); - - if(!isVisible || !isInitalized) return null; + if(!isVisible) return null; return ( setIsVisible(false) } /> - { getSelectedCategory && + { selectedCategory && setSelectedCategoryCode(null) } className="nitro-achievements-back-arrow" /> - { LocalizeText(`quests.${ getSelectedCategory.code }.name`) } - { LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ getSelectedCategory.getProgress().toString(), getSelectedCategory.getMaxProgress().toString() ]) } + { LocalizeText(`quests.${ selectedCategory.code }.name`) } + { LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ selectedCategory.getProgress().toString(), selectedCategory.getMaxProgress().toString() ]) } - + } - { !getSelectedCategory && + { !selectedCategory && <> @@ -239,8 +71,8 @@ export const AchievementsView: FC<{}> = props => } - { getSelectedCategory && - } + { selectedCategory && + } ); diff --git a/src/components/achievements/views/AchievementCategoryView.tsx b/src/components/achievements/views/AchievementCategoryView.tsx index e8a20579..d5834c7c 100644 --- a/src/components/achievements/views/AchievementCategoryView.tsx +++ b/src/components/achievements/views/AchievementCategoryView.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useMemo, useState } from 'react'; +import { Dispatch, FC, SetStateAction, useEffect, useMemo } from 'react'; import { AchievementCategory } from '../../../api'; import { Column } from '../../../common'; import { AchievementListView } from './achievement-list/AchievementListView'; @@ -7,40 +7,44 @@ import { AchievementDetailsView } from './AchievementDetailsView'; interface AchievementCategoryViewProps { category: AchievementCategory; + selectedAchievementId: number; + setSelectedAchievementId: Dispatch>; setAchievementSeen: (code: string, achievementId: number) => void; } export const AchievementCategoryView: FC = props => { - const { category = null, setAchievementSeen = null } = props; - const [ selectedAchievementId, setSelectedAchievementId ] = useState(0); + const { category = null, selectedAchievementId = -1, setSelectedAchievementId = null, setAchievementSeen = null } = props; - const getSelectedAchievement = useMemo(() => + const selectedAchievement = useMemo(() => { - if(!category || !category.achievements.length) return null; + if(selectedAchievementId === -1) return null; - return category.achievements.find(existing => (existing.achievementId === selectedAchievementId)); + return category.achievements.find(achievement => (achievement.achievementId === selectedAchievementId)); }, [ category, selectedAchievementId ]); useEffect(() => { - setSelectedAchievementId((!category || !category.achievements.length) ? 0 : category.achievements[0].achievementId); - }, [ category ]); + if(!selectedAchievement) + { + if(category.achievements.length) setSelectedAchievementId(category.achievements[0].achievementId); + } + }, [ selectedAchievement, category, setSelectedAchievementId ]); useEffect(() => { - if(!getSelectedAchievement || !getSelectedAchievement.unseen) return; + if(!selectedAchievement) return; - setAchievementSeen(category.code, getSelectedAchievement.achievementId); - }, [ category, getSelectedAchievement, setAchievementSeen ]); + setAchievementSeen(category.code, selectedAchievement.achievementId); + }, [ selectedAchievement, category, setAchievementSeen ]); if(!category) return null; return ( - { getSelectedAchievement && - } + { !!selectedAchievement && + } ); } diff --git a/src/components/achievements/views/AchievementDetailsView.tsx b/src/components/achievements/views/AchievementDetailsView.tsx index 64532f52..2503098e 100644 --- a/src/components/achievements/views/AchievementDetailsView.tsx +++ b/src/components/achievements/views/AchievementDetailsView.tsx @@ -1,5 +1,5 @@ import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { GetAchievementBadgeCode, GetAchievementLevel, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../api'; import { Column, Flex, LayoutCurrencyIcon, LayoutProgressBar, Text } from '../../../common'; import { AchievementBadgeView } from './AchievementBadgeView'; @@ -9,14 +9,14 @@ interface AchievementDetailsViewProps achievement: AchievementData; } -export const AchievementDetailsView: FC = props => +export const AchievementDetailsView: FC> = props => { - const { achievement = null } = props; + const { achievement = null, children = null, ...rest } = props; if(!achievement) return null; return ( - + @@ -48,6 +48,7 @@ export const AchievementDetailsView: FC = props => } } + { children } ) } diff --git a/src/components/achievements/views/achievement-list/AchievementListItemView.tsx b/src/components/achievements/views/achievement-list/AchievementListItemView.tsx index 0041783b..bf686088 100644 --- a/src/components/achievements/views/achievement-list/AchievementListItemView.tsx +++ b/src/components/achievements/views/achievement-list/AchievementListItemView.tsx @@ -1,21 +1,23 @@ import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LayoutGridItem, LayoutGridItemProps } from '../../../../common'; +import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react'; +import { LayoutGridItem } from '../../../../common'; import { AchievementBadgeView } from '../AchievementBadgeView'; -interface AchievementListItemViewProps extends LayoutGridItemProps +interface AchievementListItemViewProps { achievement: AchievementData; + selectedAchievementId: number; + setSelectedAchievementId: Dispatch>; } -export const AchievementListItemView: FC = props => +export const AchievementListItemView: FC> = props => { - const { achievement = null, children = null, ...rest } = props; + const { achievement = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props; if(!achievement) return null; return ( - + 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } { ...rest }> { children } diff --git a/src/components/achievements/views/achievement-list/AchievementListView.tsx b/src/components/achievements/views/achievement-list/AchievementListView.tsx index bad0ffe9..341af280 100644 --- a/src/components/achievements/views/achievement-list/AchievementListView.tsx +++ b/src/components/achievements/views/achievement-list/AchievementListView.tsx @@ -1,22 +1,22 @@ import { AchievementData } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, SetStateAction } from 'react'; +import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react'; import { AutoGrid } from '../../../../common'; import { AchievementListItemView } from './AchievementListItemView'; -export interface AchievementListViewProps +interface AchievementListViewProps { achievements: AchievementData[]; selectedAchievementId: number; setSelectedAchievementId: Dispatch>; } -export const AchievementListView: FC = props => +export const AchievementListView: FC> = props => { - const { achievements = null, selectedAchievementId = 0, setSelectedAchievementId = null, children = null } = props; + const { achievements = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props; return ( - - { achievements && (achievements.length > 0) && achievements.map((achievement, index) => 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } />) } + + { achievements && (achievements.length > 0) && achievements.map((achievement, index) => ) } { children } ); diff --git a/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx b/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx index 92661d9c..118b357f 100644 --- a/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx +++ b/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx @@ -1,15 +1,19 @@ -import { FC } from 'react'; +import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react'; import { GetAchievementCategoryImageUrl, GetAchievementCategoryMaxProgress, GetAchievementCategoryProgress, GetAchievementCategoryTotalUnseen, IAchievementCategory, LocalizeText } from '../../../../api'; -import { LayoutBackgroundImage, LayoutGridItem, LayoutGridItemProps, Text } from '../../../../common'; +import { LayoutBackgroundImage, LayoutGridItem, Text } from '../../../../common'; -export interface AchievementCategoryListItemViewProps extends LayoutGridItemProps +interface AchievementCategoryListItemViewProps { category: IAchievementCategory; + selectedCategoryCode: string; + setSelectedCategoryCode: Dispatch>; } -export const AchievementsCategoryListItemView: FC = props => +export const AchievementsCategoryListItemView: FC> = props => { - const { category = null, children = null, ...rest } = props; + const { category = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props; + + if(!category) return null; const progress = GetAchievementCategoryProgress(category); const maxProgress = GetAchievementCategoryMaxProgress(category); @@ -17,9 +21,9 @@ export const AchievementsCategoryListItemView: FC - { LocalizeText(`quests.${ category.code }.name`) } - + setSelectedCategoryCode(category.code) } { ...rest }> + { LocalizeText(`quests.${ category.code }.name`) } + { progress } / { maxProgress } { children } diff --git a/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx b/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx index f77dabbf..231cd4f4 100644 --- a/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx +++ b/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx @@ -1,22 +1,22 @@ -import { Dispatch, FC, SetStateAction } from 'react'; +import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react'; import { IAchievementCategory } from '../../../../api'; -import { AutoGrid, AutoGridProps } from '../../../../common'; +import { AutoGrid } from '../../../../common'; import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView'; -export interface AchievementsCategoryListViewProps extends AutoGridProps +interface AchievementsCategoryListViewProps { categories: IAchievementCategory[]; selectedCategoryCode: string; setSelectedCategoryCode: Dispatch>; } -export const AchievementsCategoryListView: FC = props => +export const AchievementsCategoryListView: FC> = props => { - const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null, columnCount = 3, columnMinWidth = 90, columnMinHeight = 100, children = null, ...rest } = props; + const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props; return ( - - { categories && (categories.length > 0) && categories.map((category, index) => setSelectedCategoryCode(category.code) } /> ) } + + { categories && (categories.length > 0) && categories.map((category, index) => ) } { children } ); diff --git a/src/components/avatar-editor/AvatarEditorView.tsx b/src/components/avatar-editor/AvatarEditorView.tsx index 98aa2d81..5ab1bd60 100644 --- a/src/components/avatar-editor/AvatarEditorView.tsx +++ b/src/components/avatar-editor/AvatarEditorView.tsx @@ -288,15 +288,15 @@ export const AvatarEditorView: FC<{}> = props => setIsVisible(false) } /> { categories && (categories.size > 0) && Array.from(categories.keys()).map(category => - { - const isActive = (activeCategory && (activeCategory.name === category)); + { + const isActive = (activeCategory && (activeCategory.name === category)); - return ( - selectCategory(category) }> - { LocalizeText(`avatareditor.category.${ category }`) } - - ); - })} + return ( + selectCategory(category) }> + { LocalizeText(`avatareditor.category.${ category }`) } + + ); + }) } setIsWardrobeVisible(true) }> { LocalizeText('avatareditor.category.wardrobe') } diff --git a/src/components/avatar-editor/common/AvatarEditorGridPartItem.ts b/src/components/avatar-editor/common/AvatarEditorGridPartItem.ts index 285cbcad..a277b5ad 100644 --- a/src/components/avatar-editor/common/AvatarEditorGridPartItem.ts +++ b/src/components/avatar-editor/common/AvatarEditorGridPartItem.ts @@ -5,8 +5,8 @@ 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 DRAW_ORDER: string[] = [ + private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ]; + private static DRAW_ORDER: string[] = [ AvatarFigurePartType.LEFT_HAND_ITEM, AvatarFigurePartType.LEFT_HAND, AvatarFigurePartType.LEFT_SLEEVE, @@ -201,13 +201,13 @@ export class AvatarEditorGridPartItem implements IAvatarImageListener if(this._partSet) { - this._isHC = (this._partSet.clubLevel > 0); - this._isSellable = this._partSet.isSellable; + this._isHC = (this._partSet.clubLevel > 0); + this._isSellable = this._partSet.isSellable; } else { - this._isHC = false; - this._isSellable = false; + this._isHC = false; + this._isSellable = false; } if(this._isDisabled) this.setAlpha(container, 0.2); diff --git a/src/components/avatar-editor/common/CategoryBaseModel.ts b/src/components/avatar-editor/common/CategoryBaseModel.ts index 5cd311c0..34dd9330 100644 --- a/src/components/avatar-editor/common/CategoryBaseModel.ts +++ b/src/components/avatar-editor/common/CategoryBaseModel.ts @@ -11,7 +11,7 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel constructor() { - this._isInitalized = false; + this._isInitalized = false; this._maxPaletteCount = 0; } diff --git a/src/components/avatar-editor/common/FigureData.ts b/src/components/avatar-editor/common/FigureData.ts index 072ced1c..78014d11 100644 --- a/src/components/avatar-editor/common/FigureData.ts +++ b/src/components/avatar-editor/common/FigureData.ts @@ -199,8 +199,8 @@ export class FigureData { let figureString = ''; - const setTypes: string[] = [ FigureData.FACE ]; - const figureSets: string[] = []; + const setTypes: string[] = [ FigureData.FACE ]; + const figureSets: string[] = []; for(const setType of setTypes) { diff --git a/src/components/avatar-editor/common/FigureGenerator.ts b/src/components/avatar-editor/common/FigureGenerator.ts index fa4126ed..30ac1385 100644 --- a/src/components/avatar-editor/common/FigureGenerator.ts +++ b/src/components/avatar-editor/common/FigureGenerator.ts @@ -26,11 +26,11 @@ function getRandomPartSet(setType: SetType, gender: string, clubLevel: number = if(!setType) return null; const options = setType.partSets.getValues().filter(option => - { - if(!option.isSelectable || ((option.gender !== 'U') && (option.gender !== gender)) || (option.clubLevel > clubLevel) || (option.isSellable && (figureSetIds.indexOf(option.id) === -1))) return null; + { + if(!option.isSelectable || ((option.gender !== 'U') && (option.gender !== gender)) || (option.clubLevel > clubLevel) || (option.isSellable && (figureSetIds.indexOf(option.id) === -1))) return null; - return option; - }); + return option; + }); if(!options || !options.length) return null; @@ -42,11 +42,11 @@ function getRandomColors(palette: IPalette, partSet: IFigurePartSet, clubLevel: if(!palette) return []; const options = palette.colors.getValues().filter(option => - { - if(!option.isSelectable || (option.clubLevel > clubLevel)) return null; + { + if(!option.isSelectable || (option.clubLevel > clubLevel)) return null; - return option; - }); + return option; + }); if(!options || !options.length) return null; diff --git a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx b/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx index 12d9c153..9bc42217 100644 --- a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx +++ b/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx @@ -1,4 +1,5 @@ import { FC, useCallback, useEffect, useState } from 'react'; +import { GetConfiguration } from '../../../../api'; import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; import { AvatarEditorGridPartItem } from '../../common/AvatarEditorGridPartItem'; import { AvatarEditorIcon } from '../AvatarEditorIcon'; @@ -13,6 +14,8 @@ export const AvatarEditorFigureSetItemView: FC('hc.disabled', false); + const rerender = useCallback(() => { setUpdateId(prevValue => (prevValue + 1)); @@ -30,7 +33,7 @@ export const AvatarEditorFigureSetItemView: FC - { partItem.isHC && } + { !hcDisabled && partItem.isHC && } { partItem.isClear && } { partItem.isSellable && } { children } diff --git a/src/components/avatar-editor/views/model/AvatarEditorModelView.tsx b/src/components/avatar-editor/views/model/AvatarEditorModelView.tsx index c1d11164..ea9cbda7 100644 --- a/src/components/avatar-editor/views/model/AvatarEditorModelView.tsx +++ b/src/components/avatar-editor/views/model/AvatarEditorModelView.tsx @@ -67,16 +67,16 @@ export const AvatarEditorModelView: FC = props => } - { !model.canSetGender && model.categories && (model.categories.size > 0) && Array.from(model.categories.keys()).map(name => - { - const category = model.categories.get(name); + { !model.canSetGender && model.categories && (model.categories.size > 0) && Array.from(model.categories.keys()).map(name => + { + const category = model.categories.get(name); - return ( - selectCategory(name) }> - - - ); - })} + return ( + selectCategory(name) }> + + + ); + }) } diff --git a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx b/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx index 94ebb40c..2933c244 100644 --- a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx +++ b/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx @@ -1,4 +1,5 @@ import { FC, useCallback, useEffect, useState } from 'react'; +import { GetConfiguration } from '../../../../api'; import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem'; @@ -12,6 +13,8 @@ export const AvatarEditorPaletteSetItem: FC = p const { colorItem = null, children = null, ...rest } = props; const [ updateId, setUpdateId ] = useState(-1); + const hcDisabled = GetConfiguration('hc.disabled', false); + const rerender = useCallback(() => { setUpdateId(prevValue => (prevValue + 1)); @@ -26,7 +29,7 @@ export const AvatarEditorPaletteSetItem: FC = p return ( - { colorItem.isHC && } + { !hcDisabled && colorItem.isHC && } { children } ); diff --git a/src/components/avatar-editor/views/wardrobe/AvatarEditorWardrobeView.tsx b/src/components/avatar-editor/views/wardrobe/AvatarEditorWardrobeView.tsx index e050b57c..6efea5ed 100644 --- a/src/components/avatar-editor/views/wardrobe/AvatarEditorWardrobeView.tsx +++ b/src/components/avatar-editor/views/wardrobe/AvatarEditorWardrobeView.tsx @@ -1,6 +1,6 @@ import { IAvatarFigureContainer, SaveWardrobeOutfitMessageComposer } from '@nitrots/nitro-renderer'; import { Dispatch, FC, SetStateAction, useCallback, useMemo } from 'react'; -import { GetAvatarRenderManager, GetClubMemberLevel, LocalizeText, SendMessageComposer } from '../../../../api'; +import { GetAvatarRenderManager, GetClubMemberLevel, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../../api'; import { AutoGrid, Base, Button, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, LayoutGridItem } from '../../../../common'; import { FigureData } from '../../common/FigureData'; @@ -16,6 +16,8 @@ export const AvatarEditorWardrobeView: FC = props { const { figureData = null, savedFigures = [], setSavedFigures = null, loadAvatarInEditor = null } = props; + const hcDisabled = GetConfiguration('hc.disabled', false); + const wearFigureAtIndex = useCallback((index: number) => { if((index >= savedFigures.length) || (index < 0)) return; @@ -47,28 +49,28 @@ export const AvatarEditorWardrobeView: FC = props const items: JSX.Element[] = []; savedFigures.forEach(([ figureContainer, gender ], index) => - { - let clubLevel = 0; + { + let clubLevel = 0; - if(figureContainer) clubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender); + if(figureContainer) clubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender); - items.push( - + items.push( + + { figureContainer && + } + + { !hcDisabled && (clubLevel > 0) && } + + { figureContainer && - } - - { (clubLevel > 0) && } - - - { figureContainer && - } - - - ); - }); + } + + + ); + }); return items; - }, [ savedFigures, saveFigureAtWardrobeIndex, wearFigureAtIndex ]); + }, [ savedFigures, hcDisabled, saveFigureAtWardrobeIndex, wearFigureAtIndex ]); return ( diff --git a/src/components/camera/CameraWidgetView.scss b/src/components/camera/CameraWidgetView.scss index 6ad9b68a..18b18d8a 100644 --- a/src/components/camera/CameraWidgetView.scss +++ b/src/components/camera/CameraWidgetView.scss @@ -7,15 +7,20 @@ border-radius: $border-radius; box-shadow: 0 0 0 1.5px $white; border: 2px solid #921911; - background: repeating-linear-gradient(rgba(245,80,65,1), rgba(245,80,65,1) 50%, rgba(194,48,39,1) 50%, rgba(194,48,39,1) 100%); + background: repeating-linear-gradient( + rgba(245, 80, 65, 1), + rgba(245, 80, 65, 1) 50%, + rgba(194, 48, 39, 1) 50%, + rgba(194, 48, 39, 1) 100% + ); cursor: pointer; line-height: 1; padding: 1px 3px; - + &:hover { filter: brightness(1.2); } - + &:active { filter: brightness(0.8); } @@ -28,42 +33,41 @@ width: 320px; height: 320px; } - + .camera-canvas { position: relative; width: 340px; height: 462px; - background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); + background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png"); background-position: -1px -1px; z-index: 2; - + .camera-button { width: 94px; height: 94px; cursor: pointer; margin-top: 362px; - - background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); + + background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png"); background-position: -343px -321px; - + &:hover { background-position: -535px -321px; } - + &:active { background-position: -439px -321px; } } .camera-view-finder { - background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); + background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png"); background-position: -343px -1px; } .camera-frame { - .camera-frame-preview-actions { - background: rgba(0, 0, 0, .5); + background: rgba(0, 0, 0, 0.5); } } } @@ -80,6 +84,8 @@ width: 56px; height: 56px; border: 1px solid black; + object-fit: contain; + image-rendering: initial; } } } @@ -87,7 +93,7 @@ .nitro-camera-editor { width: $camera-editor-width; height: $camera-editor-height; - + .picture-preview { width: 320px; height: 320px; @@ -99,7 +105,6 @@ } .effect-thumbnail-image { - img { width: 50px; height: 50px; diff --git a/src/components/camera/CameraWidgetView.tsx b/src/components/camera/CameraWidgetView.tsx index aab9d341..89118329 100644 --- a/src/components/camera/CameraWidgetView.tsx +++ b/src/components/camera/CameraWidgetView.tsx @@ -70,13 +70,13 @@ export const CameraWidgetView: FC<{}> = props => return; case 'delete': setCameraRoll(prevValue => - { - const clone = [ ...prevValue ]; + { + const clone = [ ...prevValue ]; - clone.splice(selectedPictureIndex, 1); + clone.splice(selectedPictureIndex, 1); - return clone; - }); + return clone; + }); return; case 'editor_cancel': setMode(MODE_CAPTURE); @@ -106,10 +106,10 @@ export const CameraWidgetView: FC<{}> = props => return; case 'toggle': setMode(prevValue => - { - if(!prevValue) return MODE_CAPTURE; - else return MODE_NONE; - }); + { + if(!prevValue) return MODE_CAPTURE; + else return MODE_NONE; + }); return; } }, []); diff --git a/src/components/camera/common/CameraPicture.ts b/src/components/camera/common/CameraPicture.ts index 8d9401b6..fe8c2210 100644 --- a/src/components/camera/common/CameraPicture.ts +++ b/src/components/camera/common/CameraPicture.ts @@ -4,5 +4,6 @@ export class CameraPicture { constructor( public texture: NitroTexture, - public imageUrl: string) {} + public imageUrl: string) + {} } diff --git a/src/components/camera/common/CameraPictureThumbnail.ts b/src/components/camera/common/CameraPictureThumbnail.ts index d88f9dcd..cd126607 100644 --- a/src/components/camera/common/CameraPictureThumbnail.ts +++ b/src/components/camera/common/CameraPictureThumbnail.ts @@ -2,5 +2,6 @@ export class CameraPictureThumbnail { constructor( public effectName: string, - public thumbnailUrl: string) {} + public thumbnailUrl: string) + {} } diff --git a/src/components/camera/views/capture/CameraWidgetCaptureView.tsx b/src/components/camera/views/capture/CameraWidgetCaptureView.tsx index a7f16f60..07a3ded1 100644 --- a/src/components/camera/views/capture/CameraWidgetCaptureView.tsx +++ b/src/components/camera/views/capture/CameraWidgetCaptureView.tsx @@ -80,9 +80,9 @@ export const CameraWidgetCaptureView: FC = props = { (cameraRoll.length > 0) && { cameraRoll.map((picture, index) => - { - return setSelectedPictureIndex(index) } />; - }) } + { + return setSelectedPictureIndex(index) } />; + }) } } diff --git a/src/components/camera/views/checkout/CameraWidgetCheckoutView.tsx b/src/components/camera/views/checkout/CameraWidgetCheckoutView.tsx index 0125e0c4..cd10dcd3 100644 --- a/src/components/camera/views/checkout/CameraWidgetCheckoutView.tsx +++ b/src/components/camera/views/checkout/CameraWidgetCheckoutView.tsx @@ -1,9 +1,8 @@ import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api'; +import { CreateLinkEvent, 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 { UseMessageEventHook } from '../../../../hooks'; export interface CameraWidgetCheckoutViewProps { @@ -27,11 +26,8 @@ export const CameraWidgetCheckoutView: FC = props const onCameraPurchaseOKMessageEvent = useCallback((event: CameraPurchaseOKMessageEvent) => { - BatchUpdates(() => - { - setPicturesBought(value => (value + 1)); - setIsWaiting(false); - }); + setPicturesBought(value => (value + 1)); + setIsWaiting(false); }, []); UseMessageEventHook(CameraPurchaseOKMessageEvent, onCameraPurchaseOKMessageEvent); @@ -40,13 +36,10 @@ export const CameraWidgetCheckoutView: FC = props { const parser = event.getParser(); - BatchUpdates(() => - { - setPublishUrl(parser.extraDataId); - setPublishCooldown(parser.secondsToWait); - setWasPicturePublished(parser.ok); - setIsWaiting(false); - }); + setPublishUrl(parser.extraDataId); + setPublishCooldown(parser.secondsToWait); + setWasPicturePublished(parser.ok); + setIsWaiting(false); }, []); UseMessageEventHook(CameraPublishStatusMessageEvent, onCameraPublishStatusMessageEvent); @@ -128,7 +121,7 @@ export const CameraWidgetCheckoutView: FC = props { (picturesBought > 0) && { LocalizeText('camera.purchase.count.info') } { picturesBought } - DispatchUiEvent(new InventoryEvent(InventoryEvent.SHOW_INVENTORY)) }>{ LocalizeText('camera.open.inventory') } + CreateLinkEvent('inventory/toggle') }>{ LocalizeText('camera.open.inventory') } } diff --git a/src/components/camera/views/editor/CameraWidgetEditorView.tsx b/src/components/camera/views/editor/CameraWidgetEditorView.tsx index e1b70a25..18f1da98 100644 --- a/src/components/camera/views/editor/CameraWidgetEditorView.tsx +++ b/src/components/camera/views/editor/CameraWidgetEditorView.tsx @@ -76,14 +76,14 @@ export const CameraWidgetEditorView: FC = props => if(index === -1) return; setSelectedEffects(prevValue => - { - const clone = [ ...prevValue ]; - const currentEffect = clone[index]; + { + const clone = [ ...prevValue ]; + const currentEffect = clone[index]; - clone[getCurrentEffectIndex] = new RoomCameraWidgetSelectedEffect(currentEffect.effect, alpha); + clone[getCurrentEffectIndex] = new RoomCameraWidgetSelectedEffect(currentEffect.effect, alpha); - return clone; - }); + return clone; + }); }, [ getCurrentEffectIndex, setSelectedEffects ]); const getCurrentPictureUrl = useMemo(() => @@ -117,9 +117,9 @@ export const CameraWidgetEditorView: FC = props => if(!effect) return; setSelectedEffects(prevValue => - { - return [ ...prevValue, new RoomCameraWidgetSelectedEffect(effect, 1) ]; - }); + { + return [ ...prevValue, new RoomCameraWidgetSelectedEffect(effect, 1) ]; + }); setSelectedEffectName(effect.name); return; @@ -130,13 +130,13 @@ export const CameraWidgetEditorView: FC = props => if(existingIndex === -1) return; setSelectedEffects(prevValue => - { - const clone = [ ...prevValue ]; + { + const clone = [ ...prevValue ]; - clone.splice(existingIndex, 1); + clone.splice(existingIndex, 1); - return clone; - }); + return clone; + }); if(selectedEffectName === effectName) setSelectedEffectName(null); return; @@ -177,9 +177,9 @@ export const CameraWidgetEditorView: FC = props => processAction('close') } /> { TABS.map(tab => - { - return processAction('change_tab', tab) }> - }) } + { + return processAction('change_tab', tab) }> + }) } diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx index 3c007676..faf8cea6 100644 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx +++ b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx @@ -1,6 +1,6 @@ import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; import { FC } from 'react'; -import { AutoGrid } from '../../../../../common/AutoGrid'; +import { Grid } from '../../../../../common'; import { CameraPictureThumbnail } from '../../../common/CameraPictureThumbnail'; import { CameraWidgetEffectListItemView } from './CameraWidgetEffectListItemView'; @@ -18,14 +18,14 @@ export const CameraWidgetEffectListView: FC = p const { myLevel = 0, selectedEffects = [], effects = [], thumbnails = [], processAction = null } = props; return ( - + { effects && (effects.length > 0) && effects.map((effect, index) => - { - const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name))); - const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1); + { + const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name))); + const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1); - return myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } /> - }) } - + return myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } /> + }) } + ); } diff --git a/src/components/campaign/CalendarItemView.tsx b/src/components/campaign/CalendarItemView.tsx index 33df1ff7..7a745c18 100644 --- a/src/components/campaign/CalendarItemView.tsx +++ b/src/components/campaign/CalendarItemView.tsx @@ -33,7 +33,7 @@ export const CalendarItemView: FC = props => } return ( - onClick(itemId) }> + onClick(itemId) }> { (state === CalendarItemState.STATE_UNLOCKED) && diff --git a/src/components/campaign/CalendarView.tsx b/src/components/campaign/CalendarView.tsx index ba6e711e..48538fe3 100644 --- a/src/components/campaign/CalendarView.tsx +++ b/src/components/campaign/CalendarView.tsx @@ -104,7 +104,7 @@ export const CalendarView: FC = props => - { LocalizeText('campaign.calendar.heading.day', ['number'], [(selectedDay + 1).toString()]) } + { LocalizeText('campaign.calendar.heading.day', [ 'number' ], [ (selectedDay + 1).toString() ]) } { dayMessage(selectedDay) }
@@ -121,16 +121,16 @@ export const CalendarView: FC = props => - { [...Array(TOTAL_SHOWN_ITEMS)].map((e, i) => - { - const day = (index + i); + { [ ...Array(TOTAL_SHOWN_ITEMS) ].map((e, i) => + { + const day = (index + i); - return ( - - - - ); - }) } + return ( + + + + ); + }) } diff --git a/src/components/campaign/CampaignView.tsx b/src/components/campaign/CampaignView.tsx index f34af2d2..3a8964a7 100644 --- a/src/components/campaign/CampaignView.tsx +++ b/src/components/campaign/CampaignView.tsx @@ -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 => @@ -31,28 +31,25 @@ export const CampaignView: FC<{}> = props => if(parser.doorOpened) { - BatchUpdates(() => + setCalendarData(prev => { - setCalendarData(prev => - { - const copy = prev.clone(); - copy.openedDays.push(lastOpenAttempt); - - return copy; - }); - - setReceivedProducts(prev => - { - const copy = new Map(prev); - copy.set(lastAttempt, new CalendarItem(parser.productName, parser.customImage,parser.furnitureClassName)); - - return copy; - }); + const copy = prev.clone(); + copy.openedDays.push(lastOpenAttempt); + + return copy; + }); + + setReceivedProducts(prev => + { + const copy = new Map(prev); + copy.set(lastAttempt, new CalendarItem(parser.productName, parser.customImage,parser.furnitureClassName)); + + 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,12 +98,12 @@ export const CampaignView: FC<{}> = props => { RemoveLinkEventTracker(linkTracker); } - }, [onLinkReceived]); + }, [ onLinkReceived ]); return ( <> - {(calendarData && isCalendarOpen) && - + { (calendarData && isCalendarOpen) && + } ) diff --git a/src/components/catalog/CatalogContext.tsx b/src/components/catalog/CatalogContext.tsx deleted file mode 100644 index 6d6f9492..00000000 --- a/src/components/catalog/CatalogContext.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { FrontPageItem, RoomPreviewer } from '@nitrots/nitro-renderer'; -import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react'; -import { ICatalogNode } from './common/ICatalogNode'; -import { ICatalogOptions } from './common/ICatalogOptions'; -import { ICatalogPage } from './common/ICatalogPage'; -import { IPageLocalization } from './common/IPageLocalization'; -import { IPurchasableOffer } from './common/IPurchasableOffer'; -import { IPurchaseOptions } from './common/IPurchaseOptions'; -import { SearchResult } from './common/SearchResult'; - -interface ICatalogContext -{ - isVisible: boolean; - isBusy: boolean; - setIsBusy: Dispatch>; - pageId: number; - currentType: string; - setCurrentType: Dispatch>; - rootNode: ICatalogNode; - setRootNode: Dispatch>; - offersToNodes: Map; - setOffersToNodes: Dispatch>>; - currentPage: ICatalogPage; - setCurrentPage: Dispatch>; - currentOffer: IPurchasableOffer; - setCurrentOffer: Dispatch>; - activeNodes: ICatalogNode[]; - setActiveNodes: Dispatch>; - searchResult: SearchResult; - setSearchResult: Dispatch>; - frontPageItems: FrontPageItem[]; - setFrontPageItems: Dispatch>; - roomPreviewer: RoomPreviewer; - purchaseOptions: IPurchaseOptions; - setPurchaseOptions: Dispatch>; - catalogOptions: ICatalogOptions; - setCatalogOptions: Dispatch>; - resetState: () => void; - getNodesByOfferId: (offerId: number, flag?: boolean) => ICatalogNode[]; - loadCatalogPage: (pageId: number, offerId: number) => void; - showCatalogPage: (pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], offerId: number, acceptSeasonCurrencyAsCredits: boolean) => void; - activateNode: (targetNode: ICatalogNode) => void; -} - -const CatalogContext = createContext({ - isVisible: null, - isBusy: null, - setIsBusy: null, - pageId: null, - currentType: null, - setCurrentType: null, - rootNode: null, - setRootNode: null, - offersToNodes: null, - setOffersToNodes: null, - currentPage: null, - setCurrentPage: null, - currentOffer: null, - setCurrentOffer: null, - activeNodes: null, - setActiveNodes: null, - searchResult: null, - setSearchResult: null, - frontPageItems: null, - setFrontPageItems: null, - roomPreviewer: null, - purchaseOptions: null, - setPurchaseOptions: null, - catalogOptions: null, - setCatalogOptions: null, - resetState: null, - getNodesByOfferId: null, - loadCatalogPage: null, - showCatalogPage: null, - activateNode: null -}); - -export const CatalogContextProvider: FC> = props => -{ - return { props.children } -} - -export const useCatalogContext = () => useContext(CatalogContext); diff --git a/src/components/catalog/CatalogMessageHandler.tsx b/src/components/catalog/CatalogMessageHandler.tsx deleted file mode 100644 index 3e3e2552..00000000 --- a/src/components/catalog/CatalogMessageHandler.tsx +++ /dev/null @@ -1,317 +0,0 @@ -import { ApproveNameMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, ClubGiftInfoEvent, GiftReceiverNotFoundEvent, GiftWrappingConfigurationEvent, HabboClubOffersMessageEvent, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, SellablePetPalettesMessageEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer'; -import { GuildMembershipsMessageEvent } from '@nitrots/nitro-renderer/src/nitro/communication/messages/incoming/user/GuildMembershipsMessageEvent'; -import { FC, useCallback } from 'react'; -import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, NotificationAlertType, NotificationUtilities } from '../../api'; -import { CatalogGiftReceiverNotFoundEvent, CatalogNameResultEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../events'; -import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks'; -import { useCatalogContext } from './CatalogContext'; -import { CatalogNode } from './common/CatalogNode'; -import { CatalogPetPalette } from './common/CatalogPetPalette'; -import { CatalogType } from './common/CatalogType'; -import { GiftWrappingConfiguration } from './common/GiftWrappingConfiguration'; -import { ICatalogNode } from './common/ICatalogNode'; -import { IProduct } from './common/IProduct'; -import { IPurchasableOffer } from './common/IPurchasableOffer'; -import { Offer } from './common/Offer'; -import { PageLocalization } from './common/PageLocalization'; -import { Product } from './common/Product'; -import { ProductTypeEnum } from './common/ProductTypeEnum'; -import { SubscriptionInfo } from './common/SubscriptionInfo'; - -export const CatalogMessageHandler: FC<{}> = props => -{ - const { setIsBusy, pageId, currentType, setRootNode, setOffersToNodes, currentPage, setCurrentOffer, setFrontPageItems, resetState, showCatalogPage, setCatalogOptions, setPurchaseOptions } = useCatalogContext(); - - const onCatalogPagesListEvent = useCallback((event: CatalogPagesListEvent) => - { - const parser = event.getParser(); - const offers: Map = new Map(); - - const getCatalogNode = (node: NodeData, depth: number, parent: ICatalogNode) => - { - const catalogNode = (new CatalogNode(node, depth, parent) as ICatalogNode); - - for(const offerId of catalogNode.offerIds) - { - if(offers.has(offerId)) offers.get(offerId).push(catalogNode); - else offers.set(offerId, [ catalogNode ]); - } - - depth++; - - for(const child of node.children) catalogNode.addChild(getCatalogNode(child, depth, catalogNode)); - - return catalogNode; - } - - BatchUpdates(() => - { - setRootNode(getCatalogNode(parser.root, 0, null)); - setOffersToNodes(offers); - }); - }, [ setRootNode, setOffersToNodes ]); - - const onCatalogPageMessageEvent = useCallback((event: CatalogPageMessageEvent) => - { - const parser = event.getParser(); - - if(parser.catalogType !== currentType) return; - - const purchasableOffers: IPurchasableOffer[] = []; - - for(const offer of parser.offers) - { - const products: IProduct[] = []; - const productData = GetProductDataForLocalization(offer.localizationId); - - for(const product of offer.products) - { - const furnitureData = GetFurnitureData(product.furniClassId, product.productType); - - products.push(new Product(product.productType, product.furniClassId, product.extraParam, product.productCount, productData, furnitureData, product.uniqueLimitedItem, product.uniqueLimitedSeriesSize, product.uniqueLimitedItemsLeft)); - } - - if(!products.length) continue; - - const purchasableOffer = new Offer(offer.offerId, offer.localizationId, offer.rent, offer.priceCredits, offer.priceActivityPoints, offer.priceActivityPointsType, offer.giftable, offer.clubLevel, products, offer.bundlePurchaseAllowed); - - 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); - - if(pageId === parser.pageId) - { - 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) => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchasedEvent(parser.offer)); - }, []); - - const onPurchaseErrorMessageEvent = useCallback((event: PurchaseErrorMessageEvent) => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseFailureEvent(parser.code)); - }, []); - - const onPurchaseNotAllowedMessageEvent = useCallback((event: PurchaseNotAllowedMessageEvent) => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseNotAllowedEvent(parser.code)); - }, []); - - const onLimitedEditionSoldOutEvent = useCallback((event: LimitedEditionSoldOutEvent) => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseSoldOutEvent()); - }, []); - - const onProductOfferEvent = useCallback((event: ProductOfferEvent) => - { - const parser = event.getParser(); - const offerData = parser.offer; - - if(!offerData || !offerData.products.length) return; - - const offerProductData = offerData.products[0]; - - if(offerProductData.uniqueLimitedItem) - { - // update unique - } - - const products: IProduct[] = []; - const productData = GetProductDataForLocalization(offerData.localizationId); - - for(const product of offerData.products) - { - const furnitureData = GetFurnitureData(product.furniClassId, product.productType); - - products.push(new Product(product.productType, product.furniClassId, product.extraParam, product.productCount, productData, furnitureData, product.uniqueLimitedItem, product.uniqueLimitedSeriesSize, product.uniqueLimitedItemsLeft)); - } - - const offer = new Offer(offerData.offerId, offerData.localizationId, offerData.rent, offerData.priceCredits, offerData.priceActivityPoints, offerData.priceActivityPointsType, offerData.giftable, offerData.clubLevel, products, offerData.bundlePurchaseAllowed); - - if(!((currentType === CatalogType.NORMAL) || ((offer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (offer.pricingModel !== Offer.PRICING_MODEL_MULTI)))) return; - - offer.page = currentPage; - - setCurrentOffer(offer); - - if(offer.product && (offer.product.productType === ProductTypeEnum.WALL)) - { - if(offer.product && (offer.product.productType === ProductTypeEnum.WALL)) - { - setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; - - newValue.extraData =( offer.product.extraParam || null); - - return newValue; - }); - } - } - - // (this._isObjectMoverRequested) && (this._purchasableOffer) - }, [ currentType, currentPage, setCurrentOffer, setPurchaseOptions ]); - - const onSellablePetPalettesMessageEvent = useCallback((event: SellablePetPalettesMessageEvent) => - { - const parser = event.getParser(); - const petPalette = new CatalogPetPalette(parser.productCode, parser.palettes.slice()); - - setCatalogOptions(prevValue => - { - const petPalettes = []; - - if(prevValue.petPalettes) petPalettes.push(...prevValue.petPalettes); - - for(let i = 0; i < petPalettes.length; i++) - { - const palette = petPalettes[i]; - - if(palette.breed === petPalette.breed) - { - petPalettes.splice(i, 1); - - break; - } - } - - petPalettes.push(petPalette); - - return { ...prevValue, petPalettes }; - }); - }, [ setCatalogOptions ]); - - const onApproveNameMessageEvent = useCallback((event: ApproveNameMessageEvent) => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogNameResultEvent(parser.result, parser.validationInfo)); - }, []); - - const onGiftReceiverNotFoundEvent = useCallback(() => - { - DispatchUiEvent(new CatalogGiftReceiverNotFoundEvent()); - }, []); - - const onHabboClubOffersMessageEvent = useCallback((event: HabboClubOffersMessageEvent) => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const clubOffers = parser.offers; - - return { ...prevValue, clubOffers }; - }); - }, [ setCatalogOptions ]); - - const onGuildMembershipsMessageEvent = useCallback((event: GuildMembershipsMessageEvent) => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const groups = parser.groups; - - return { ...prevValue, groups }; - }); - }, [ setCatalogOptions ]); - - const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const subscriptionInfo = new SubscriptionInfo( - Math.max(0, parser.daysToPeriodEnd), - Math.max(0, parser.periodsSubscribedAhead), - parser.isVip, - parser.pastClubDays, - parser.pastVipDays); - - return { ...prevValue, subscriptionInfo }; - }); - }, [ setCatalogOptions ]); - - const onGiftWrappingConfigurationEvent = useCallback((event: GiftWrappingConfigurationEvent) => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const giftConfiguration = new GiftWrappingConfiguration(parser); - - return { ...prevValue, giftConfiguration }; - }); - }, [ setCatalogOptions ]); - - const onMarketplaceMakeOfferResult = useCallback((event: MarketplaceMakeOfferResult) => - { - const parser = event.getParser(); - - if(!parser) return; - - let title = ''; - if(parser.result === 1) - { - title = LocalizeText('inventory.marketplace.result.title.success'); - } - else - { - title = LocalizeText('inventory.marketplace.result.title.failure'); - } - - const message = LocalizeText(`inventory.marketplace.result.${parser.result}`); - - NotificationUtilities.simpleAlert(message, NotificationAlertType.DEFAULT, null, null, title); - }, []); - - const onClubGiftInfoEvent = useCallback((event: ClubGiftInfoEvent) => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const clubGifts = parser; - - return { ...prevValue, clubGifts }; - }); - }, [ setCatalogOptions ]); - - UseMessageEventHook(CatalogPagesListEvent, onCatalogPagesListEvent); - UseMessageEventHook(CatalogPageMessageEvent, onCatalogPageMessageEvent); - UseMessageEventHook(PurchaseOKMessageEvent, onPurchaseOKMessageEvent); - UseMessageEventHook(PurchaseErrorMessageEvent, onPurchaseErrorMessageEvent); - UseMessageEventHook(PurchaseNotAllowedMessageEvent, onPurchaseNotAllowedMessageEvent); - UseMessageEventHook(LimitedEditionSoldOutEvent, onLimitedEditionSoldOutEvent); - UseMessageEventHook(ProductOfferEvent, onProductOfferEvent); - UseMessageEventHook(GuildMembershipsMessageEvent, onGuildMembershipsMessageEvent); - UseMessageEventHook(SellablePetPalettesMessageEvent, onSellablePetPalettesMessageEvent); - UseMessageEventHook(ApproveNameMessageEvent, onApproveNameMessageEvent); - UseMessageEventHook(GiftReceiverNotFoundEvent, onGiftReceiverNotFoundEvent); - UseMessageEventHook(HabboClubOffersMessageEvent, onHabboClubOffersMessageEvent); - UseMessageEventHook(UserSubscriptionEvent, onUserSubscriptionEvent); - UseMessageEventHook(GiftWrappingConfigurationEvent, onGiftWrappingConfigurationEvent); - UseMessageEventHook(ClubGiftInfoEvent, onClubGiftInfoEvent); - UseMessageEventHook(MarketplaceMakeOfferResult, onMarketplaceMakeOfferResult); - - return null; -} diff --git a/src/components/catalog/CatalogView.tsx b/src/components/catalog/CatalogView.tsx index 97d86efa..3af9b189 100644 --- a/src/components/catalog/CatalogView.tsx +++ b/src/components/catalog/CatalogView.tsx @@ -1,437 +1,91 @@ -import { CatalogPublishedMessageEvent, FrontPageItem, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, ILinkEventTracker, RoomPreviewer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { AddEventLinkTracker, GetRoomEngine, LocalizeText, NotificationUtilities, PlaySound, RemoveLinkEventTracker, SendMessageComposer, SoundNames } from '../../api'; +import { ILinkEventTracker } from '@nitrots/nitro-renderer'; +import { FC, useEffect } from 'react'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api'; import { Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; -import { CatalogPurchasedEvent } from '../../events'; -import { BatchUpdates, UseMessageEventHook, UseUiEvent } from '../../hooks'; -import { CatalogContextProvider } from './CatalogContext'; -import { CatalogMessageHandler } from './CatalogMessageHandler'; -import { CatalogPage } from './common/CatalogPage'; -import { CatalogType } from './common/CatalogType'; -import { ICatalogNode } from './common/ICatalogNode'; -import { ICatalogOptions } from './common/ICatalogOptions'; -import { ICatalogPage } from './common/ICatalogPage'; -import { IPageLocalization } from './common/IPageLocalization'; -import { IPurchasableOffer } from './common/IPurchasableOffer'; -import { IPurchaseOptions } from './common/IPurchaseOptions'; -import { RequestedPage } from './common/RequestedPage'; -import { SearchResult } from './common/SearchResult'; +import { useCatalog } from '../../hooks'; import { CatalogGiftView } from './views/gift/CatalogGiftView'; import { CatalogNavigationView } from './views/navigation/CatalogNavigationView'; import { GetCatalogLayout } from './views/page/layout/GetCatalogLayout'; import { MarketplacePostOfferView } from './views/page/layout/marketplace/MarketplacePostOfferView'; -const REQUESTED_PAGE = new RequestedPage(); - export const CatalogView: FC<{}> = props => { - const [ isVisible, setIsVisible ] = useState(false); - const [ isBusy, setIsBusy ] = useState(false); - const [ pageId, setPageId ] = useState(-1); - const [ previousPageId, setPreviousPageId ] = useState(-1); - const [ currentType, setCurrentType ] = useState(CatalogType.NORMAL); - const [ rootNode, setRootNode ] = useState(null); - const [ offersToNodes, setOffersToNodes ] = useState>(null); - const [ currentPage, setCurrentPage ] = useState(null); - const [ currentOffer, setCurrentOffer ] = useState(null); - const [ activeNodes, setActiveNodes ] = useState([]); - const [ searchResult, setSearchResult ] = useState(null); - const [ frontPageItems, setFrontPageItems ] = useState([]); - const [ roomPreviewer, setRoomPreviewer ] = useState(null); - const [ navigationHidden, setNavigationHidden ] = useState(false); - const [ purchaseOptions, setPurchaseOptions ] = useState({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null }); - const [ catalogOptions, setCatalogOptions ] = useState({}); - - const resetState = useCallback(() => - { - BatchUpdates(() => - { - setPageId(-1); - setPreviousPageId(-1); - setRootNode(null); - setOffersToNodes(null); - setCurrentPage(null); - setCurrentOffer(null); - setActiveNodes([]); - setSearchResult(null); - setFrontPageItems([]); - setIsVisible(false); - }); - }, []); - - const onCatalogPublishedMessageEvent = useCallback((event: CatalogPublishedMessageEvent) => - { - const wasVisible = isVisible; - - resetState(); - - if(wasVisible) NotificationUtilities.simpleAlert(LocalizeText('catalog.alert.published.description'), null, null, null, LocalizeText('catalog.alert.published.title')); - }, [ isVisible, resetState ]); - - UseMessageEventHook(CatalogPublishedMessageEvent, onCatalogPublishedMessageEvent); - - const getNodeById = useCallback((id: number, node: ICatalogNode) => - { - if((node.pageId === id) && (node !== rootNode)) return node; - - for(const child of node.children) - { - const found = (getNodeById(id, child) as ICatalogNode); - - if(found) return found; - } - - return null; - }, [ rootNode ]); - - const getNodeByName = useCallback((name: string, node: ICatalogNode) => - { - if((node.pageName === name) && (node !== rootNode)) return node; - - for(const child of node.children) - { - const found = (getNodeByName(name, child) as ICatalogNode); - - if(found) return found; - } - - return null; - }, [ rootNode ]); - - const getNodesByOfferId = useCallback((offerId: number, flag: boolean = false) => - { - if(!offersToNodes || !offersToNodes.size) return null; - - if(flag) - { - const nodes: ICatalogNode[] = []; - const offers = offersToNodes.get(offerId); - - if(offers && offers.length) for(const offer of offers) (offer.isVisible && nodes.push(offer)); - - if(nodes.length) return nodes; - } - - return offersToNodes.get(offerId); - }, [ offersToNodes ]); - - const loadCatalogPage = useCallback((pageId: number, offerId: number) => - { - if(pageId < 0) return; - - BatchUpdates(() => - { - setIsBusy(true); - setPageId(pageId); - }); - - if(pageId > -1) SendMessageComposer(new GetCatalogPageComposer(pageId, offerId, currentType)); - }, [ currentType ]); - - const showCatalogPage = useCallback((pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], offerId: number, acceptSeasonCurrencyAsCredits: boolean) => - { - const catalogPage = (new CatalogPage(pageId, layoutCode, localization, offers, acceptSeasonCurrencyAsCredits) as ICatalogPage); - - BatchUpdates(() => - { - setCurrentPage(catalogPage); - setPreviousPageId(prevValue => ((pageId !== -1) ? pageId : prevValue)); - setNavigationHidden(false); - - if((offerId > -1) && catalogPage.offers.length) - { - for(const offer of catalogPage.offers) - { - if(offer.offerId !== offerId) continue; - - setCurrentOffer(offer) - - break; - } - } - }); - }, []); - - const activateNode = useCallback((targetNode: ICatalogNode, offerId: number = -1) => - { - if(targetNode.parent.pageName === 'root') - { - if(targetNode.children.length) - { - for(const child of targetNode.children) - { - if(!child.isVisible) continue; - - targetNode = child; - - break; - } - } - } - - const nodes: ICatalogNode[] = []; - - let node = targetNode; - - while(node && (node.pageName !== 'root')) - { - nodes.push(node); - - node = node.parent; - } - - nodes.reverse(); - - setActiveNodes(prevValue => - { - const isActive = (prevValue.indexOf(targetNode) >= 0); - const isOpen = targetNode.isOpen; - - for(const existing of prevValue) - { - existing.deactivate(); - - if(nodes.indexOf(existing) === -1) existing.close(); - } - - for(const n of nodes) - { - n.activate(); - - if(n.parent) n.open(); - - if((n === targetNode.parent) && n.children.length) n.open(); - } - - if(isActive && isOpen) targetNode.close(); - else targetNode.open(); - - return nodes; - }); - - if(targetNode.pageId > -1) loadCatalogPage(targetNode.pageId, offerId); - }, [ setActiveNodes, loadCatalogPage ]); - - const openPageById = useCallback((id: number) => - { - BatchUpdates(() => - { - setSearchResult(null); - - if(!isVisible) - { - REQUESTED_PAGE.requestById = id; - - setIsVisible(true); - } - else - { - const node = getNodeById(id, rootNode); - - if(node) activateNode(node); - } - }); - }, [ isVisible, rootNode, getNodeById, activateNode ]); - - const openPageByName = useCallback((name: string) => - { - BatchUpdates(() => - { - setSearchResult(null); - - if(!isVisible) - { - REQUESTED_PAGE.requestByName = name; - - setIsVisible(true); - } - else - { - const node = getNodeByName(name, rootNode); - - if(node) activateNode(node); - } - }); - }, [ isVisible, rootNode, getNodeByName, activateNode ]); - - const openPageByOfferId = useCallback((offerId: number) => - { - BatchUpdates(() => - { - setSearchResult(null); - - if(!isVisible) - { - REQUESTED_PAGE.requestedByOfferId = offerId; - - setIsVisible(true); - } - else - { - const nodes = getNodesByOfferId(offerId); - - if(!nodes || !nodes.length) return; - - activateNode(nodes[0], offerId); - } - }); - }, [ isVisible, getNodesByOfferId, activateNode ]); - - const onCatalogPurchasedEvent = useCallback((event: CatalogPurchasedEvent) => - { - PlaySound(SoundNames.CREDITS); - }, []); - - UseUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogPurchasedEvent); - - const linkReceived = useCallback((url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - case 'open': - if(parts.length > 2) - { - if(parts.length === 4) - { - switch(parts[2]) - { - case 'offerId': - openPageByOfferId(parseInt(parts[3])); - return; - } - } - else - { - openPageByName(parts[2]); - } - } - else - { - setIsVisible(true); - } - - return; - } - }, [ openPageByOfferId, openPageByName ]); + const { isVisible = false, setIsVisible = null, rootNode = null, currentPage = null, navigationHidden = false, setNavigationHidden = null, activeNodes = [], searchResult = null, setSearchResult = null, openPageByName = null, openPageByOfferId = null, activateNode = null } = useCatalog(); useEffect(() => { const linkTracker: ILinkEventTracker = { - linkReceived, + linkReceived: (url: string) => + { + const parts = url.split('/'); + + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'show': + setIsVisible(true); + return; + case 'hide': + setIsVisible(false); + return; + case 'toggle': + setIsVisible(prevValue => !prevValue); + return; + case 'open': + if(parts.length > 2) + { + if(parts.length === 4) + { + switch(parts[2]) + { + case 'offerId': + openPageByOfferId(parseInt(parts[3])); + return; + } + } + else + { + openPageByName(parts[2]); + } + } + else + { + setIsVisible(true); + } + + return; + } + }, eventUrlPrefix: 'catalog/' }; AddEventLinkTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); - }, [ linkReceived ]); - - useEffect(() => - { - setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER)); - - return () => - { - setRoomPreviewer(prevValue => - { - prevValue.dispose(); - - return null; - }); - } - }, []); - - useEffect(() => - { - if(!isVisible || rootNode) return; - - SendMessageComposer(new GetGiftWrappingConfigurationComposer()); - SendMessageComposer(new GetClubGiftInfo()); - SendMessageComposer(new GetCatalogIndexComposer(currentType)); - }, [ isVisible, rootNode, currentType ]); - - useEffect(() => - { - if(!isVisible || !rootNode) return; - - switch(REQUESTED_PAGE.requestType) - { - case RequestedPage.REQUEST_TYPE_NONE: - if(activeNodes && activeNodes.length) return; - - if(rootNode.isBranch) - { - for(const child of rootNode.children) - { - if(child && child.isVisible) - { - activateNode(child); - - return; - } - } - } - return; - case RequestedPage.REQUEST_TYPE_ID: - openPageById(REQUESTED_PAGE.requestById); - REQUESTED_PAGE.resetRequest(); - return; - case RequestedPage.REQUEST_TYPE_OFFER: - openPageByOfferId(REQUESTED_PAGE.requestedByOfferId); - REQUESTED_PAGE.resetRequest(); - return; - case RequestedPage.REQUEST_TYPE_NAME: - openPageByName(REQUESTED_PAGE.requestByName); - REQUESTED_PAGE.resetRequest(); - return; - } - }, [ isVisible, rootNode, activeNodes, activateNode, openPageById, openPageByOfferId, openPageByName ]); - - useEffect(() => - { - if(!searchResult && currentPage && (currentPage.pageId === -1)) openPageById(previousPageId); - }, [ searchResult, currentPage, previousPageId, openPageById ]); - - useEffect(() => - { - return () => setCurrentOffer(null); - }, [ currentPage ]); + }, [ setIsVisible, openPageByOfferId, openPageByName ]); return ( - - + <> { isVisible && - { setIsVisible(false); } } /> + setIsVisible(false) } /> { rootNode && (rootNode.children.length > 0) && rootNode.children.map(child => - { - if(!child.isVisible) return null; + { + if(!child.isVisible) return null; - return ( - - { - if(searchResult) setSearchResult(null); + return ( + + { + if(searchResult) setSearchResult(null); - activateNode(child); - } }> - { child.localization } - - ); - }) } + activateNode(child); + } }> + { child.localization } + + ); + }) } @@ -446,8 +100,8 @@ export const CatalogView: FC<{}> = props => } - - - + + + ); } diff --git a/src/components/catalog/common/AttemptCatalogPlacement.ts b/src/components/catalog/common/AttemptCatalogPlacement.ts deleted file mode 100644 index af342ee3..00000000 --- a/src/components/catalog/common/AttemptCatalogPlacement.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CatalogPageMessageOfferData, RoomObjectCategory, RoomObjectPlacementSource } from '@nitrots/nitro-renderer'; -import { GetRoomEngine } from '../../../api'; -import { IsCatalogOfferDraggable } from './IsCatalogOfferDraggable'; -import { ProductTypeEnum } from './ProductTypeEnum'; - -export const AttemptCatalogPlacement = (offer: CatalogPageMessageOfferData) => -{ - if(!IsCatalogOfferDraggable(offer)) return; - - const product = offer.products[0]; - - let category: number = -1; - - switch(product.productType) - { - case ProductTypeEnum.FLOOR: - category = RoomObjectCategory.FLOOR; - break; - case ProductTypeEnum.WALL: - category = RoomObjectCategory.WALL; - break; - } - - if(category === -1) return; - - if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.CATALOG, -(offer.offerId), category, product.furniClassId, (product.extraParam) ? product.extraParam.toString() : null)) - { - - } -} diff --git a/src/components/catalog/common/FurniCategory.ts b/src/components/catalog/common/FurniCategory.ts deleted file mode 100644 index 7eeeca24..00000000 --- a/src/components/catalog/common/FurniCategory.ts +++ /dev/null @@ -1,26 +0,0 @@ -export class FurniCategory -{ - public static DEFAULT: number = 1; - public static WALL_PAPER: number = 2; - public static FLOOR: number = 3; - public static LANDSCAPE: number = 4; - public static POST_IT: number = 5; - public static POSTER: number = 6; - public static SOUND_SET: number = 7; - public static TRAX_SONG: number = 8; - public static PRESENT: number = 9; - public static ECOTRON_BOX: number = 10; - public static TROPHY: number = 11; - public static CREDIT_FURNI: number = 12; - public static PET_SHAMPOO: number = 13; - public static PET_CUSTOM_PART: number = 14; - public static PET_CUSTOM_PART_SHAMPOO: number = 15; - public static PET_SADDLE: number = 16; - public static GUILD_FURNI: number = 17; - public static GAME_FURNI: number = 18; - public static MONSTERPLANT_SEED: number = 19; - public static MONSTERPLANT_REVIVAL: number = 20; - public static MONSTERPLANT_REBREED: number = 21; - public static MONSTERPLANT_FERTILIZE: number = 22; - public static FIGURE_PURCHASABLE_SET: number = 23; -} \ No newline at end of file diff --git a/src/components/catalog/common/IPurse.ts b/src/components/catalog/common/IPurse.ts deleted file mode 100644 index bd365ba6..00000000 --- a/src/components/catalog/common/IPurse.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface IPurse -{ - _Str_14389: boolean; - _Str_4458: number; - credits: number; - clubDays: number; - clubPeriods: number; - _Str_13571: boolean; - _Str_3738: boolean; - _Str_6288: number; - _Str_4605: number; - _Str_6312: number; - _Str_5590(_arg_1: number): number; -} diff --git a/src/components/catalog/common/IsCatalogOfferDraggable.ts b/src/components/catalog/common/IsCatalogOfferDraggable.ts deleted file mode 100644 index 174ce4d0..00000000 --- a/src/components/catalog/common/IsCatalogOfferDraggable.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CatalogPageMessageOfferData, RoomControllerLevel } from '@nitrots/nitro-renderer'; -import { GetRoomSession } from '../../../api'; -import { ProductTypeEnum } from './ProductTypeEnum'; - -export const IsCatalogOfferDraggable = (offer: CatalogPageMessageOfferData) => -{ - return ((GetRoomSession().isRoomOwner || (GetRoomSession().isGuildRoom && (GetRoomSession().controllerLevel >= RoomControllerLevel.GUILD_MEMBER))) && (offer.products.length === 1) && (offer.products[0].productType !== ProductTypeEnum.EFFECT) && (offer.products[0].productType !== ProductTypeEnum.HABBO_CLUB)) -} diff --git a/src/components/catalog/common/ProductTypeEnum.ts b/src/components/catalog/common/ProductTypeEnum.ts deleted file mode 100644 index 75257e55..00000000 --- a/src/components/catalog/common/ProductTypeEnum.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class ProductTypeEnum -{ - public static WALL: string = 'i'; - public static FLOOR: string = 's'; - public static EFFECT: string = 'e'; - public static HABBO_CLUB: string = 'h'; - public static BADGE: string = 'b'; - public static GAME_TOKEN: string = 'GAME_TOKEN'; - public static PET: string = 'p'; - public static ROBOT: string = 'r'; -} \ No newline at end of file diff --git a/src/components/catalog/common/Purse.ts b/src/components/catalog/common/Purse.ts deleted file mode 100644 index eebaacf8..00000000 --- a/src/components/catalog/common/Purse.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { GetNitroInstance } from '../../../api'; -import { IPurse } from './IPurse'; - -export class Purse implements IPurse -{ - private _credits: number = 0; - private _activityPoints: Map; - private _clubDays: number = 0; - private _clubPeriods: number = 0; - private _isVIP: boolean = false; - private _pastClubDays: number = 0; - private _pastVipDays: number = 0; - private _isExpiring: boolean = false; - private _minutesUntilExpiration: number = 0; - private _minutesSinceLastModified: number; - private _lastUpdated: number; - - public get credits(): number - { - return this._credits; - } - - public set credits(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._credits = k; - } - - public get clubDays(): number - { - return this._clubDays; - } - - public set clubDays(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._clubDays = k; - } - - public get clubPeriods(): number - { - return this._clubPeriods; - } - - public set clubPeriods(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._clubPeriods = k; - } - - public get _Str_13571(): boolean - { - return (this._clubDays > 0) || (this._clubPeriods > 0); - } - - public get _Str_3738(): boolean - { - return this._isVIP; - } - - public get _Str_14389(): boolean - { - return this._isExpiring; - } - - public set _Str_14389(k: boolean) - { - this._isExpiring = k; - } - - public set _Str_3738(k: boolean) - { - this._isVIP = k; - } - - public get _Str_6288(): number - { - return this._pastClubDays; - } - - public set _Str_6288(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._pastClubDays = k; - } - - public get _Str_4605(): number - { - return this._pastVipDays; - } - - public set _Str_4605(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._pastVipDays = k; - } - - public get _Str_18527(): Map - { - return this._activityPoints; - } - - public set _Str_18527(k: Map) - { - this._lastUpdated = GetNitroInstance().time; - this._activityPoints = k; - } - - public _Str_5590(k: number): number - { - return this._activityPoints[k]; - } - - public set _Str_4458(k: number) - { - this._lastUpdated = GetNitroInstance().time; - - this._minutesUntilExpiration = k; - } - - public get _Str_4458(): number - { - const k = ((GetNitroInstance().time - this._lastUpdated) / (1000 * 60)); - const _local_2 = (this._minutesUntilExpiration - k); - - return (_local_2 > 0) ? _local_2 : 0; - } - - public set _Str_6312(k: number) - { - this._lastUpdated = GetNitroInstance().time; - this._minutesSinceLastModified = k; - } - - public get _Str_6312(): number - { - return this._minutesSinceLastModified; - } - - public get _Str_26225(): number - { - return this._lastUpdated; - } -} diff --git a/src/components/catalog/common/SubscriptionInfo.ts b/src/components/catalog/common/SubscriptionInfo.ts deleted file mode 100644 index 29d4b358..00000000 --- a/src/components/catalog/common/SubscriptionInfo.ts +++ /dev/null @@ -1,17 +0,0 @@ - -export class SubscriptionInfo -{ - private _lastUpdated: number; - - constructor( - public readonly clubDays: number = 0, - public readonly clubPeriods: number = 0, - public readonly isVip: boolean = false, - public readonly pastDays: number = 0, - public readonly pastVipDays: number = 0) {} - - public get lastUpdated(): number - { - return this._lastUpdated; - } -} diff --git a/src/components/catalog/views/CatalogPurchaseConfirmView.tsx b/src/components/catalog/views/CatalogPurchaseConfirmView.tsx new file mode 100644 index 00000000..30dcfc3b --- /dev/null +++ b/src/components/catalog/views/CatalogPurchaseConfirmView.tsx @@ -0,0 +1,10 @@ +import { FC } from 'react'; + +export const CatalogPurchaseConfirmView: FC<{}> = props => +{ + const {} = props; + + return ( +
+ ); +} diff --git a/src/components/catalog/views/gift/CatalogGiftView.tsx b/src/components/catalog/views/gift/CatalogGiftView.tsx index 2da5ee13..74cb4a84 100644 --- a/src/components/catalog/views/gift/CatalogGiftView.tsx +++ b/src/components/catalog/views/gift/CatalogGiftView.tsx @@ -1,13 +1,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer'; +import { GiftReceiverNotFoundEvent, PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer'; import classNames from 'classnames'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../../api'; +import { GetSessionDataManager, LocalizeText, ProductTypeEnum, SendMessageComposer } from '../../../../api'; import { Base, Button, ButtonGroup, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events'; -import { BatchUpdates, UseUiEvent } from '../../../../hooks'; -import { useCatalogContext } from '../../CatalogContext'; -import { ProductTypeEnum } from '../../common/ProductTypeEnum'; +import { useCatalog, UseMessageEventHook, UseUiEvent } from '../../../../hooks'; export const CatalogGiftView: FC<{}> = props => { @@ -25,25 +23,22 @@ export const CatalogGiftView: FC<{}> = props => const [ maxBoxIndex, setMaxBoxIndex ] = useState(0); const [ maxRibbonIndex, setMaxRibbonIndex ] = useState(0); const [ receiverNotFound, setReceiverNotFound ] = useState(false); - const { catalogOptions = null } = useCatalogContext(); + const { catalogOptions = null } = useCatalog(); const { giftConfiguration = null } = catalogOptions; const close = useCallback(() => { - BatchUpdates(() => - { - setIsVisible(false); - setPageId(0); - setOfferId(0); - setExtraData(''); - setReceiverName(''); - setShowMyFace(true); - setMessage(''); - setSelectedBoxIndex(0); - setSelectedRibbonIndex(0); - - if(colors.length) setSelectedColorId(colors[0].id); - }); + setIsVisible(false); + setPageId(0); + setOfferId(0); + setExtraData(''); + setReceiverName(''); + setShowMyFace(true); + setMessage(''); + setSelectedBoxIndex(0); + setSelectedRibbonIndex(0); + + if(colors.length) setSelectedColorId(colors[0].id); }, [ colors ]); const onCatalogEvent = useCallback((event: CatalogEvent) => @@ -56,25 +51,18 @@ export const CatalogGiftView: FC<{}> = props => case CatalogEvent.INIT_GIFT: const castedEvent = (event as CatalogInitGiftEvent); - BatchUpdates(() => - { - close(); + close(); - setPageId(castedEvent.pageId); - setOfferId(castedEvent.offerId); - setExtraData(castedEvent.extraData); - setIsVisible(true); - }); - return; - case CatalogEvent.GIFT_RECEIVER_NOT_FOUND: - setReceiverNotFound(true); + setPageId(castedEvent.pageId); + setOfferId(castedEvent.offerId); + setExtraData(castedEvent.extraData); + setIsVisible(true); return; } }, [ close ]); UseUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogEvent); UseUiEvent(CatalogEvent.INIT_GIFT, onCatalogEvent); - UseUiEvent(CatalogEvent.GIFT_RECEIVER_NOT_FOUND, onCatalogEvent); const isBoxDefault = useMemo(() => { @@ -125,6 +113,13 @@ export const CatalogGiftView: FC<{}> = props => } }, [ extraData, maxBoxIndex, maxRibbonIndex, message, offerId, pageId, receiverName, selectedBoxIndex, selectedColorId, selectedRibbonIndex, showMyFace ]); + const onGiftReceiverNotFoundEvent = useCallback(() => + { + setReceiverNotFound(true); + }, []); + + UseMessageEventHook(GiftReceiverNotFoundEvent, onGiftReceiverNotFoundEvent); + useEffect(() => { setReceiverNotFound(false); @@ -142,20 +137,17 @@ export const CatalogGiftView: FC<{}> = props => if(!giftData) continue; - if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${giftData.colors[0].toString(16)}` }); + if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${ giftData.colors[0].toString(16) }` }); } - BatchUpdates(() => - { - setMaxBoxIndex(giftConfiguration.boxTypes.length - 1); - setMaxRibbonIndex(giftConfiguration.ribbonTypes.length - 1); + setMaxBoxIndex(giftConfiguration.boxTypes.length - 1); + setMaxRibbonIndex(giftConfiguration.ribbonTypes.length - 1); - if(newColors.length) - { - setSelectedColorId(newColors[0].id); - setColors(newColors); - } - }); + if(newColors.length) + { + setSelectedColorId(newColors[0].id); + setColors(newColors); + } }, [ giftConfiguration ]); if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null; @@ -197,7 +189,7 @@ export const CatalogGiftView: FC<{}> = props => { LocalizeText(boxName) } - { LocalizeText(priceText, ['price'], [giftConfiguration.price.toString()]) } + { LocalizeText(priceText, [ 'price' ], [ giftConfiguration.price.toString() ]) } @@ -220,7 +212,7 @@ export const CatalogGiftView: FC<{}> = props => { LocalizeText('catalog.gift_wrapping.pick_color') } - { colors.map(color => ; } - if(pendingOffer.priceActivityPoints > GetCurrencyAmount(pendingOffer.priceActivityPointsType)) + if(pendingOffer.priceActivityPoints > getCurrencyAmount(pendingOffer.priceActivityPointsType)) { return ; } @@ -128,7 +121,7 @@ export const CatalogLayoutVipBuyView: FC = props => default: return ; } - }, [ pendingOffer, purchaseState, purchaseSubscription ]); + }, [ pendingOffer, purchaseState, purchaseSubscription, getCurrencyAmount ]); useEffect(() => { @@ -140,35 +133,35 @@ export const CatalogLayoutVipBuyView: FC = props => { clubOffers && (clubOffers.length > 0) && clubOffers.map((offer, index) => - { - return ( - setOffer(offer) }> - - - { getOfferText(offer) } - - { (offer.priceCredits > 0) && - - { offer.priceCredits } - - } - { (offer.priceActivityPoints > 0) && - - { offer.priceActivityPoints } - - } - - - - ); - }) } + { + return ( + setOffer(offer) }> + + + { getOfferText(offer) } + + { (offer.priceCredits > 0) && + + { offer.priceCredits } + + } + { (offer.priceActivityPoints > 0) && + + { offer.priceActivityPoints } + + } + + + + ); + }) } - + { currentPage.localization.getImage(1) && } - + { pendingOffer && diff --git a/src/components/catalog/views/page/layout/GetCatalogLayout.tsx b/src/components/catalog/views/page/layout/GetCatalogLayout.tsx index 69f497ea..2f5afd1c 100644 --- a/src/components/catalog/views/page/layout/GetCatalogLayout.tsx +++ b/src/components/catalog/views/page/layout/GetCatalogLayout.tsx @@ -1,4 +1,4 @@ -import { ICatalogPage } from '../../../common/ICatalogPage'; +import { ICatalogPage } from '../../../../../api'; import { CatalogLayoutProps } from './CatalogLayout.types'; import { CatalogLayoutBadgeDisplayView } from './CatalogLayoutBadgeDisplayView'; import { CatalogLayoutDefaultView } from './CatalogLayoutDefaultView'; @@ -67,7 +67,7 @@ export const GetCatalogLayout = (page: ICatalogPage, hideNavigation: () => void) case 'roomads': return ; //case 'default_3x3_color_grouping': - //return ; + //return ; case 'bots': case 'default_3x3': default: diff --git a/src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontpage4View.tsx b/src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontpage4View.tsx index 807adbf8..f2e1da6c 100644 --- a/src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontpage4View.tsx +++ b/src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontpage4View.tsx @@ -1,9 +1,8 @@ import { FrontPageItem } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect } from 'react'; import { CreateLinkEvent } from '../../../../../../api'; -import { Column } from '../../../../../../common/Column'; -import { Grid } from '../../../../../../common/Grid'; -import { useCatalogContext } from '../../../../CatalogContext'; +import { Column, Grid } from '../../../../../../common'; +import { useCatalog } from '../../../../../../hooks'; import { CatalogRedeemVoucherView } from '../../common/CatalogRedeemVoucherView'; import { CatalogLayoutProps } from '../CatalogLayout.types'; import { CatalogLayoutFrontPageItemView } from './CatalogLayoutFrontPageItemView'; @@ -11,7 +10,7 @@ import { CatalogLayoutFrontPageItemView } from './CatalogLayoutFrontPageItemView export const CatalogLayoutFrontpage4View: FC = props => { const { page = null, hideNavigation = null } = props; - const { frontPageItems = [] } = useCatalogContext(); + const { frontPageItems = [] } = useCatalog(); const selectItem = useCallback((item: FrontPageItem) => { diff --git a/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceItemView.tsx b/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceItemView.tsx index 3e2719a4..22d7dfd9 100644 --- a/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceItemView.tsx +++ b/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceItemView.tsx @@ -1,11 +1,6 @@ import { FC, useCallback, useMemo } from 'react'; -import { LocalizeText } from '../../../../../../api'; -import { LayoutFurniIconImageView } from '../../../../../../common'; -import { Button } from '../../../../../../common/Button'; -import { Column } from '../../../../../../common/Column'; -import { LayoutGridItem } from '../../../../../../common/layout/LayoutGridItem'; -import { Text } from '../../../../../../common/Text'; -import { ProductTypeEnum } from '../../../../common/ProductTypeEnum'; +import { LocalizeText, ProductTypeEnum } from '../../../../../../api'; +import { Button, Column, LayoutFurniIconImageView, LayoutGridItem, Text } from '../../../../../../common'; import { MarketplaceOfferData } from './common/MarketplaceOfferData'; import { MarketPlaceOfferState } from './common/MarketplaceOfferState'; @@ -41,7 +36,7 @@ export const CatalogLayoutMarketplaceItemView: FC = pr const time = Math.max(1, offerData.timeLeftMinutes); const hours = Math.floor(time / 60); - const minutes = time - (hours * 60); + const minutes = time - (hours * 60); let text = minutes + ' ' + LocalizeText('catalog.marketplace.offer.minutes'); if(hours > 0) @@ -49,8 +44,8 @@ export const CatalogLayoutMarketplaceItemView: FC = 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 ( @@ -64,8 +59,8 @@ export const CatalogLayoutMarketplaceItemView: FC = pr } { (type === PUBLIC_OFFER) && <> - { LocalizeText('catalog.marketplace.offer.price_public_item', ['price', 'average'], [offerData.price.toString(), offerData.averagePrice.toString() ]) } - { LocalizeText('catalog.marketplace.offer_count', ['count'], [offerData.offerCount.toString()]) } + { LocalizeText('catalog.marketplace.offer.price_public_item', [ 'price', 'average' ], [ offerData.price.toString(), offerData.averagePrice.toString() ]) } + { LocalizeText('catalog.marketplace.offer_count', [ 'count' ], [ offerData.offerCount.toString() ]) } } diff --git a/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceOwnItemsView.tsx b/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceOwnItemsView.tsx index 2772c0d9..67860591 100644 --- a/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceOwnItemsView.tsx +++ b/src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceOwnItemsView.tsx @@ -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'; @@ -20,19 +20,16 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC = prop if(!parser) return; const offers = parser.offers.map(offer => - { - const newOffer = new MarketplaceOfferData(offer.offerId, offer.furniId, offer.furniType, offer.extraData, offer.stuffData, offer.price, offer.status, offer.averagePrice, offer.offerCount); - - newOffer.timeLeftMinutes = offer.timeLeftMinutes; - - return newOffer; - }); - - BatchUpdates(() => { - setCreditsWaiting(parser.creditsWaiting); - setOffers(offers); + const newOffer = new MarketplaceOfferData(offer.offerId, offer.furniId, offer.furniType, offer.extraData, offer.stuffData, offer.price, offer.status, offer.averagePrice, offer.offerCount); + + newOffer.timeLeftMinutes = offer.timeLeftMinutes; + + return newOffer; }); + + setCreditsWaiting(parser.creditsWaiting); + setOffers(offers); }, []); UseMessageEventHook(MarketplaceOwnOffersEvent, onMarketPlaceOwnOffersEvent); @@ -77,10 +74,10 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC = prop SendMessageComposer(new CancelMarketplaceOfferMessageComposer(offerData.offerId)); }; - UseMountEffect(() => + useEffect(() => { SendMessageComposer(new GetMarketplaceOwnOffersMessageComposer()); - }); + }, []); return ( @@ -91,7 +88,7 @@ export const CatalogLayoutMarketplaceOwnItemsView: FC = prop { (creditsWaiting > 0) && - { 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() ]) } diff --git a/src/components/catalog/views/page/widgets/CatalogAddOnBadgeWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogAddOnBadgeWidgetView.tsx index 0b041536..38892cea 100644 --- a/src/components/catalog/views/page/widgets/CatalogAddOnBadgeWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogAddOnBadgeWidgetView.tsx @@ -1,6 +1,6 @@ import { FC } from 'react'; import { BaseProps, LayoutBadgeImageView } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; +import { useCatalog } from '../../../../../hooks'; interface CatalogAddOnBadgeWidgetViewProps extends BaseProps { @@ -10,7 +10,7 @@ interface CatalogAddOnBadgeWidgetViewProps extends BaseProps export const CatalogAddOnBadgeWidgetView: FC = props => { const { ...rest } = props; - const { currentOffer = null } = useCatalogContext(); + const { currentOffer = null } = useCatalog(); if(!currentOffer || !currentOffer.badgeCode || !currentOffer.badgeCode.length) return null; diff --git a/src/components/catalog/views/page/widgets/CatalogBadgeSelectorWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogBadgeSelectorWidgetView.tsx index fb32c1b2..04891dde 100644 --- a/src/components/catalog/views/page/widgets/CatalogBadgeSelectorWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogBadgeSelectorWidgetView.tsx @@ -1,9 +1,7 @@ import { StringDataType } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { FC, useEffect, useMemo, useState } from 'react'; import { AutoGrid, AutoGridProps, LayoutBadgeImageView, LayoutGridItem } from '../../../../../common'; -import { InventoryBadgesRequestEvent, InventoryBadgesUpdatedEvent } from '../../../../../events'; -import { DispatchUiEvent, UseUiEvent } from '../../../../../hooks'; -import { useCatalogContext } from '../../../CatalogContext'; +import { useCatalog, useInventoryBadges } from '../../../../../hooks'; const EXCLUDED_BADGE_CODES: string[] = []; @@ -15,59 +13,64 @@ interface CatalogBadgeSelectorWidgetViewProps extends AutoGridProps export const CatalogBadgeSelectorWidgetView: FC = props => { const { columnCount = 5, ...rest } = props; - const [ badges, setBadges ] = useState([]); - const [ currentBadge, setCurrentBadge ] = useState(null); - const { currentOffer = null, setPurchaseOptions = null } = useCatalogContext(); - - const onInventoryBadgesUpdatedEvent = useCallback((event: InventoryBadgesUpdatedEvent) => - { - setBadges(event.badges); - }, []); - - UseUiEvent(InventoryBadgesUpdatedEvent.BADGES_UPDATED, onInventoryBadgesUpdatedEvent); + const [ isVisible, setIsVisible ] = useState(false); + const [ currentBadgeCode, setCurrentBadgeCode ] = useState(null); + const { currentOffer = null, setPurchaseOptions = null } = useCatalog(); + const { badgeCodes = [], activate = null, deactivate = null } = useInventoryBadges(); const previewStuffData = useMemo(() => { - if(!currentBadge) return null; + if(!currentBadgeCode) return null; const stuffData = new StringDataType(); - stuffData.setValue([ '0', currentBadge, '', '' ]); + stuffData.setValue([ '0', currentBadgeCode, '', '' ]); return stuffData; - }, [ currentBadge ]); + }, [ currentBadgeCode ]); useEffect(() => { if(!currentOffer) return; setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.extraParamRequired = true; - newValue.extraData = ((previewStuffData && previewStuffData.getValue(1)) || null); - newValue.previewStuffData = previewStuffData; + newValue.extraParamRequired = true; + newValue.extraData = ((previewStuffData && previewStuffData.getValue(1)) || null); + newValue.previewStuffData = previewStuffData; - return newValue; - }); + return newValue; + }); }, [ currentOffer, previewStuffData, setPurchaseOptions ]); useEffect(() => { - DispatchUiEvent(new InventoryBadgesRequestEvent(InventoryBadgesRequestEvent.REQUEST_BADGES)); + if(!isVisible) return; + + const id = activate(); + + return () => deactivate(id); + }, [ isVisible, activate, deactivate ]); + + useEffect(() => + { + setIsVisible(true); + + return () => setIsVisible(false); }, []); return ( - { badges && (badges.length > 0) && badges.map((code, index) => - { - return ( - setCurrentBadge(code) }> - - - ); - }) } + { badgeCodes && (badgeCodes.length > 0) && badgeCodes.map((badgeCode, index) => + { + return ( + setCurrentBadgeCode(badgeCode) }> + + + ); + }) } ); } diff --git a/src/components/catalog/views/page/widgets/CatalogBundleGridWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogBundleGridWidgetView.tsx index e684387b..d98ff1dd 100644 --- a/src/components/catalog/views/page/widgets/CatalogBundleGridWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogBundleGridWidgetView.tsx @@ -1,7 +1,6 @@ import { FC } from 'react'; -import { AutoGrid, AutoGridProps } from '../../../../../common/AutoGrid'; -import { LayoutGridItem } from '../../../../../common/layout/LayoutGridItem'; -import { useCatalogContext } from '../../../CatalogContext'; +import { AutoGrid, AutoGridProps, LayoutGridItem } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; interface CatalogBundleGridWidgetViewProps extends AutoGridProps { @@ -11,7 +10,7 @@ interface CatalogBundleGridWidgetViewProps extends AutoGridProps export const CatalogBundleGridWidgetView: FC = props => { const { columnCount = 5, children = null, ...rest } = props; - const { currentOffer = null } = useCatalogContext(); + const { currentOffer = null } = useCatalog(); if(!currentOffer) return null; diff --git a/src/components/catalog/views/page/widgets/CatalogFirstProductSelectorWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogFirstProductSelectorWidgetView.tsx index dfab4d85..a0d71033 100644 --- a/src/components/catalog/views/page/widgets/CatalogFirstProductSelectorWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogFirstProductSelectorWidgetView.tsx @@ -1,9 +1,9 @@ import { FC, useEffect } from 'react'; -import { useCatalogContext } from '../../../CatalogContext'; +import { useCatalog } from '../../../../../hooks'; export const CatalogFirstProductSelectorWidgetView: FC<{}> = props => { - const { currentPage = null, setCurrentOffer = null } = useCatalogContext(); + const { currentPage = null, setCurrentOffer = null } = useCatalog(); useEffect(() => { diff --git a/src/components/catalog/views/page/widgets/CatalogGuildBadgeWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogGuildBadgeWidgetView.tsx index ae7deb55..db893ad3 100644 --- a/src/components/catalog/views/page/widgets/CatalogGuildBadgeWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogGuildBadgeWidgetView.tsx @@ -1,7 +1,7 @@ import { StringDataType } from '@nitrots/nitro-renderer'; import { FC, useMemo } from 'react'; import { BaseProps, LayoutBadgeImageView } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; +import { useCatalog } from '../../../../../hooks'; interface CatalogGuildBadgeWidgetViewProps extends BaseProps { @@ -11,7 +11,7 @@ interface CatalogGuildBadgeWidgetViewProps extends BaseProps export const CatalogGuildBadgeWidgetView: FC = props => { const { ...rest } = props; - const { currentOffer = null, purchaseOptions = null } = useCatalogContext(); + const { currentOffer = null, purchaseOptions = null } = useCatalog(); const { previewStuffData = null } = purchaseOptions; const badgeCode = useMemo(() => diff --git a/src/components/catalog/views/page/widgets/CatalogGuildSelectorWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogGuildSelectorWidgetView.tsx index ea856b59..d097bd36 100644 --- a/src/components/catalog/views/page/widgets/CatalogGuildSelectorWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogGuildSelectorWidgetView.tsx @@ -2,12 +2,12 @@ import { CatalogGroupsComposer, StringDataType } from '@nitrots/nitro-renderer'; import { FC, useEffect, useMemo, useState } from 'react'; import { LocalizeText, SendMessageComposer } from '../../../../../api'; import { Base, Button, Flex } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; +import { useCatalog } from '../../../../../hooks'; export const CatalogGuildSelectorWidgetView: FC<{}> = props => { const [ selectedGroupIndex, setSelectedGroupIndex ] = useState(0); - const { currentOffer = null, catalogOptions = null, setPurchaseOptions = null } = useCatalogContext(); + const { currentOffer = null, catalogOptions = null, setPurchaseOptions = null } = useCatalog(); const { groups = null } = catalogOptions; const previewStuffData = useMemo(() => @@ -30,15 +30,15 @@ export const CatalogGuildSelectorWidgetView: FC<{}> = props => if(!currentOffer) return; setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.extraParamRequired = true; - newValue.extraData = ((previewStuffData && previewStuffData.getValue(1)) || null); - newValue.previewStuffData = previewStuffData; + newValue.extraParamRequired = true; + newValue.extraData = ((previewStuffData && previewStuffData.getValue(1)) || null); + newValue.previewStuffData = previewStuffData; - return newValue; - }); + return newValue; + }); }, [ currentOffer, previewStuffData, setPurchaseOptions ]); useEffect(() => diff --git a/src/components/catalog/views/page/widgets/CatalogItemGridWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogItemGridWidgetView.tsx index 93ae4540..933dede6 100644 --- a/src/components/catalog/views/page/widgets/CatalogItemGridWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogItemGridWidgetView.tsx @@ -1,8 +1,7 @@ import { FC } from 'react'; -import { AutoGrid, AutoGridProps } from '../../../../../common/AutoGrid'; -import { useCatalogContext } from '../../../CatalogContext'; -import { IPurchasableOffer } from '../../../common/IPurchasableOffer'; -import { ProductTypeEnum } from '../../../common/ProductTypeEnum'; +import { IPurchasableOffer, ProductTypeEnum } from '../../../../../api'; +import { AutoGrid, AutoGridProps } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; import { CatalogGridOfferView } from '../common/CatalogGridOfferView'; interface CatalogItemGridWidgetViewProps extends AutoGridProps @@ -13,7 +12,7 @@ interface CatalogItemGridWidgetViewProps extends AutoGridProps export const CatalogItemGridWidgetView: FC = props => { const { columnCount = 5, children = null, ...rest } = props; - const { currentOffer = null, setCurrentOffer = null, currentPage = null, setPurchaseOptions = null } = useCatalogContext(); + const { currentOffer = null, setCurrentOffer = null, currentPage = null, setPurchaseOptions = null } = useCatalog(); if(!currentPage) return null; @@ -28,19 +27,19 @@ export const CatalogItemGridWidgetView: FC = pro if(offer.product && (offer.product.productType === ProductTypeEnum.WALL)) { setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.extraData = (offer.product.extraParam || null); + newValue.extraData = (offer.product.extraParam || null); - return newValue; - }); + return newValue; + }); } } return ( - { currentPage.offers && (currentPage.offers.length > 0) && currentPage.offers.map((offer, index) => selectOffer(offer) } />) } + { currentPage.offers && (currentPage.offers.length > 0) && currentPage.offers.map((offer, index) => ) } { children } ); diff --git a/src/components/catalog/views/page/widgets/CatalogLimitedItemWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogLimitedItemWidgetView.tsx index 035d7d44..70b52cbd 100644 --- a/src/components/catalog/views/page/widgets/CatalogLimitedItemWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogLimitedItemWidgetView.tsx @@ -1,12 +1,12 @@ import { FC } from 'react'; +import { Offer } from '../../../../../api'; import { Base, BaseProps, LayoutLimitedEditionCompletePlateView } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; -import { Offer } from '../../../common/Offer'; +import { useCatalog } from '../../../../../hooks'; export const CatalogLimitedItemWidgetView: FC> = props => { const { children = null, ...rest } = props; - const { currentOffer = null } = useCatalogContext(); + const { currentOffer = null } = useCatalog(); if(!currentOffer || (currentOffer.pricingModel !== Offer.PRICING_MODEL_SINGLE) || !currentOffer.product.isUniqueLimitedItem) return null; diff --git a/src/components/catalog/views/page/widgets/CatalogPriceDisplayWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogPriceDisplayWidgetView.tsx index 7cf8c76b..0ca15604 100644 --- a/src/components/catalog/views/page/widgets/CatalogPriceDisplayWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogPriceDisplayWidgetView.tsx @@ -1,8 +1,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FC } from 'react'; +import { IPurchasableOffer } from '../../../../../api'; import { Flex, LayoutCurrencyIcon, Text } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; -import { IPurchasableOffer } from '../../../common/IPurchasableOffer'; +import { useCatalog } from '../../../../../hooks'; interface CatalogPriceDisplayWidgetViewProps { @@ -13,7 +13,7 @@ interface CatalogPriceDisplayWidgetViewProps export const CatalogPriceDisplayWidgetView: FC = props => { const { offer = null, separator = false } = props; - const { purchaseOptions = null } = useCatalogContext(); + const { purchaseOptions = null } = useCatalog(); const { quantity = 1 } = purchaseOptions; if(!offer) return null; diff --git a/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx index 7ed446aa..93637305 100644 --- a/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx @@ -1,13 +1,9 @@ import { PurchaseFromCatalogComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { CreateLinkEvent, GetClubMemberLevel, LocalizeText, SendMessageComposer } from '../../../../../api'; +import { CatalogPurchaseState, CreateLinkEvent, GetClubMemberLevel, LocalizeText, LocalStorageKeys, Offer, SendMessageComposer } from '../../../../../api'; import { Button, LayoutLoadingSpinnerView } from '../../../../../common'; -import { CatalogEvent, CatalogInitGiftEvent, CatalogInitPurchaseEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent, CatalogWidgetEvent } from '../../../../../events'; -import { DispatchUiEvent, UseUiEvent } from '../../../../../hooks'; -import { GetCurrencyAmount } from '../../../../purse/common/CurrencyHelper'; -import { useCatalogContext } from '../../../CatalogContext'; -import { CatalogPurchaseState } from '../../../common/CatalogPurchaseState'; -import { Offer } from '../../../common/Offer'; +import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../../../../events'; +import { DispatchUiEvent, useCatalog, useLocalStorage, usePurse, UseUiEvent } from '../../../../../hooks'; interface CatalogPurchaseWidgetViewProps { @@ -20,17 +16,9 @@ export const CatalogPurchaseWidgetView: FC = pro const { noGiftOption = false, purchaseCallback = null } = props; const [ purchaseWillBeGift, setPurchaseWillBeGift ] = useState(false); const [ purchaseState, setPurchaseState ] = useState(CatalogPurchaseState.NONE); - const { currentOffer = null, currentPage = null, purchaseOptions = null, setPurchaseOptions = null } = useCatalogContext(); - - const onCatalogInitPurchaseEvent = useCallback((event: CatalogInitPurchaseEvent) => - { - if(!currentOffer) return; - - // show purchase confirmation - // offer, page.pageId, extraData, quantity, previewStuffData, null, true, null - }, [ currentOffer ]); - - UseUiEvent(CatalogWidgetEvent.INIT_PURCHASE, onCatalogInitPurchaseEvent); + const [ catalogSkipPurchaseConfirmation, setCatalogSkipPurchaseConfirmation ] = useLocalStorage(LocalStorageKeys.CATALOG_SKIP_PURCHASE_CONFIRMATION, false); + const { currentOffer = null, currentPage = null, purchaseOptions = null, setPurchaseOptions = null } = useCatalog(); + const { getCurrencyAmount = null } = usePurse(); const onCatalogEvent = useCallback((event: CatalogEvent) => { @@ -148,9 +136,9 @@ export const CatalogPurchaseWidgetView: FC = pro if(isLimitedSoldOut) return ; - if(priceCredits > GetCurrencyAmount(-1)) return ; + if(priceCredits > getCurrencyAmount(-1)) return ; - if(pricePoints > GetCurrencyAmount(currentOffer.activityPointType)) return ; + if(pricePoints > getCurrencyAmount(currentOffer.activityPointType)) return ; switch(purchaseState) { diff --git a/src/components/catalog/views/page/widgets/CatalogSimplePriceWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogSimplePriceWidgetView.tsx index 80b5dafb..694507df 100644 --- a/src/components/catalog/views/page/widgets/CatalogSimplePriceWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogSimplePriceWidgetView.tsx @@ -1,6 +1,6 @@ import { FC } from 'react'; -import { Flex, FlexProps } from '../../../../../common/Flex'; -import { useCatalogContext } from '../../../CatalogContext'; +import { Flex, FlexProps } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; import { CatalogPriceDisplayWidgetView } from './CatalogPriceDisplayWidgetView'; interface CatalogSimplePriceWidgetViewProps extends FlexProps @@ -11,7 +11,7 @@ interface CatalogSimplePriceWidgetViewProps extends FlexProps export const CatalogSimplePriceWidgetView: FC = props => { const { gap = 1, ...rest } = props; - const { currentOffer = null } = useCatalogContext(); + const { currentOffer = null } = useCatalog(); return ( diff --git a/src/components/catalog/views/page/widgets/CatalogSpacesWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogSpacesWidgetView.tsx index 8ade2a26..fdc3f5f4 100644 --- a/src/components/catalog/views/page/widgets/CatalogSpacesWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogSpacesWidgetView.tsx @@ -1,13 +1,7 @@ import { FC, useEffect, useState } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { AutoGrid, AutoGridProps } from '../../../../../common/AutoGrid'; -import { Button } from '../../../../../common/Button'; -import { ButtonGroup } from '../../../../../common/ButtonGroup'; -import { BatchUpdates } from '../../../../../hooks'; -import { useCatalogContext } from '../../../CatalogContext'; -import { IPurchasableOffer } from '../../../common/IPurchasableOffer'; -import { Offer } from '../../../common/Offer'; -import { ProductTypeEnum } from '../../../common/ProductTypeEnum'; +import { IPurchasableOffer, LocalizeText, Offer, ProductTypeEnum } from '../../../../../api'; +import { AutoGrid, AutoGridProps, Button, ButtonGroup } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; import { CatalogGridOfferView } from '../common/CatalogGridOfferView'; interface CatalogSpacesWidgetViewProps extends AutoGridProps @@ -23,7 +17,21 @@ export const CatalogSpacesWidgetView: FC = props = const [ groupedOffers, setGroupedOffers ] = useState(null); const [ selectedGroupIndex, setSelectedGroupIndex ] = useState(-1); const [ selectedOfferForGroup, setSelectedOfferForGroup ] = useState(null); - const { currentPage = null, currentOffer = null, setCurrentOffer = null, setPurchaseOptions = null } = useCatalogContext(); + const { currentPage = null, currentOffer = null, setCurrentOffer = null, setPurchaseOptions = null } = useCatalog(); + + const setSelectedOffer = (offer: IPurchasableOffer) => + { + if(!offer) return; + + setSelectedOfferForGroup(prevValue => + { + const newValue = [ ...prevValue ]; + + newValue[selectedGroupIndex] = offer; + + return newValue; + }); + } useEffect(() => { @@ -55,12 +63,9 @@ export const CatalogSpacesWidgetView: FC = props = } } - BatchUpdates(() => - { - setGroupedOffers(groupedOffers); - setSelectedGroupIndex(0); - setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]); - }); + setGroupedOffers(groupedOffers); + setSelectedGroupIndex(0); + setSelectedOfferForGroup([ groupedOffers[0][0], groupedOffers[1][0], groupedOffers[2][0] ]); }, [ currentPage ]); useEffect(() => @@ -76,14 +81,14 @@ export const CatalogSpacesWidgetView: FC = props = if((selectedGroupIndex === -1) || !selectedOfferForGroup || !currentOffer) return; setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.extraData = selectedOfferForGroup[selectedGroupIndex].product.extraParam; - newValue.extraParamRequired = true; + newValue.extraData = selectedOfferForGroup[selectedGroupIndex].product.extraParam; + newValue.extraParamRequired = true; - return newValue; - }); + return newValue; + }); }, [ currentOffer, selectedGroupIndex, selectedOfferForGroup, setPurchaseOptions ]); if(!groupedOffers || (selectedGroupIndex === -1)) return null; @@ -96,22 +101,7 @@ export const CatalogSpacesWidgetView: FC = props = { SPACES_GROUP_NAMES.map((name, index) => ) } - { offers && (offers.length > 0) && offers.map((offer, index) => - { - const setSelectedOffer = () => - { - setSelectedOfferForGroup(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue[selectedGroupIndex] = offer; - - return newValue; - }); - } - - return ; - }) } + { offers && (offers.length > 0) && offers.map((offer, index) => setSelectedOffer(offer) } />) } { children } diff --git a/src/components/catalog/views/page/widgets/CatalogSpinnerWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogSpinnerWidgetView.tsx index 47f8a3a1..2749fa7b 100644 --- a/src/components/catalog/views/page/widgets/CatalogSpinnerWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogSpinnerWidgetView.tsx @@ -1,16 +1,15 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FC } from 'react'; import { LocalizeText } from '../../../../../api'; -import { Flex } from '../../../../../common/Flex'; -import { Text } from '../../../../../common/Text'; -import { useCatalogContext } from '../../../CatalogContext'; +import { Flex, Text } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; const MIN_VALUE: number = 1; const MAX_VALUE: number = 100; export const CatalogSpinnerWidgetView: FC<{}> = props => { - const { currentOffer = null, purchaseOptions = null, setPurchaseOptions = null } = useCatalogContext(); + const { currentOffer = null, purchaseOptions = null, setPurchaseOptions = null } = useCatalog(); const { quantity = 1 } = purchaseOptions; const updateQuantity = (value: number) => @@ -23,13 +22,13 @@ export const CatalogSpinnerWidgetView: FC<{}> = props => if(value === quantity) return; setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.quantity = value; + newValue.quantity = value; - return newValue; - }); + return newValue; + }); } if(!currentOffer || !currentOffer.bundlePurchaseAllowed) return null; @@ -39,7 +38,7 @@ export const CatalogSpinnerWidgetView: FC<{}> = props => { LocalizeText('catalog.bundlewidget.spinner.select.amount') } updateQuantity(quantity - 1) } /> - updateQuantity(event.target.valueAsNumber)} /> + updateQuantity(event.target.valueAsNumber) } /> updateQuantity(quantity + 1) } /> diff --git a/src/components/catalog/views/page/widgets/CatalogTotalPriceWidget.tsx b/src/components/catalog/views/page/widgets/CatalogTotalPriceWidget.tsx index ae10d810..b3f935ae 100644 --- a/src/components/catalog/views/page/widgets/CatalogTotalPriceWidget.tsx +++ b/src/components/catalog/views/page/widgets/CatalogTotalPriceWidget.tsx @@ -1,6 +1,6 @@ import { FC } from 'react'; -import { Column, ColumnProps } from '../../../../../common/Column'; -import { useCatalogContext } from '../../../CatalogContext'; +import { Column, ColumnProps } from '../../../../../common'; +import { useCatalog } from '../../../../../hooks'; import { CatalogPriceDisplayWidgetView } from './CatalogPriceDisplayWidgetView'; interface CatalogSimplePriceWidgetViewProps extends ColumnProps @@ -10,7 +10,7 @@ interface CatalogSimplePriceWidgetViewProps extends ColumnProps export const CatalogTotalPriceWidget: FC = props => { const { gap = 1, ...rest } = props; - const { currentOffer = null } = useCatalogContext(); + const { currentOffer = null } = useCatalog(); return ( diff --git a/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx index f6a709af..620ece15 100644 --- a/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx @@ -1,15 +1,12 @@ import { Vector3d } from '@nitrots/nitro-renderer'; import { FC, useEffect } from 'react'; -import { GetAvatarRenderManager, GetSessionDataManager } from '../../../../../api'; +import { FurniCategory, GetAvatarRenderManager, GetSessionDataManager, Offer, ProductTypeEnum } from '../../../../../api'; import { AutoGrid, Column, LayoutGridItem, LayoutRoomPreviewerView } from '../../../../../common'; -import { useCatalogContext } from '../../../CatalogContext'; -import { FurniCategory } from '../../../common/FurniCategory'; -import { Offer } from '../../../common/Offer'; -import { ProductTypeEnum } from '../../../common/ProductTypeEnum'; +import { useCatalog } from '../../../../../hooks'; export const CatalogViewProductWidgetView: FC<{}> = props => { - const { currentOffer = null, roomPreviewer = null, purchaseOptions = null } = useCatalogContext(); + const { currentOffer = null, roomPreviewer = null, purchaseOptions = null } = useCatalog(); const { previewStuffData = null } = purchaseOptions; useEffect(() => diff --git a/src/components/chat-history/ChatHistoryMessageHandler.tsx b/src/components/chat-history/ChatHistoryMessageHandler.tsx index 87f8e28d..77d27dc1 100644 --- a/src/components/chat-history/ChatHistoryMessageHandler.tsx +++ b/src/components/chat-history/ChatHistoryMessageHandler.tsx @@ -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); @@ -74,7 +74,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props => setNeedsRoomInsert(true); break; case RoomSessionEvent.ENDED: - //dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.HIDE_CHAT_HISTORY)); + //dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.HIDE_CHAT_HISTORY)); break; } }, []); @@ -104,7 +104,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props => setNeedsRoomInsert(false); } - }, [addChatEntry, addRoomHistoryEntry, needsRoomInsert]); + }, [ addChatEntry, addRoomHistoryEntry, needsRoomInsert ]); UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent); diff --git a/src/components/chat-history/ChatHistoryView.tsx b/src/components/chat-history/ChatHistoryView.tsx index e8b1afa6..03e63c0d 100644 --- a/src/components/chat-history/ChatHistoryView.tsx +++ b/src/components/chat-history/ChatHistoryView.tsx @@ -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'; @@ -34,7 +33,7 @@ export const ChatHistoryView: FC<{}> = props => { item.timestamp } { (item.type === ChatEntryType.TYPE_CHAT) && <> - + { item.message } } { (item.type === ChatEntryType.TYPE_ROOM_INFO) && @@ -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); - }); + setChatHistoryState(chatState); + setRoomHistoryState(roomState); return () => { @@ -118,19 +114,19 @@ export const ChatHistoryView: FC<{}> = props => { ({ height, width }) => - { - return ( - - ) - } } + { + return ( + + ) + } } } diff --git a/src/components/chat-history/common/Utilities.ts b/src/components/chat-history/common/Utilities.ts index 29b00cfa..12d6d3eb 100644 --- a/src/components/chat-history/common/Utilities.ts +++ b/src/components/chat-history/common/Utilities.ts @@ -1,5 +1,5 @@ export const currentDate = () => { const currentTime = new Date(); - return `${currentTime.getHours().toString().padStart(2, '0')}:${currentTime.getMinutes().toString().padStart(2, '0')}`; + return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; } diff --git a/src/components/floorplan-editor/FloorplanEditorContext.tsx b/src/components/floorplan-editor/FloorplanEditorContext.tsx index bd0c1ddf..6c582ed8 100644 --- a/src/components/floorplan-editor/FloorplanEditorContext.tsx +++ b/src/components/floorplan-editor/FloorplanEditorContext.tsx @@ -17,9 +17,6 @@ const FloorplanEditorContext = createContext({ setVisualizationSettings: null }); -export const FloorplanEditorContextProvider: FC> = props => -{ - return { props.children } -} +export const FloorplanEditorContextProvider: FC> = props => ; export const useFloorplanEditorContext = () => useContext(FloorplanEditorContext); diff --git a/src/components/floorplan-editor/FloorplanEditorView.tsx b/src/components/floorplan-editor/FloorplanEditorView.tsx index b595916e..76ad8b53 100644 --- a/src/components/floorplan-editor/FloorplanEditorView.tsx +++ b/src/components/floorplan-editor/FloorplanEditorView.tsx @@ -1,9 +1,8 @@ -import { FloorHeightMapEvent, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; +import { FloorHeightMapEvent, ILinkEventTracker, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../api'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api'; import { Button, ButtonGroup, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; -import { FloorplanEditorEvent } from '../../events'; -import { UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks'; +import { UseMessageEventHook, UseRoomEngineEvent } from '../../hooks'; import { FloorplanEditor } from './common/FloorplanEditor'; import { IFloorplanSettings } from './common/IFloorplanSettings'; import { IVisualizationSettings } from './common/IVisualizationSettings'; @@ -20,7 +19,7 @@ export const FloorplanEditorView: FC<{}> = props => const [ originalFloorplanSettings, setOriginalFloorplanSettings ] = useState({ tilemap: '', reservedTiles: [], - entryPoint: [0, 0], + entryPoint: [ 0, 0 ], entryPointDir: 2, wallHeight: -1, thicknessWall: 1, @@ -33,86 +32,6 @@ export const FloorplanEditorView: FC<{}> = props => thicknessFloor: 1 }); - const onFloorplanEditorEvent = useCallback((event: FloorplanEditorEvent) => - { - switch(event.type) - { - case FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR: - setIsVisible(false); - break; - case FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR: - setIsVisible(true); - break; - case FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR: - setIsVisible(prevValue => !prevValue); - break; - } - }, []); - - UseUiEvent(FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR, onFloorplanEditorEvent); - UseUiEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR, onFloorplanEditorEvent); - UseUiEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR, onFloorplanEditorEvent); - - const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => - { - setIsVisible(false); - }, []); - - UseRoomEngineEvent(RoomEngineEvent.DISPOSED, onRoomEngineEvent); - - const onFloorHeightMapEvent = useCallback((event: FloorHeightMapEvent) => - { - const parser = event.getParser(); - - setOriginalFloorplanSettings(prevValue => - { - const newValue = { ...prevValue }; - - newValue.tilemap = parser.model; - newValue.wallHeight = (parser.wallHeight + 1); - - return newValue; - }); - - setVisualizationSettings(prevValue => - { - const newValue = { ...prevValue }; - - newValue.wallHeight = (parser.wallHeight + 1); - - return newValue; - }); - }, []); - - UseMessageEventHook(FloorHeightMapEvent, onFloorHeightMapEvent); - - const onRoomVisualizationSettingsEvent = useCallback((event: RoomVisualizationSettingsEvent) => - { - const parser = event.getParser(); - - setOriginalFloorplanSettings(prevValue => - { - const newValue = { ...prevValue }; - - newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); - newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall); - - return newValue; - }); - - setVisualizationSettings(prevValue => - { - const newValue = { ...prevValue }; - - newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); - newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall); - - return newValue; - }); - }, []); - - UseMessageEventHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent); - const saveFloorChanges = () => { SendMessageComposer(new UpdateFloorPropertiesMessageComposer( @@ -135,13 +54,103 @@ export const FloorplanEditorView: FC<{}> = props => FloorplanEditor.instance.renderTiles(); } + const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => + { + setIsVisible(false); + }, []); + + UseRoomEngineEvent(RoomEngineEvent.DISPOSED, onRoomEngineEvent); + + const onFloorHeightMapEvent = useCallback((event: FloorHeightMapEvent) => + { + const parser = event.getParser(); + + setOriginalFloorplanSettings(prevValue => + { + const newValue = { ...prevValue }; + + newValue.tilemap = parser.model; + newValue.wallHeight = (parser.wallHeight + 1); + + return newValue; + }); + + setVisualizationSettings(prevValue => + { + const newValue = { ...prevValue }; + + newValue.wallHeight = (parser.wallHeight + 1); + + return newValue; + }); + }, []); + + UseMessageEventHook(FloorHeightMapEvent, onFloorHeightMapEvent); + + const onRoomVisualizationSettingsEvent = useCallback((event: RoomVisualizationSettingsEvent) => + { + const parser = event.getParser(); + + setOriginalFloorplanSettings(prevValue => + { + const newValue = { ...prevValue }; + + newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); + newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall); + + return newValue; + }); + + setVisualizationSettings(prevValue => + { + const newValue = { ...prevValue }; + + newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); + newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall); + + return newValue; + }); + }, []); + + UseMessageEventHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent); + + useEffect(() => + { + const linkTracker: ILinkEventTracker = { + linkReceived: (url: string) => + { + const parts = url.split('/'); + + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'show': + setIsVisible(true); + return; + case 'hide': + setIsVisible(false); + return; + case 'toggle': + setIsVisible(prevValue => !prevValue); + return; + } + }, + eventUrlPrefix: 'floor-editor/' + }; + + AddEventLinkTracker(linkTracker); + + return () => RemoveLinkEventTracker(linkTracker); + }, []); + useEffect(() => { FloorplanEditor.instance.initialize(); }, []); return ( - + { isVisible && setIsVisible(false) } /> diff --git a/src/components/floorplan-editor/common/Constants.ts b/src/components/floorplan-editor/common/Constants.ts index 8f52f282..da66d515 100644 --- a/src/components/floorplan-editor/common/Constants.ts +++ b/src/components/floorplan-editor/common/Constants.ts @@ -12,7 +12,7 @@ export class FloorAction public static readonly UNSET = 4; } -export const COLORMAP: object = { +export const COLORMAP: object = { 'x': '101010', '0': '0065ff', '1': '0091ff', diff --git a/src/components/floorplan-editor/common/FloorplanEditor.ts b/src/components/floorplan-editor/common/FloorplanEditor.ts index ae81088a..34008af5 100644 --- a/src/components/floorplan-editor/common/FloorplanEditor.ts +++ b/src/components/floorplan-editor/common/FloorplanEditor.ts @@ -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); } diff --git a/src/components/floorplan-editor/common/Utils.ts b/src/components/floorplan-editor/common/Utils.ts index 6ffa52de..841b1938 100644 --- a/src/components/floorplan-editor/common/Utils.ts +++ b/src/components/floorplan-editor/common/Utils.ts @@ -7,17 +7,17 @@ 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] => { const translatedX = x - 1024; // after centering translation - const realX = ((translatedX /(TILE_SIZE / 2)) + (y / (TILE_SIZE / 4))) / 2; + 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 => diff --git a/src/components/floorplan-editor/views/FloorplanCanvasView.tsx b/src/components/floorplan-editor/views/FloorplanCanvasView.tsx index 4f392771..9ff612ab 100644 --- a/src/components/floorplan-editor/views/FloorplanCanvasView.tsx +++ b/src/components/floorplan-editor/views/FloorplanCanvasView.tsx @@ -5,15 +5,9 @@ import { SendMessageComposer } from '../../../api'; import { Base, Button, Column, ColumnProps, Flex, Grid } from '../../../common'; import { UseMessageEventHook } from '../../../hooks'; import { FloorplanEditor } from '../common/FloorplanEditor'; -import { IFloorplanSettings } from '../common/IFloorplanSettings'; import { useFloorplanEditorContext } from '../FloorplanEditorContext'; -interface FloorplanCanvasViewProps extends ColumnProps -{ - -} - -export const FloorplanCanvasView: FC = props => +export const FloorplanCanvasView: FC = props => { const { gap = 1, children = null, ...rest } = props; const [ occupiedTilesReceived , setOccupiedTilesReceived ] = useState(false); @@ -25,20 +19,16 @@ export const FloorplanCanvasView: FC = props => { const parser = event.getParser(); - let newFloorPlanSettings: IFloorplanSettings = null; - setOriginalFloorplanSettings(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.reservedTiles = parser.blockedTilesMap; + newValue.reservedTiles = parser.blockedTilesMap; - newFloorPlanSettings = newValue; + FloorplanEditor.instance.setTilemap(newValue.tilemap, newValue.reservedTiles); - return newValue; - }); - - FloorplanEditor.instance.setTilemap(newFloorPlanSettings.tilemap, parser.blockedTilesMap); + return newValue; + }); setOccupiedTilesReceived(true); @@ -52,23 +42,23 @@ export const FloorplanCanvasView: FC = props => const parser = event.getParser(); setOriginalFloorplanSettings(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.entryPoint = [ parser.x, parser.y ]; - newValue.entryPointDir = parser.direction; + newValue.entryPoint = [ parser.x, parser.y ]; + newValue.entryPointDir = parser.direction; - return newValue; - }); + return newValue; + }); setVisualizationSettings(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.entryPointDir = parser.direction; + newValue.entryPointDir = parser.direction; - return newValue; - }); + return newValue; + }); FloorplanEditor.instance.doorLocation = new NitroPoint(parser.x, parser.y); @@ -107,14 +97,14 @@ export const FloorplanCanvasView: FC = props => FloorplanEditor.instance.clear(); setVisualizationSettings(prevValue => - { - return { - wallHeight: originalFloorplanSettings.wallHeight, - thicknessWall: originalFloorplanSettings.thicknessWall, - thicknessFloor: originalFloorplanSettings.thicknessFloor, - entryPointDir: prevValue.entryPointDir - } - }); + { + return { + wallHeight: originalFloorplanSettings.wallHeight, + thicknessWall: originalFloorplanSettings.thicknessWall, + thicknessFloor: originalFloorplanSettings.thicknessFloor, + entryPointDir: prevValue.entryPointDir + } + }); } }, [ originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight, setVisualizationSettings ]); diff --git a/src/components/floorplan-editor/views/FloorplanImportExportView.tsx b/src/components/floorplan-editor/views/FloorplanImportExportView.tsx index 5523d073..c8f64d31 100644 --- a/src/components/floorplan-editor/views/FloorplanImportExportView.tsx +++ b/src/components/floorplan-editor/views/FloorplanImportExportView.tsx @@ -42,7 +42,7 @@ export const FloorplanImportExportView: FC = pro diff --git a/src/components/mod-tools/views/user/ModToolsUserView.tsx b/src/components/mod-tools/views/user/ModToolsUserView.tsx index 322aee1a..97c399d3 100644 --- a/src/components/mod-tools/views/user/ModToolsUserView.tsx +++ b/src/components/mod-tools/views/user/ModToolsUserView.tsx @@ -107,7 +107,7 @@ export const ModToolsUserView: FC = props => return ( <> - + onCloseClick() } /> @@ -115,19 +115,19 @@ export const ModToolsUserView: FC = props => { userProperties.map( (property, index) => - { + { - return ( - - - - - ); - }) } + return ( + + + + + ); + }) }
{ LocalizeText(property.localeKey) } - { property.value } - { property.showOnline && - } -
{ LocalizeText(property.localeKey) } + { property.value } + { property.showOnline && + } +
diff --git a/src/components/navigator/NavigatorMessageHandler.tsx b/src/components/navigator/NavigatorMessageHandler.tsx index 6b00eeef..da1b4256 100644 --- a/src/components/navigator/NavigatorMessageHandler.tsx +++ b/src/components/navigator/NavigatorMessageHandler.tsx @@ -1,7 +1,7 @@ import { CanCreateRoomEventEvent, CantConnectMessageParser, DoorbellMessageEvent, FlatAccessDeniedMessageEvent, FlatCreatedEvent, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, HabboWebTools, LegacyExternalInterface, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, 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 => @@ -44,14 +44,14 @@ export const NavigatorMessageHandler: FC<{}> = props => const parser = event.getParser(); setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR); - newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY); + newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR); + newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY); - return newValue; - }); + return newValue; + }); }, [ setNavigatorData ]); const onRoomForwardEvent = useCallback((event: RoomForwardEvent) => @@ -66,15 +66,15 @@ export const NavigatorMessageHandler: FC<{}> = props => const parser = event.getParser(); setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.enteredGuestRoom = null; - newValue.currentRoomOwner = parser.isOwner; - newValue.currentRoomId = parser.roomId; + newValue.enteredGuestRoom = null; + newValue.currentRoomOwner = parser.isOwner; + newValue.currentRoomId = parser.roomId; - return newValue; - }); + return newValue; + }); // close room info // close room settings @@ -94,28 +94,28 @@ export const NavigatorMessageHandler: FC<{}> = props => setDoorData({ roomInfo: null, state: DoorStateType.NONE }); setNavigatorData(prevValue => + { + const newValue = { ...prevValue }; + + newValue.enteredGuestRoom = parser.data; + newValue.currentRoomIsStaffPick = parser.staffPick; + + const isCreated = (newValue.createdFlatId === parser.data.roomId); + + if(!isCreated && parser.data.displayRoomEntryAd) { - const newValue = { ...prevValue }; + if(GetConfiguration('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd(); + } - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; + newValue.createdFlatId = 0; - const isCreated = (newValue.createdFlatId === parser.data.roomId); + if(newValue.enteredGuestRoom && (newValue.enteredGuestRoom.habboGroupId > 0)) + { + // close event info + } - if(!isCreated && parser.data.displayRoomEntryAd) - { - if(GetConfiguration('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd(); - } - - newValue.createdFlatId = 0; - - if(newValue.enteredGuestRoom && (newValue.enteredGuestRoom.habboGroupId > 0)) - { - // close event info - } - - return newValue; - }); + return newValue; + }); } else if(parser.roomForward) { @@ -125,25 +125,25 @@ export const NavigatorMessageHandler: FC<{}> = props => { case RoomDataParser.DOORBELL_STATE: setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_DOORBELL; + newValue.roomInfo = parser.data; + newValue.state = DoorStateType.START_DOORBELL; - return newValue; - }); + return newValue; + }); return; case RoomDataParser.PASSWORD_STATE: setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_PASSWORD; + newValue.roomInfo = parser.data; + newValue.state = DoorStateType.START_PASSWORD; - return newValue; - }); + return newValue; + }); return; } } @@ -155,14 +155,14 @@ export const NavigatorMessageHandler: FC<{}> = props => else { setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; + newValue.enteredGuestRoom = parser.data; + newValue.currentRoomIsStaffPick = parser.staffPick; - return newValue; - }); + return newValue; + }); } }, [ setNavigatorData, setDoorData ]); @@ -171,14 +171,14 @@ export const NavigatorMessageHandler: FC<{}> = props => const parser = event.getParser(); setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.currentRoomRating = parser.totalLikes; - newValue.canRate = parser.canLike; + newValue.currentRoomRating = parser.totalLikes; + newValue.canRate = parser.canLike; - return newValue; - }); + return newValue; + }); }, [ setNavigatorData ]); const onRoomDoorbellEvent = useCallback((event: DoorbellMessageEvent) => @@ -188,13 +188,13 @@ export const NavigatorMessageHandler: FC<{}> = props => if(!parser.userName || (parser.userName.length === 0)) { setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_WAITING; + newValue.state = DoorStateType.STATE_WAITING; - return newValue; - }); + return newValue; + }); } }, [ setDoorData ]); @@ -205,13 +205,13 @@ export const NavigatorMessageHandler: FC<{}> = props => if(!parser.userName || (parser.userName.length === 0)) { setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_ACCEPTED; + newValue.state = DoorStateType.STATE_ACCEPTED; - return newValue; - }); + return newValue; + }); } }, [ setDoorData ]); @@ -222,13 +222,13 @@ export const NavigatorMessageHandler: FC<{}> = props => if(!parser.userName || (parser.userName.length === 0)) { setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_NO_ANSWER; + newValue.state = DoorStateType.STATE_NO_ANSWER; - return newValue; - }); + return newValue; + }); } }, [ setDoorData ]); @@ -240,13 +240,13 @@ export const NavigatorMessageHandler: FC<{}> = props => { case -100002: setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_WRONG_PASSWORD; + newValue.state = DoorStateType.STATE_WRONG_PASSWORD; - return newValue; - }); + return newValue; + }); return; case 4009: NotificationUtilities.simpleAlert(LocalizeText('navigator.alert.need.to.be.vip'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title')); @@ -271,49 +271,43 @@ export const NavigatorMessageHandler: FC<{}> = props => { const parser = event.getParser(); - BatchUpdates(() => - { - setTopLevelContexts(parser.topLevelContexts); - setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null); - }); + 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 => { - setTopLevelContext(prevValue => + let newValue = prevValue; + + if(!newValue) newValue = ((topLevelContexts && topLevelContexts.length && topLevelContexts[0]) || null); + + if(!newValue) return null; + + if((parser.result.code !== newValue.code) && topLevelContexts && topLevelContexts.length) + { + for(const context of topLevelContexts) { - let newValue = prevValue; + if(context.code !== parser.result.code) continue; - if(!newValue) newValue = ((topLevelContexts && topLevelContexts.length && topLevelContexts[0]) || null); + newValue = context; + } + } - if(!newValue) return null; + for(const context of topLevelContexts) + { + if(context.code !== parser.result.code) continue; - if((parser.result.code !== newValue.code) && topLevelContexts && topLevelContexts.length) - { - for(const context of topLevelContexts) - { - if(context.code !== parser.result.code) continue; + newValue = context; + } - newValue = context; - } - } - - for(const context of topLevelContexts) - { - if(context.code !== parser.result.code) continue; - - newValue = context; - } - - return newValue; - }); - - setSearchResult(parser.result); + return newValue; }); + + setSearchResult(parser.result); }, [ topLevelContexts, setTopLevelContext, setSearchResult ]); const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) => @@ -337,16 +331,16 @@ export const NavigatorMessageHandler: FC<{}> = props => let prevSettingsReceived = false; setNavigatorData(prevValue => - { - prevSettingsReceived = prevValue.settingsReceived; + { + prevSettingsReceived = prevValue.settingsReceived; - const newValue = { ...prevValue }; + const newValue = { ...prevValue }; - newValue.homeRoomId = parser.homeRoomId; - newValue.settingsReceived = true; + newValue.homeRoomId = parser.homeRoomId; + newValue.settingsReceived = true; - return newValue; - }); + return newValue; + }); if(prevSettingsReceived) { diff --git a/src/components/navigator/NavigatorView.scss b/src/components/navigator/NavigatorView.scss index 22b513ce..ef235bc0 100644 --- a/src/components/navigator/NavigatorView.scss +++ b/src/components/navigator/NavigatorView.scss @@ -59,3 +59,7 @@ } } } + +.room-info { + width: 275px; +} diff --git a/src/components/navigator/NavigatorView.tsx b/src/components/navigator/NavigatorView.tsx index fa2740b6..d54c885d 100644 --- a/src/components/navigator/NavigatorView.tsx +++ b/src/components/navigator/NavigatorView.tsx @@ -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); - }); + setIsVisible(false); + setCreatorOpen(false); return; } }, []); @@ -96,11 +93,8 @@ export const NavigatorView: FC<{}> = props => switch(parts[1]) { case 'show': { - BatchUpdates(() => - { - setIsVisible(true); - setNeedsSearch(true); - }); + setIsVisible(true); + setNeedsSearch(true); return; } case 'hide': @@ -114,11 +108,8 @@ export const NavigatorView: FC<{}> = props => return; } - BatchUpdates(() => - { - setIsVisible(true); - setNeedsSearch(true); - }); + 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); - }); + 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); - }); + setIsVisible(true); + setNeedsSearch(true); } return; } @@ -229,18 +214,18 @@ export const NavigatorView: FC<{}> = props => setIsVisible(false) } /> { topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) => - { - return ( - sendSearch('', context.code) }> - { LocalizeText(('navigator.toplevelview.' + context.code)) } - - ); - }) } + { + return ( + sendSearch('', context.code) }> + { LocalizeText(('navigator.toplevelview.' + context.code)) } + + ); + }) } setCreatorOpen(true) }> - + { isLoading && } { !isCreatorOpen && diff --git a/src/components/navigator/views/NavigatorDoorStateView.tsx b/src/components/navigator/views/NavigatorDoorStateView.tsx index 26324a61..d9b4228e 100644 --- a/src/components/navigator/views/NavigatorDoorStateView.tsx +++ b/src/components/navigator/views/NavigatorDoorStateView.tsx @@ -26,13 +26,13 @@ export const NavigatorDoorStateView: FC<{}> = props => CreateRoomSession(doorData.roomInfo.roomId); setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_PENDING_SERVER; + newValue.state = DoorStateType.STATE_PENDING_SERVER; - return newValue; - }); + return newValue; + }); } const tryEntering = () => @@ -42,13 +42,13 @@ export const NavigatorDoorStateView: FC<{}> = props => CreateRoomSession(doorData.roomInfo.roomId, password); setDoorData(prevValue => - { - const newValue = { ...prevValue }; + { + const newValue = { ...prevValue }; - newValue.state = DoorStateType.STATE_PENDING_SERVER; + newValue.state = DoorStateType.STATE_PENDING_SERVER; - return newValue; - }); + return newValue; + }); } useEffect(() => diff --git a/src/components/navigator/views/NavigatorRoomCreatorView.tsx b/src/components/navigator/views/NavigatorRoomCreatorView.tsx index 47ddde7e..73f7a8d5 100644 --- a/src/components/navigator/views/NavigatorRoomCreatorView.tsx +++ b/src/components/navigator/views/NavigatorRoomCreatorView.tsx @@ -1,9 +1,8 @@ /* eslint-disable no-template-curly-in-string */ import { CreateFlatMessageComposer, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; -import { GetClubMemberLevel, GetConfiguration, IRoomModel, LocalizeText, RoomModels, SendMessageComposer } from '../../../api'; +import { GetClubMemberLevel, GetConfiguration, IRoomModel, LocalizeText, 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 => @@ -14,22 +13,25 @@ export const NavigatorRoomCreatorView: FC<{}> = props => const [ category, setCategory ] = useState(null); const [ visitorsCount, setVisitorsCount ] = useState(null); const [ tradesSetting, setTradesSetting ] = useState(0); - const [ selectedModelName, setSelectedModelName ] = useState(RoomModels[0].name); + const [ roomModels, setRoomModels ] = useState([]); + const [ selectedModelName, setSelectedModelName ] = useState(''); const { categories = null } = useNavigatorContext(); + const hcDisabled = GetConfiguration('hc.disabled', false); + const getRoomModelImage = (name: string) => GetConfiguration('images.url') + `/navigator/models/model_${ name }.png`; const selectModel = (model: IRoomModel, index: number) => { if(!model || (model.clubLevel > GetClubMemberLevel())) return; - setSelectedModelName(RoomModels[index].name); - } + setSelectedModelName(roomModels[index].name); + }; const createRoom = () => { SendMessageComposer(new CreateFlatMessageComposer(name, description, 'model_' + selectedModelName, Number(category), Number(visitorsCount), tradesSetting)); - } + }; useEffect(() => { @@ -39,11 +41,8 @@ export const NavigatorRoomCreatorView: FC<{}> = props => for(let i = 10; i <= 100; i = i + 10) list.push(i); - BatchUpdates(() => - { - setMaxVisitorsList(list); - setVisitorsCount(list[0]); - }); + setMaxVisitorsList(list); + setVisitorsCount(list[0]); } }, [ maxVisitorsList ]); @@ -52,6 +51,17 @@ export const NavigatorRoomCreatorView: FC<{}> = props => if(categories && categories.length) setCategory(categories[0].id); }, [ categories ]); + useEffect(() => + { + const models = GetConfiguration('navigator.room.models'); + + if(models && models.length) + { + setRoomModels(models); + setSelectedModelName(models[0].name); + } + }, []); + return ( @@ -62,24 +72,24 @@ export const NavigatorRoomCreatorView: FC<{}> = props => { LocalizeText('navigator.createroom.roomdescinfo') } -