From 535fa71020ccd2dc82b6638cf4e2663c37c6233b Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Mon, 11 May 2026 16:31:50 +0000 Subject: [PATCH] ESLint --fix: auto-fix brace-style, indent, semi, no-trailing-spaces Run eslint --fix across src/ to clear ~1900 mechanical lint errors surfaced by the @typescript-eslint v8 + react-hooks v7 + react-compiler upgrade in the React 19 modernization PR. Issues fixed automatically: - brace-style (Allman): try/catch one-liners reformatted to multi-line - indent: tab-vs-space and depth corrections - semi: missing trailing semicolons - no-trailing-spaces No semantic changes. Remaining 701 errors are real-code issues (set-state-in-effect, rules-of-hooks, no-unsafe-* type checks) that need manual per-file review. https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q --- src/App.tsx | 32 +- src/api/auth/accessToken.ts | 18 +- .../avatar/AvatarEditorThumbnailsHelper.ts | 2 +- src/api/badges/CustomBadgeApi.ts | 33 +- src/api/catalog/FurnitureOffer.ts | 2 +- src/api/friends/GetGroupChatData.ts | 2 +- src/api/room/widgets/AvatarInfoUser.ts | 2 +- src/api/room/widgets/AvatarInfoUtilities.ts | 2 +- .../widgets/ChooserSelectionVisualizer.ts | 12 +- src/api/room/widgets/MannequinUtilities.ts | 2 +- src/api/ui-settings/UiSettingsContext.tsx | 18 +- src/api/utils/ProductImageUtility.ts | 2 +- src/api/utils/RememberLogin.ts | 11 +- src/api/youtube/YouTubeRoomState.ts | 5 +- .../images/user_custom/nick_icons/index.ts | 2 +- src/bootstrap.ts | 12 +- src/common/Button.tsx | 6 +- src/common/ButtonGroup.tsx | 2 +- src/common/Slider.tsx | 2 +- src/common/Text.tsx | 29 +- .../draggable-window/DraggableWindow.tsx | 86 ++- src/common/index.ts | 2 +- src/common/layout/LayoutFurniImageView.tsx | 5 +- src/common/layout/LayoutMiniCameraView.tsx | 9 +- .../layout/LayoutRoomObjectImageView.tsx | 5 +- src/components/MainView.tsx | 2 +- src/components/ads/GoogleAdsView.tsx | 63 +- .../AvatarEditorAdvancedColorView.tsx | 12 +- .../avatar-effects/AvatarEffectsView.tsx | 9 +- .../backgrounds/BackgroundsView.tsx | 12 +- .../badge-creator/BadgeCreatorView.tsx | 58 +- .../views/CameraWidgetShowPhotoView.tsx | 32 +- .../views/editor/CameraWidgetEditorView.tsx | 54 +- .../CameraWidgetEffectListItemView.tsx | 10 +- .../CameraWidgetEffectListView.tsx | 4 +- .../catalog/CatalogAdminContext.tsx | 5 +- src/components/catalog/CatalogClassicView.tsx | 21 +- src/components/catalog/CatalogModernView.tsx | 11 +- .../views/favorites/CatalogFavoritesView.tsx | 20 +- .../catalog/views/gift/CatalogGiftView.tsx | 5 +- .../navigation/CatalogNavigationItemView.tsx | 5 +- .../page/common/CatalogGridOfferView.tsx | 5 +- .../views/page/common/CatalogSearchView.tsx | 2 +- .../CatalogLayoutBuildersClubBuyView.tsx | 59 +- .../layout/CatalogLayoutCustomPrefixView.tsx | 25 +- .../page/layout/CatalogLayoutDefaultView.tsx | 5 +- .../page/layout/CatalogLayoutTrophiesView.tsx | 5 +- .../page/layout/pets/CatalogLayoutPetView.tsx | 5 +- .../widgets/CatalogPurchaseWidgetView.tsx | 5 +- .../chat-history/ChatHistoryView.tsx | 50 +- .../customize/CustomizeNickIconView.tsx | 81 +-- .../views/FloorplanImportExportView.tsx | 4 +- src/components/friends/FriendsView.tsx | 3 +- .../views/friends-bar/FriendBarItemView.tsx | 47 +- .../views/friends-bar/FriendsBarView.tsx | 21 +- .../views/friends-list/FriendsListView.tsx | 10 +- .../furni-editor/FurniEditorView.tsx | 4 +- .../views/forums/GroupForumListView.tsx | 10 +- .../views/forums/GroupForumThreadListView.tsx | 10 +- src/components/hotel-view/HotelView.tsx | 32 +- src/components/hotel-view/RoomWidgetView.tsx | 3 +- .../InterfaceColorTabView.tsx | 3 +- .../views/badge/InventoryBadgeView.tsx | 13 +- src/components/loading/LoadingView.tsx | 3 +- src/components/login/LoginView.tsx | 141 ++++- src/components/login/TurnstileWidget.tsx | 14 +- .../login/components/NewsWindow.tsx | 25 +- .../login/components/RegisterDialog.tsx | 83 ++- src/components/login/utils/i18n.ts | 13 +- src/components/login/utils/lockState.ts | 13 +- src/components/login/utils/news.ts | 15 +- .../views/room/ModToolsChatlogView.tsx | 2 +- .../NavigatorRoomSettingsAccessTabView.tsx | 2 +- .../NavigatorRoomSettingsBasicTabView.tsx | 10 +- .../NavigatorRoomSettingsModTabView.tsx | 6 +- .../NavigatorRoomSettingsRightsTabView.tsx | 4 +- .../NavigatorRoomSettingsView.tsx | 5 +- .../NavigatorSearchResultItemInfoView.tsx | 10 +- .../NitrobubbleHiddenView.tsx | 10 +- .../alert-layouts/NitroSystemAlertView.tsx | 18 +- src/components/plugins/NitroPluginApi.ts | 15 +- src/components/purse/PurseView.tsx | 71 ++- src/components/purse/views/CurrencyView.tsx | 2 +- src/components/purse/views/SeasonalView.tsx | 55 +- src/components/room/RoomView.tsx | 8 +- .../infostand/InfoStandWidgetFurniView.tsx | 5 +- .../infostand/InfoStandWidgetPetView.tsx | 557 ++++++++--------- .../infostand/InfoStandWidgetUserView.tsx | 562 +++++++++--------- .../chat-input/ChatInputStyleSelectorView.tsx | 72 +-- .../room/widgets/chat-input/ChatInputView.tsx | 5 +- .../widgets/choosers/ChooserWidgetView.tsx | 14 +- .../widgets/context-menu/ContextMenuView.tsx | 229 +++---- .../furniture/FurnitureExternalImageView.tsx | 11 +- .../room-tools/RoomToolsWidgetView.tsx | 43 +- src/components/toolbar/ToolbarView.tsx | 38 +- src/components/toolbar/YouTubePlayerView.tsx | 378 +++++++----- .../wired-tools/WiredCreatorToolsView.tsx | 116 ++-- .../wired/views/WiredVariablePickerData.ts | 54 +- .../actions/WiredActionFurniToFurniView.tsx | 2 +- .../actions/WiredActionGiveRewardView.tsx | 12 +- .../actions/WiredActionSendSignalView.tsx | 15 +- .../WiredConditionFurniIsOfTypeView.tsx | 2 +- .../extras/WiredExtraFilterByVariableView.tsx | 2 +- .../WiredExtraTextInputVariableView.tsx | 2 +- .../selectors/WiredActionFurniAreaView.tsx | 2 +- .../WiredSelectorFurniByTypeView.tsx | 12 +- .../WiredSelectorWithVariableView.tsx | 2 +- src/hooks/avatar-editor/useAvatarEditor.ts | 2 +- src/hooks/furni-editor/useFurniEditor.ts | 3 +- src/hooks/inventory/useInventoryBots.ts | 4 +- .../rooms/widgets/useAvatarInfoWidget.ts | 4 +- .../rooms/widgets/useUserChooserWidget.ts | 2 +- src/hooks/useLocalStorage.ts | 8 +- src/hooks/wired/useWired.ts | 12 +- src/secure-assets.ts | 18 +- 115 files changed, 2217 insertions(+), 1524 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 20b1f54..4a04744 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,7 +36,8 @@ const preloadUrl = async (url: string): Promise => const response = await fetch(url, { cache: 'force-cache' }); await response.arrayBuffer(); } - catch {} + catch + {} }; const preloadImage = (url: string): void => @@ -49,7 +50,8 @@ const preloadImage = (url: string): void => image.decoding = 'async'; image.src = url; } - catch {} + catch + {} }; const asStringArray = (value: unknown): string[] => @@ -126,8 +128,12 @@ export const App: FC<{}> = props => }); let payload: Record = {}; - try { payload = await response.json(); } - catch {} + try + { + payload = await response.json(); + } + catch + {} const ssoTicket = typeof payload.ssoTicket === 'string' ? payload.ssoTicket : (typeof payload.sso === 'string' ? payload.sso : ''); @@ -175,8 +181,12 @@ export const App: FC<{}> = props => }); let payload: Record = {}; - try { payload = await response.json(); } - catch {} + try + { + payload = await response.json(); + } + catch + {} if(response.ok) { @@ -320,8 +330,14 @@ export const App: FC<{}> = props => // Configuration is loaded lazily — fetch it up-front so the login // screen toggle and Turnstile keys are available before we decide. let configInitError: unknown = null; - try { await GetConfiguration().init(); } - catch(e) { configInitError = e; } + try + { + await GetConfiguration().init(); + } + catch(e) + { + configInitError = e; + } const rawLoginEnabled = GetConfiguration().getValue('login.screen.enabled', false); const loginScreenEnabled = rawLoginEnabled === true || rawLoginEnabled === 'true' || rawLoginEnabled === 1; diff --git a/src/api/auth/accessToken.ts b/src/api/auth/accessToken.ts index 1d53575..94f7d51 100644 --- a/src/api/auth/accessToken.ts +++ b/src/api/auth/accessToken.ts @@ -17,13 +17,20 @@ export const setAccessToken = (token: string | null | undefined, expiresAt?: num window.localStorage.removeItem(EXPIRES_KEY); } } - catch {} + catch + {} }; export const getAccessToken = (): string => { - try { return window.localStorage.getItem(STORAGE_KEY) ?? ''; } - catch { return ''; } + try + { + return window.localStorage.getItem(STORAGE_KEY) ?? ''; + } + catch + { + return ''; + } }; export const getAccessTokenExpiresAt = (): number => @@ -35,7 +42,10 @@ export const getAccessTokenExpiresAt = (): number => const value = parseInt(raw, 10); return Number.isFinite(value) ? value : 0; } - catch { return 0; } + catch + { + return 0; + } }; export const clearAccessToken = (): void => diff --git a/src/api/avatar/AvatarEditorThumbnailsHelper.ts b/src/api/avatar/AvatarEditorThumbnailsHelper.ts index 5176436..c90eb1b 100644 --- a/src/api/avatar/AvatarEditorThumbnailsHelper.ts +++ b/src/api/avatar/AvatarEditorThumbnailsHelper.ts @@ -87,7 +87,7 @@ export class AvatarEditorThumbnailsHelper AvatarFigurePartType.PET, 'ptl', 'ptr', - AvatarFigurePartType.MISC, + AvatarFigurePartType.MISC, 'mcl', 'mcr', ]; diff --git a/src/api/badges/CustomBadgeApi.ts b/src/api/badges/CustomBadgeApi.ts index 9e6eeca..1cf9d88 100644 --- a/src/api/badges/CustomBadgeApi.ts +++ b/src/api/badges/CustomBadgeApi.ts @@ -31,8 +31,14 @@ export interface CustomBadgeError const interpolate = (value: string): string => { - try { return GetConfiguration().interpolate(value); } - catch { return value; } + try + { + return GetConfiguration().interpolate(value); + } + catch + { + return value; + } }; const getConfigUrl = (key: string, fallback: string): string => @@ -61,8 +67,14 @@ const parseJson = async (response: Response): Promise => { const text = await response.text(); if(!text) return {} as T; - try { return JSON.parse(text) as T; } - catch { throw new Error('Invalid response from server.'); } + try + { + return JSON.parse(text) as T; + } + catch + { + throw new Error('Invalid response from server.'); + } }; const throwOnError = async (response: Response): Promise => @@ -129,8 +141,14 @@ const injectTextsIntoLocalization = (texts: Record | null | unde { if(!texts) return; let manager: ReturnType | null = null; - try { manager = GetLocalizationManager(); } - catch { return; } + try + { + manager = GetLocalizationManager(); + } + catch + { + return; + } if(!manager || typeof manager.setValue !== 'function') return; for(const key of Object.keys(texts)) { @@ -152,7 +170,8 @@ export const ensureCustomBadgeTexts = (): Promise => const payload = await parseJson<{ texts: Record }>(response); injectTextsIntoLocalization(payload.texts); } - catch {} + catch + {} })(); return customBadgeTextsLoadPromise; }; diff --git a/src/api/catalog/FurnitureOffer.ts b/src/api/catalog/FurnitureOffer.ts index acc1c14..e9b744c 100644 --- a/src/api/catalog/FurnitureOffer.ts +++ b/src/api/catalog/FurnitureOffer.ts @@ -15,7 +15,7 @@ export class FurnitureOffer implements IPurchasableOffer constructor(furniData: IFurnitureData) { this._furniData = furniData; - this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData) as IProduct); + this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData)); } public activate(): void diff --git a/src/api/friends/GetGroupChatData.ts b/src/api/friends/GetGroupChatData.ts index d1a2c7b..fe7feb8 100644 --- a/src/api/friends/GetGroupChatData.ts +++ b/src/api/friends/GetGroupChatData.ts @@ -9,5 +9,5 @@ export const GetGroupChatData = (extraData: string) => const figure = splitData[1]; const userId = parseInt(splitData[2]); - return ({ username: username, figure: figure, userId: userId } as IGroupChatData); + return ({ username: username, figure: figure, userId: userId }); }; diff --git a/src/api/room/widgets/AvatarInfoUser.ts b/src/api/room/widgets/AvatarInfoUser.ts index 2d3157e..a5b239b 100644 --- a/src/api/room/widgets/AvatarInfoUser.ts +++ b/src/api/room/widgets/AvatarInfoUser.ts @@ -20,7 +20,7 @@ export class AvatarInfoUser implements IAvatarInfo public prefixFont: string = ''; public displayOrder: string = 'icon-prefix-name'; public achievementScore: number = 0; - public backgroundId: number = 0; + public backgroundId: number = 0; public standId: number = 0; public overlayId: number = 0; public cardBackgroundId: number = 0; diff --git a/src/api/room/widgets/AvatarInfoUtilities.ts b/src/api/room/widgets/AvatarInfoUtilities.ts index ffd8b8a..f786aff 100644 --- a/src/api/room/widgets/AvatarInfoUtilities.ts +++ b/src/api/room/widgets/AvatarInfoUtilities.ts @@ -190,7 +190,7 @@ export class AvatarInfoUtilities userInfo.prefixEffect = userData.prefixEffect; userInfo.prefixFont = userData.prefixFont; userInfo.displayOrder = userData.displayOrder; - userInfo.backgroundId = userData.background; + userInfo.backgroundId = userData.background; userInfo.standId = userData.stand; userInfo.overlayId = userData.overlay; userInfo.cardBackgroundId = userData.cardBackground ?? 0; diff --git a/src/api/room/widgets/ChooserSelectionVisualizer.ts b/src/api/room/widgets/ChooserSelectionVisualizer.ts index b9bd248..b041a01 100644 --- a/src/api/room/widgets/ChooserSelectionVisualizer.ts +++ b/src/api/room/widgets/ChooserSelectionVisualizer.ts @@ -9,9 +9,11 @@ export class chooserSelectionVisualizer { if (this.animationFrameId !== null) return; - const animate = (time: number) => { + const animate = (time: number) => + { const elapsed = time / 1000; // Convert to seconds - this.activeFilters.forEach(filter => { + this.activeFilters.forEach(filter => + { filter.time = elapsed; // Update time uniform }); this.animationFrameId = requestAnimationFrame(animate); @@ -22,7 +24,8 @@ export class chooserSelectionVisualizer private static stopAnimation(): void { - if (this.animationFrameId !== null) { + if (this.animationFrameId !== null) + { cancelAnimationFrame(this.animationFrameId); this.animationFrameId = null; } @@ -69,7 +72,8 @@ export class chooserSelectionVisualizer sprite.filters = (sprite.filters || []).filter(f => !(f instanceof ChooserSelectionFilter)); } - if (this.activeFilters.size === 0) { + if (this.activeFilters.size === 0) + { this.stopAnimation(); } } diff --git a/src/api/room/widgets/MannequinUtilities.ts b/src/api/room/widgets/MannequinUtilities.ts index 74d45f9..2638eb9 100644 --- a/src/api/room/widgets/MannequinUtilities.ts +++ b/src/api/room/widgets/MannequinUtilities.ts @@ -33,6 +33,6 @@ export class MannequinUtilities figureContainer.removePart(part); } - figureContainer.updatePart((this.MANNEQUIN_FIGURE[0] as string), (this.MANNEQUIN_FIGURE[1] as number), (this.MANNEQUIN_FIGURE[2] as number[])); + figureContainer.updatePart((this.MANNEQUIN_FIGURE[0]), (this.MANNEQUIN_FIGURE[1]), (this.MANNEQUIN_FIGURE[2])); }; } diff --git a/src/api/ui-settings/UiSettingsContext.tsx b/src/api/ui-settings/UiSettingsContext.tsx index 23357f8..fb5abcb 100644 --- a/src/api/ui-settings/UiSettingsContext.tsx +++ b/src/api/ui-settings/UiSettingsContext.tsx @@ -18,8 +18,10 @@ interface IUiSettingsContext const UiSettingsContext = createContext({ settings: DEFAULT_UI_SETTINGS, isCustomActive: false, - updateSettings: () => {}, - resetSettings: () => {}, + updateSettings: () => + {}, + resetSettings: () => + {}, getHeaderStyle: () => ({}), getTabsStyle: () => ({}), getAccentColor: () => DEFAULT_UI_SETTINGS.headerColor @@ -42,7 +44,8 @@ const loadSettings = (): IUiSettings => const stored = localStorage.getItem(STORAGE_KEY); if(stored) return { ...DEFAULT_UI_SETTINGS, ...JSON.parse(stored) }; } - catch(e) {} + catch(e) + {} return { ...DEFAULT_UI_SETTINGS }; }; @@ -53,7 +56,8 @@ const saveSettings = (settings: IUiSettings): void => { localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); } - catch(e) {} + catch(e) + {} }; const sendComposer = (composer: any): void => @@ -62,7 +66,8 @@ const sendComposer = (composer: any): void => { GetCommunication()?.connection?.send(composer); } - catch(e) {} + catch(e) + {} }; export const UiSettingsProvider: FC = ({ children }) => @@ -93,7 +98,8 @@ export const UiSettingsProvider: FC = ({ children }) => saveSettings(serverSettings); } } - catch(e) {} + catch(e) + {} }; connection.addMessageEvent(new UiSettingsDataEvent(handler)); diff --git a/src/api/utils/ProductImageUtility.ts b/src/api/utils/ProductImageUtility.ts index 5443513..3f8fb80 100644 --- a/src/api/utils/ProductImageUtility.ts +++ b/src/api/utils/ProductImageUtility.ts @@ -32,7 +32,7 @@ export class ProductImageUtility } } break; - case FurnitureType.EFFECT: + case FurnitureType.EFFECT: // fx_icon_furniClassId_png break; } diff --git a/src/api/utils/RememberLogin.ts b/src/api/utils/RememberLogin.ts index 6609af8..9920614 100644 --- a/src/api/utils/RememberLogin.ts +++ b/src/api/utils/RememberLogin.ts @@ -53,8 +53,12 @@ export const SetRememberLogin = (data: RememberLoginData): void => { if(!data?.token?.length && !data?.ssoTicket?.length) return; - try { window.localStorage.setItem(REMEMBER_LOGIN_KEY, JSON.stringify(data)); } - catch {} + try + { + window.localStorage.setItem(REMEMBER_LOGIN_KEY, JSON.stringify(data)); + } + catch + {} }; export const ClearRememberLogin = (): void => @@ -64,7 +68,8 @@ export const ClearRememberLogin = (): void => window.localStorage.removeItem(REMEMBER_LOGIN_KEY); window.localStorage.removeItem(LEGACY_REMEMBER_LOGIN_KEY); } - catch {} + catch + {} }; export const StoreRememberLoginFromPayload = (payload: Record, username?: string, ssoTicket?: string): void => diff --git a/src/api/youtube/YouTubeRoomState.ts b/src/api/youtube/YouTubeRoomState.ts index 364bf19..951011b 100644 --- a/src/api/youtube/YouTubeRoomState.ts +++ b/src/api/youtube/YouTubeRoomState.ts @@ -1,4 +1,7 @@ let _youtubeEnabled = false; export const getYoutubeRoomEnabled = () => _youtubeEnabled; -export const setYoutubeRoomEnabled = (enabled: boolean) => { _youtubeEnabled = enabled; }; +export const setYoutubeRoomEnabled = (enabled: boolean) => +{ + _youtubeEnabled = enabled; +}; diff --git a/src/assets/images/user_custom/nick_icons/index.ts b/src/assets/images/user_custom/nick_icons/index.ts index 5881930..dd7b6a1 100644 --- a/src/assets/images/user_custom/nick_icons/index.ts +++ b/src/assets/images/user_custom/nick_icons/index.ts @@ -1,4 +1,4 @@ -const rawNickIcons = import.meta.glob('./*.gif', { eager: true, import: 'default' }) as Record; +const rawNickIcons = import.meta.glob('./*.gif', { eager: true, import: 'default' }); export const NICK_ICON_URLS: Record = Object.entries(rawNickIcons).reduce((accumulator, [ path, url ]) => { diff --git a/src/bootstrap.ts b/src/bootstrap.ts index ecff7b4..3aeda2f 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -26,7 +26,8 @@ const setBootDebug = (message: string) => if(secureNode) secureNode.textContent = `${ secureNode.textContent }\n${ message }`; } - catch {} + catch + {} }; setBootDebug('boot: secure fetch installed'); @@ -38,14 +39,16 @@ const deployBaseUrl = (): string => const loaderBase = (window as any).__nitroLoaderBase; if(typeof loaderBase === 'string' && loaderBase.length) return new URL('..', loaderBase).toString(); } - catch {} + catch + {} try { const moduleUrl = (import.meta as any).url; if(typeof moduleUrl === 'string' && moduleUrl.length) return new URL('..', new URL('.', moduleUrl)).toString(); } - catch {} + catch + {} try { @@ -56,7 +59,8 @@ const deployBaseUrl = (): string => return trimmed ? `${ window.location.origin }/${ trimmed }/` : `${ window.location.origin }/`; } } - catch {} + catch + {} return `${ window.location.origin }/`; }; diff --git a/src/common/Button.tsx b/src/common/Button.tsx index 6b7d454..06d6bd7 100644 --- a/src/common/Button.tsx +++ b/src/common/Button.tsx @@ -44,9 +44,9 @@ export const Button: FC = props => if(variant == 'dark') newClassNames.push('text-white bg-dark [box-shadow:inset_0_2px_#ffffff26,inset_0_-2px_#0000001a,0_1px_#0000001a] hover:text-white hover:bg-[#18181bfb] hover:border-[#161619fb]'); - - if(variant == 'gray') - newClassNames.push('text-white bg-[#1e7295] border-[#1e7295] [box-shadow:inset_0_2px_#ffffff26,inset_0_-2px_#0000001a,0_1px_#0000001a] hover:text-white hover:bg-[#1a617f] hover:border-[#185b77]'); + + if(variant == 'gray') + newClassNames.push('text-white bg-[#1e7295] border-[#1e7295] [box-shadow:inset_0_2px_#ffffff26,inset_0_-2px_#0000001a,0_1px_#0000001a] hover:text-white hover:bg-[#1a617f] hover:border-[#185b77]'); } diff --git a/src/common/ButtonGroup.tsx b/src/common/ButtonGroup.tsx index 033bb1f..1962332 100644 --- a/src/common/ButtonGroup.tsx +++ b/src/common/ButtonGroup.tsx @@ -19,4 +19,4 @@ export const ButtonGroup: FC = props => }, [ classNames ]); return ; -} +}; diff --git a/src/common/Slider.tsx b/src/common/Slider.tsx index 8cd7490..9c11cc8 100644 --- a/src/common/Slider.tsx +++ b/src/common/Slider.tsx @@ -145,4 +145,4 @@ export const Slider: FC = props => ) } ); -} +}; diff --git a/src/common/Text.tsx b/src/common/Text.tsx index ffc0a85..e81cab3 100644 --- a/src/common/Text.tsx +++ b/src/common/Text.tsx @@ -20,7 +20,8 @@ export interface TextProps extends BaseProps { textBreak?: boolean; } -export const Text: FC = props => { +export const Text: FC = props => +{ const { variant = 'black', fontWeight = null, @@ -40,20 +41,22 @@ export const Text: FC = props => { ...rest } = props; - const getClassNames = useMemo(() => { + const getClassNames = useMemo(() => + { const newClassNames: string[] = [truncate ? 'block' : 'inline']; - if (variant) { - if (variant === 'primary') newClassNames.push('text-[#1e7295]'); - if (variant == 'secondary') newClassNames.push('text-[#185d79]'); - if (variant === 'black') newClassNames.push('text-[#000000]'); - if (variant == 'dark') newClassNames.push('text-[#18181b]'); - if (variant === 'gray') newClassNames.push('text-[#6b7280]'); - if (variant === 'white') newClassNames.push('text-[#ffffff]'); - if (variant == 'success') newClassNames.push('text-[#00800b]'); - if (variant == 'danger') newClassNames.push('text-[#a81a12]'); - if (variant == 'warning') newClassNames.push('text-[#ffc107]'); - } + if (variant) + { + if (variant === 'primary') newClassNames.push('text-[#1e7295]'); + if (variant == 'secondary') newClassNames.push('text-[#185d79]'); + if (variant === 'black') newClassNames.push('text-[#000000]'); + if (variant == 'dark') newClassNames.push('text-[#18181b]'); + if (variant === 'gray') newClassNames.push('text-[#6b7280]'); + if (variant === 'white') newClassNames.push('text-[#ffffff]'); + if (variant == 'success') newClassNames.push('text-[#00800b]'); + if (variant == 'danger') newClassNames.push('text-[#a81a12]'); + if (variant == 'warning') newClassNames.push('text-[#ffc107]'); + } if (bold) newClassNames.push('font-bold'); if (fontWeight) newClassNames.push('font-' + fontWeight); diff --git a/src/common/draggable-window/DraggableWindow.tsx b/src/common/draggable-window/DraggableWindow.tsx index be5e552..524fff6 100644 --- a/src/common/draggable-window/DraggableWindow.tsx +++ b/src/common/draggable-window/DraggableWindow.tsx @@ -21,7 +21,8 @@ export interface DraggableWindowProps { children?: ReactNode; } -export const DraggableWindow: FC = props => { +export const DraggableWindow: FC = props => +{ const { uniqueKey = null, handleSelector = '.drag-handler', windowPosition = DraggableWindowPosition.CENTER, disableDrag = false, dragStyle = {}, children = null, offsetLeft = 0, offsetTop = 0 } = props; const [delta, setDelta] = useState<{ x: number, y: number }>({ x: 0, y: 0 }); const [offset, setOffset] = useState<{ x: number, y: number }>({ x: 0, y: 0 }); @@ -31,49 +32,61 @@ export const DraggableWindow: FC = props => { const [dragHandler, setDragHandler] = useState(null); const elementRef = useRef(); - const bringToTop = useCallback(() => { + const bringToTop = useCallback(() => + { let zIndex = 400; - for (const existingWindow of CURRENT_WINDOWS) { + for (const existingWindow of CURRENT_WINDOWS) + { zIndex += 1; existingWindow.style.zIndex = zIndex.toString(); } }, []); - const moveCurrentWindow = useCallback(() => { + const moveCurrentWindow = useCallback(() => + { const index = CURRENT_WINDOWS.indexOf(elementRef.current); - if (index === -1) { + if (index === -1) + { CURRENT_WINDOWS.push(elementRef.current); - } else if (index === (CURRENT_WINDOWS.length - 1)) return; - else if (index >= 0) { + } + else if (index === (CURRENT_WINDOWS.length - 1)) return; + else if (index >= 0) + { CURRENT_WINDOWS.splice(index, 1); CURRENT_WINDOWS.push(elementRef.current); } bringToTop(); }, [bringToTop]); - const onMouseDown = useCallback((event: ReactMouseEvent) => { + const onMouseDown = useCallback((event: ReactMouseEvent) => + { moveCurrentWindow(); }, [moveCurrentWindow]); - const onTouchStart = useCallback((event: ReactTouchEvent) => { + const onTouchStart = useCallback((event: ReactTouchEvent) => + { moveCurrentWindow(); }, [moveCurrentWindow]); - const startDragging = useCallback((startX: number, startY: number) => { + const startDragging = useCallback((startX: number, startY: number) => + { setStart({ x: startX, y: startY }); setIsDragging(true); }, []); - const onDragMouseDown = useCallback((event: MouseEvent) => { + const onDragMouseDown = useCallback((event: MouseEvent) => + { startDragging(event.clientX, event.clientY); }, [startDragging]); - const onTouchDown = useCallback((event: TouchEvent) => { + const onTouchDown = useCallback((event: TouchEvent) => + { const touch = event.touches[0]; startDragging(touch.clientX, touch.clientY); }, [startDragging]); - const clampPosition = useCallback((newX: number, newY: number) => { + const clampPosition = useCallback((newX: number, newY: number) => + { if (!elementRef.current) return { x: newX, y: newY }; const windowWidth = elementRef.current.offsetWidth; @@ -88,7 +101,8 @@ export const DraggableWindow: FC = props => { return { x: clampedX, y: clampedY }; }, []); - const onDragMouseMove = useCallback((event: MouseEvent) => { + const onDragMouseMove = useCallback((event: MouseEvent) => + { if (!elementRef.current || !isDragging) return; const newDeltaX = event.clientX - start.x; @@ -100,7 +114,8 @@ export const DraggableWindow: FC = props => { setDelta({ x: clampedPos.x - offset.x, y: clampedPos.y - offset.y }); }, [start, offset, clampPosition, isDragging]); - const onDragTouchMove = useCallback((event: TouchEvent) => { + const onDragTouchMove = useCallback((event: TouchEvent) => + { if (!elementRef.current || !isDragging) return; const touch = event.touches[0]; @@ -113,7 +128,8 @@ export const DraggableWindow: FC = props => { setDelta({ x: clampedPos.x - offset.x, y: clampedPos.y - offset.y }); }, [start, offset, clampPosition, isDragging]); - const completeDrag = useCallback(() => { + const completeDrag = useCallback(() => + { if (!elementRef.current || !dragHandler || !isDragging) return; const finalOffsetX = offset.x + delta.x; @@ -124,29 +140,34 @@ export const DraggableWindow: FC = props => { setOffset({ x: clampedPos.x, y: clampedPos.y }); setIsDragging(false); - if (uniqueKey !== null) { - const newStorage = { ...GetLocalStorage(`nitro.windows.${uniqueKey}`) } as WindowSaveOptions; + if (uniqueKey !== null) + { + const newStorage = { ...GetLocalStorage(`nitro.windows.${uniqueKey}`) }; newStorage.offset = { x: clampedPos.x, y: clampedPos.y }; SetLocalStorage(`nitro.windows.${uniqueKey}`, newStorage); } }, [dragHandler, delta, offset, uniqueKey, clampPosition, isDragging]); - const onDragMouseUp = useCallback((event: MouseEvent) => { + const onDragMouseUp = useCallback((event: MouseEvent) => + { completeDrag(); }, [completeDrag]); - const onDragTouchUp = useCallback((event: TouchEvent) => { + const onDragTouchUp = useCallback((event: TouchEvent) => + { completeDrag(); }, [completeDrag]); - useLayoutEffect(() => { + useLayoutEffect(() => + { const element = elementRef.current as HTMLElement; if (!element) return; CURRENT_WINDOWS.push(element); bringToTop(); - if (!disableDrag) { + if (!disableDrag) + { const handle = element.querySelector(handleSelector); if (handle) setDragHandler(handle as HTMLElement); } @@ -156,7 +177,8 @@ export const DraggableWindow: FC = props => { let offsetX = 0; let offsetY = 0; - switch (windowPosition) { + switch (windowPosition) + { case DraggableWindowPosition.TOP_CENTER: offsetY = 50 + offsetTop; offsetX = (window.innerWidth - windowWidth) / 2 + offsetLeft; @@ -176,25 +198,29 @@ export const DraggableWindow: FC = props => { setDelta({ x: 0, y: 0 }); setIsPositioned(true); - return () => { + return () => + { const index = CURRENT_WINDOWS.indexOf(element); if (index >= 0) CURRENT_WINDOWS.splice(index, 1); }; }, [handleSelector, windowPosition, uniqueKey, disableDrag, offsetLeft, offsetTop, bringToTop]); - useEffect(() => { + useEffect(() => + { if (!dragHandler) return; dragHandler.addEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown); dragHandler.addEventListener(TouchEventType.TOUCH_START, onTouchDown); - return () => { + return () => + { dragHandler.removeEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown); dragHandler.removeEventListener(TouchEventType.TOUCH_START, onTouchDown); }; }, [dragHandler, onDragMouseDown, onTouchDown]); - useEffect(() => { + useEffect(() => + { if (!isDragging) return; document.addEventListener(MouseEventType.MOUSE_UP, onDragMouseUp); @@ -202,7 +228,8 @@ export const DraggableWindow: FC = props => { document.addEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove); document.addEventListener(TouchEventType.TOUCH_MOVE, onDragTouchMove); - return () => { + return () => + { document.removeEventListener(MouseEventType.MOUSE_UP, onDragMouseUp); document.removeEventListener(TouchEventType.TOUCH_END, onDragTouchUp); document.removeEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove); @@ -210,7 +237,8 @@ export const DraggableWindow: FC = props => { }; }, [isDragging, onDragMouseUp, onDragMouseMove, onDragTouchUp, onDragTouchMove]); - useEffect(() => { + useEffect(() => + { if (!uniqueKey) return; const localStorage = GetLocalStorage(`nitro.windows.${uniqueKey}`); diff --git a/src/common/index.ts b/src/common/index.ts index 6802959..a4b4aa1 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -19,5 +19,5 @@ export * from './draggable-window'; export * from './layout'; export * from './layout/limited-edition'; export * from './types'; -export * from "./Slider"; +export * from './Slider'; export * from './utils'; diff --git a/src/common/layout/LayoutFurniImageView.tsx b/src/common/layout/LayoutFurniImageView.tsx index f7fe9dc..8e456b9 100644 --- a/src/common/layout/LayoutFurniImageView.tsx +++ b/src/common/layout/LayoutFurniImageView.tsx @@ -22,7 +22,10 @@ export const LayoutFurniImageView: FC = props => { isMounted.current = true; - return () => { isMounted.current = false; }; + return () => + { + isMounted.current = false; + }; }, []); const updateImage = useCallback(async (texture: any) => diff --git a/src/common/layout/LayoutMiniCameraView.tsx b/src/common/layout/LayoutMiniCameraView.tsx index 4d1c2dc..5845332 100644 --- a/src/common/layout/LayoutMiniCameraView.tsx +++ b/src/common/layout/LayoutMiniCameraView.tsx @@ -9,11 +9,13 @@ interface LayoutMiniCameraViewProps { onClose: () => void; } -export const LayoutMiniCameraView: FC = props => { +export const LayoutMiniCameraView: FC = props => +{ const { roomId = -1, textureReceiver = null, onClose = null } = props; const elementRef = useRef(); - const getCameraBounds = () => { + const getCameraBounds = () => + { if (!elementRef || !elementRef.current) return null; const frameBounds = elementRef.current.getBoundingClientRect(); @@ -26,7 +28,8 @@ export const LayoutMiniCameraView: FC = props => { ); }; - const takePicture = () => { + const takePicture = () => + { PlaySound(SoundNames.CAMERA_SHUTTER); textureReceiver(GetRoomEngine().createTextureFromRoom(roomId, 1, getCameraBounds())); }; diff --git a/src/common/layout/LayoutRoomObjectImageView.tsx b/src/common/layout/LayoutRoomObjectImageView.tsx index aa9301c..ab07dc4 100644 --- a/src/common/layout/LayoutRoomObjectImageView.tsx +++ b/src/common/layout/LayoutRoomObjectImageView.tsx @@ -21,7 +21,10 @@ export const LayoutRoomObjectImageView: FC = pro { isMounted.current = true; - return () => { isMounted.current = false; }; + return () => + { + isMounted.current = false; + }; }, []); const getStyle = useMemo(() => diff --git a/src/components/MainView.tsx b/src/components/MainView.tsx index 7861454..cc5baf4 100644 --- a/src/components/MainView.tsx +++ b/src/components/MainView.tsx @@ -127,7 +127,7 @@ export const MainView: FC<{}> = props => - + diff --git a/src/components/ads/GoogleAdsView.tsx b/src/components/ads/GoogleAdsView.tsx index 0aaf159..4da4373 100644 --- a/src/components/ads/GoogleAdsView.tsx +++ b/src/components/ads/GoogleAdsView.tsx @@ -9,8 +9,10 @@ interface AdsenseConfig { fullWidthResponsive?: boolean; } -const parsePublisherIdFromAdsTxt = (text: string): string | null => { - for (const rawLine of text.split(/\r?\n/)) { +const parsePublisherIdFromAdsTxt = (text: string): string | null => +{ + for (const rawLine of text.split(/\r?\n/)) + { const line = rawLine.split('#')[0].trim(); if (!line) continue; const parts = line.split(',').map(part => part.trim()); @@ -22,7 +24,8 @@ const parsePublisherIdFromAdsTxt = (text: string): string | null => { return null; }; -export const GoogleAdsView: FC<{}> = () => { +export const GoogleAdsView: FC<{}> = () => +{ const adsEnabled = GetConfigurationValue('show.google.ads', false); const [ isOpen, setIsOpen ] = useState(false); const [ publisherId, setPublisherId ] = useState(null); @@ -32,7 +35,8 @@ export const GoogleAdsView: FC<{}> = () => { const pushedRef = useRef(false); const autoOpenedRef = useRef(false); - useEffect(() => { + useEffect(() => + { if (!adsEnabled) return; const handler = () => setIsOpen(prev => !prev); window.addEventListener('ads:toggle', handler); @@ -42,7 +46,8 @@ export const GoogleAdsView: FC<{}> = () => { // Auto-open once on initial mount (the login / landing stage). // Subsequent toggles are driven by the "ads:toggle" window event // (e.g. the Show Ad button in NitroSystemAlertView). - useEffect(() => { + useEffect(() => + { if (!adsEnabled) return; if (autoOpenedRef.current) return; autoOpenedRef.current = true; @@ -50,11 +55,14 @@ export const GoogleAdsView: FC<{}> = () => { return () => clearTimeout(t); }, [ adsEnabled ]); - useEffect(() => { + useEffect(() => + { let cancelled = false; - (async () => { - try { + (async () => + { + try + { const [ adsTxtRes, configRes ] = await Promise.all([ fetch('/ads.txt', { cache: 'no-cache' }), fetch(configFileUrl('adsense.json', true), { cache: 'no-cache' }) @@ -73,39 +81,54 @@ export const GoogleAdsView: FC<{}> = () => { if (cancelled) return; setPublisherId(pubId); setConfig(cfg); - } catch (err) { + } + catch (err) + { if (!cancelled) setLoadError((err as Error).message); } })(); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, []); - useEffect(() => { - if (!isOpen) { + useEffect(() => + { + if (!isOpen) + { pushedRef.current = false; return; } if (!insRef.current || pushedRef.current) return; if (!publisherId || !config?.slot) return; - const tryPush = () => { - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + const tryPush = () => + { + try + { + const w = window as any; w.adsbygoogle = w.adsbygoogle || []; w.adsbygoogle.push({}); pushedRef.current = true; - } catch { + } + catch + { // AdSense script may not be ready yet; retry once - setTimeout(() => { - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + setTimeout(() => + { + try + { + const w = window as any; w.adsbygoogle = w.adsbygoogle || []; w.adsbygoogle.push({}); pushedRef.current = true; - } catch { /* give up */ } + } + catch + { /* give up */ } }, 500); } }; diff --git a/src/components/avatar-editor/palette-set/AvatarEditorAdvancedColorView.tsx b/src/components/avatar-editor/palette-set/AvatarEditorAdvancedColorView.tsx index ce31a23..38890fe 100644 --- a/src/components/avatar-editor/palette-set/AvatarEditorAdvancedColorView.tsx +++ b/src/components/avatar-editor/palette-set/AvatarEditorAdvancedColorView.tsx @@ -23,7 +23,10 @@ const findNearestColor = (hex: string, colors: IPartColor[]): IPartColor | null const cb = color.rgb & 0xFF; const dist = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2; - if(dist < minDist) { minDist = dist; nearest = color; } + if(dist < minDist) + { + minDist = dist; nearest = color; + } } return nearest; @@ -40,7 +43,10 @@ export const AvatarEditorAdvancedColorView: FC<{ useEffect(() => { - return () => { if(debounceRef.current) clearTimeout(debounceRef.current); }; + return () => + { + if(debounceRef.current) clearTimeout(debounceRef.current); + }; }, []); const selectedColor = useMemo(() => @@ -52,7 +58,7 @@ export const AvatarEditorAdvancedColorView: FC<{ const hexColor = useMemo(() => ColorUtils.makeColorNumberHex((selectedColor?.rgb ?? 0) & 0xFFFFFF), - [ selectedColor ]); + [ selectedColor ]); const handleChange = useCallback((e: React.ChangeEvent) => { diff --git a/src/components/avatar-effects/AvatarEffectsView.tsx b/src/components/avatar-effects/AvatarEffectsView.tsx index 14d4b89..cc98168 100644 --- a/src/components/avatar-effects/AvatarEffectsView.tsx +++ b/src/components/avatar-effects/AvatarEffectsView.tsx @@ -36,8 +36,8 @@ export const AvatarEffectsView: FC<{}> = () => switch(parts[1]) { - case 'show': setIsVisible(true); return; - case 'hide': setIsVisible(false); return; + case 'show': setIsVisible(true); return; + case 'hide': setIsVisible(false); return; case 'toggle': setIsVisible(prev => !prev); return; } }, @@ -83,7 +83,10 @@ export const AvatarEffectsView: FC<{}> = () => } })(); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, [ isVisible, effects.length, loadError ]); const session = GetSessionDataManager(); diff --git a/src/components/backgrounds/BackgroundsView.tsx b/src/components/backgrounds/BackgroundsView.tsx index 9c52d7d..2aa2196 100644 --- a/src/components/backgrounds/BackgroundsView.tsx +++ b/src/components/backgrounds/BackgroundsView.tsx @@ -49,18 +49,21 @@ export const BackgroundsView: FC = ({ setSelectedOverlay, selectedCardBackground, setSelectedCardBackground -}) => { +}) => +{ const [activeTab, setActiveTab] = useState('backgrounds'); const remoteData = use(fetchBackgroundsData()); const { roomSession } = useRoom(); - const processData = useCallback((configData: any[], idField: string): ItemData[] => { + const processData = useCallback((configData: any[], idField: string): ItemData[] => + { if (!configData?.length) return []; return configData.map(item => ({ id: typeof item === 'number' ? item : item[idField] })); }, []); - const readData = useCallback((key: 'backgrounds.data' | 'stands.data' | 'overlays.data' | 'cards.data'): any[] => { + const readData = useCallback((key: 'backgrounds.data' | 'stands.data' | 'overlays.data' | 'cards.data'): any[] => + { const fromRemote = remoteData?.[key]; if(Array.isArray(fromRemote)) return fromRemote; return GetOptionalConfigurationValue(key, []) || []; @@ -73,7 +76,8 @@ export const BackgroundsView: FC = ({ cards: processData(readData('cards.data').length ? readData('cards.data') : readData('backgrounds.data'), 'backgroundId') }), [processData, readData]); - const handleSelection = useCallback((id: number) => { + const handleSelection = useCallback((id: number) => + { if (!roomSession) return; const setters = { backgrounds: setSelectedBackground, stands: setSelectedStand, overlays: setSelectedOverlay, cards: setSelectedCardBackground }; diff --git a/src/components/badge-creator/BadgeCreatorView.tsx b/src/components/badge-creator/BadgeCreatorView.tsx index e8d9db1..973330a 100644 --- a/src/components/badge-creator/BadgeCreatorView.tsx +++ b/src/components/badge-creator/BadgeCreatorView.tsx @@ -12,7 +12,8 @@ const t = (key: string, fallback: string, params?: string[], replacements?: stri const value = LocalizeText(key, params ?? null, replacements ?? null); if(value && value !== key) return value; } - catch {} + catch + {} if(!params || !replacements) return fallback; let out = fallback; @@ -38,8 +39,8 @@ const PALETTE: number[] = [ const currencyName = (type: number): string => { if(type === -1) return 'credits'; - if(type === 0) return 'duckets'; - if(type === 5) return 'diamonds'; + if(type === 0) return 'duckets'; + if(type === 5) return 'diamonds'; return `currency #${ type }`; }; @@ -58,14 +59,14 @@ const floodFill = (grid: Uint32Array, w: number, h: number, startX: number, star const stack: number[] = [ startIdx ]; while(stack.length) { - const idx = stack.pop() as number; + const idx = stack.pop(); if(next[idx] !== target) continue; next[idx] = replacement; const x = idx % w; const y = (idx - x) / w; - if(x > 0) stack.push(idx - 1); + if(x > 0) stack.push(idx - 1); if(x < w - 1) stack.push(idx + 1); - if(y > 0) stack.push(idx - w); + if(y > 0) stack.push(idx - w); if(y < h - 1) stack.push(idx + w); } return next; @@ -119,7 +120,7 @@ const gridToPngBase64 = async (grid: Uint32Array): Promise<{ b64: string; bytes: { const argb = grid[i]; const o = i * 4; - image.data[o] = (argb >>> 16) & 0xff; + image.data[o] = (argb >>> 16) & 0xff; image.data[o + 1] = (argb >>> 8) & 0xff; image.data[o + 2] = argb & 0xff; image.data[o + 3] = (argb >>> 24) & 0xff; @@ -157,12 +158,18 @@ const loadGridFromUrl = (url: string): Promise => { const o = i * 4; const a = data[o + 3]; - if(a === 0) { grid[i] = 0; continue; } + if(a === 0) + { + grid[i] = 0; continue; + } grid[i] = ((a & 0xff) << 24) | ((data[o] & 0xff) << 16) | ((data[o + 1] & 0xff) << 8) | (data[o + 2] & 0xff); } resolve(grid); } - catch(err) { reject(err); } + catch(err) + { + reject(err); + } }; image.onerror = () => reject(new Error('Could not load badge image (CORS?).')); image.src = url + (url.includes('?') ? '&' : '?') + 't=' + Date.now(); @@ -216,8 +223,8 @@ export const BadgeCreatorView: FC<{}> = () => if(parts.length < 2) return; switch(parts[1]) { - case 'show': setIsVisible(true); return; - case 'hide': setIsVisible(false); return; + case 'show': setIsVisible(true); return; + case 'hide': setIsVisible(false); return; case 'toggle': setIsVisible(v => !v); return; case 'edit': if(!parts[2]) return; @@ -232,7 +239,13 @@ export const BadgeCreatorView: FC<{}> = () => return () => RemoveLinkEventTracker(tracker); }, []); - useEffect(() => { if(isVisible) { refresh(); ensureCustomBadgeTexts(); } }, [ isVisible, refresh ]); + useEffect(() => + { + if(isVisible) + { + refresh(); ensureCustomBadgeTexts(); + } + }, [ isVisible, refresh ]); const resetEditor = useCallback(() => { @@ -316,9 +329,9 @@ export const BadgeCreatorView: FC<{}> = () => { const v = grid[i]; const o = i * 4; - buffer[o] = (v >>> 16) & 0xff; - buffer[o + 1] = (v >>> 8) & 0xff; - buffer[o + 2] = v & 0xff; + buffer[o] = (v >>> 16) & 0xff; + buffer[o + 1] = (v >>> 8) & 0xff; + buffer[o + 2] = v & 0xff; buffer[o + 3] = (v >>> 24) & 0xff; } ctx.putImageData(image, 0, 0); @@ -365,7 +378,10 @@ export const BadgeCreatorView: FC<{}> = () => useEffect(() => { - const stopDrag = () => { isDraggingRef.current = false; }; + const stopDrag = () => + { + isDraggingRef.current = false; + }; window.addEventListener('mouseup', stopDrag); return () => window.removeEventListener('mouseup', stopDrag); }, []); @@ -385,7 +401,10 @@ export const BadgeCreatorView: FC<{}> = () => const handleSave = useCallback(async () => { if(submitting) return; - if(isEmpty) { setError(t('badgecreator.error.empty', 'Draw something first.')); return; } + if(isEmpty) + { + setError(t('badgecreator.error.empty', 'Draw something first.')); return; + } if(!editingBadgeId && !canCreateMore) { setError(t('badgecreator.error.limit', 'You already have %max% custom badges.', [ 'max' ], [ String(maxBadges) ])); @@ -506,7 +525,10 @@ export const BadgeCreatorView: FC<{}> = () => } - { !isLocked && (thumbnailUrl && thumbnailUrl.length > 0) && + { !isLocked && (thumbnailUrl && thumbnailUrl.length > 0) &&
} - { isLocked && + { isLocked &&
{ effect.minLevel }
} - + ); }; diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx index 5f9b965..6c2cd9e 100644 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx +++ b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx @@ -25,8 +25,8 @@ export const CameraWidgetEffectListView: FC = p const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1); // return myLevel) } removeEffect={ () => processAction('remove_effect', effect.name) } selectEffect={ () => processAction('select_effect', effect.name) } thumbnailUrl={ ((thumbnailUrl && thumbnailUrl.thumbnailUrl) || null) } />; - - 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/catalog/CatalogAdminContext.tsx b/src/components/catalog/CatalogAdminContext.tsx index 2e941f1..2d27597 100644 --- a/src/components/catalog/CatalogAdminContext.tsx +++ b/src/components/catalog/CatalogAdminContext.tsx @@ -97,7 +97,10 @@ export const CatalogAdminProvider: FC<{ children: ReactNode }> = ({ children }) { if(e.key === 'Escape') { - if(editingOffer) { setEditingOffer(null); e.preventDefault(); return; } + if(editingOffer) + { + setEditingOffer(null); e.preventDefault(); return; + } if(editingPageData || editingRootPage || editingPageNode) { setEditingPageData(false); diff --git a/src/components/catalog/CatalogClassicView.tsx b/src/components/catalog/CatalogClassicView.tsx index 2daeb3d..2a49735 100644 --- a/src/components/catalog/CatalogClassicView.tsx +++ b/src/components/catalog/CatalogClassicView.tsx @@ -19,9 +19,11 @@ const CatalogClassicViewInner: FC<{}> = () => const { isVisible = false, setIsVisible = null, rootNode = null, currentPage = null, navigationHidden = false, setNavigationHidden = null, activeNodes = [], searchResult = null, setSearchResult = null, openPageByName = null, openPageByOfferId = null, activateNode = null, openCatalogByType = null, toggleCatalogByType = null, currentType = CatalogType.NORMAL } = useCatalog(); const catalogAdmin = useCatalogAdmin(); const adminMode = catalogAdmin?.adminMode ?? false; - const setAdminMode = catalogAdmin?.setAdminMode ?? (() => {}); + const setAdminMode = catalogAdmin?.setAdminMode ?? (() => + {}); const hasPendingChanges = catalogAdmin?.hasPendingChanges ?? false; - const publishCatalog = catalogAdmin?.publishCatalog ?? (() => {}); + const publishCatalog = catalogAdmin?.publishCatalog ?? (() => + {}); const loading = catalogAdmin?.loading ?? false; const isMod = GetSessionDataManager().isModerator; @@ -148,13 +150,19 @@ const CatalogClassicViewInner: FC<{}> = () => { adminMode &&
e.stopPropagation() }> { catalogAdmin.setEditingPageNode(child); catalogAdmin.setEditingRootPage(false); catalogAdmin.setEditingPageData(true); } } /> + onClick={ () => + { + catalogAdmin.setEditingPageNode(child); catalogAdmin.setEditingRootPage(false); catalogAdmin.setEditingPageData(true); + } } /> catalogAdmin.togglePageVisible(child.pageId) }> { isHidden ? : } { if(confirm(LocalizeText('catalog.admin.delete.category.confirm', [ 'name' ], [ child.localization ]))) catalogAdmin.deletePage(child.pageId); } } /> + onClick={ () => + { + if(confirm(LocalizeText('catalog.admin.delete.category.confirm', [ 'name' ], [ child.localization ]))) catalogAdmin.deletePage(child.pageId); + } } />
} @@ -180,7 +188,10 @@ const CatalogClassicViewInner: FC<{}> = () => @@ -328,7 +340,10 @@ export const CatalogLayoutCustomPrefixView: FC = props => zIndex: isSelected ? 10 : 1, boxShadow: isSelected ? '0 0 8px rgba(59,130,246,0.3)' : 'none' } } - onClick={ () => { setSelectedLetterIndex(i); setCustomColorInput(charColor); } }> + onClick={ () => + { + setSelectedLetterIndex(i); setCustomColorInput(charColor); + } }> { char } diff --git a/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx index e797289..e9417ab 100644 --- a/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx +++ b/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx @@ -28,7 +28,10 @@ export const CatalogLayoutDefaultView: FC = props =>
diff --git a/src/components/catalog/views/page/layout/CatalogLayoutTrophiesView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutTrophiesView.tsx index e576695..1e1c174 100644 --- a/src/components/catalog/views/page/layout/CatalogLayoutTrophiesView.tsx +++ b/src/components/catalog/views/page/layout/CatalogLayoutTrophiesView.tsx @@ -42,7 +42,10 @@ export const CatalogLayoutTrophiesView: FC = props =>
diff --git a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx b/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx index 4897797..08a9356 100644 --- a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx +++ b/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx @@ -202,7 +202,10 @@ export const CatalogLayoutPetView: FC = props =>
diff --git a/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx index 9e0beb0..b329fa7 100644 --- a/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx @@ -89,7 +89,10 @@ export const CatalogPurchaseWidgetView: FC = pro isPurchasingCatalogItem = true; setPurchaseState(CatalogPurchaseState.PURCHASE); - setTimeout(() => { isPurchasingCatalogItem = false; }, 10000); + setTimeout(() => + { + isPurchasingCatalogItem = false; + }, 10000); if(purchaseCallback) { diff --git a/src/components/chat-history/ChatHistoryView.tsx b/src/components/chat-history/ChatHistoryView.tsx index 8e6c819..c86bbf8 100644 --- a/src/components/chat-history/ChatHistoryView.tsx +++ b/src/components/chat-history/ChatHistoryView.tsx @@ -5,54 +5,64 @@ import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } import { useChatHistory, useOnClickChat } from '../../hooks'; import { NitroInput } from '../../layout'; -export const ChatHistoryView: FC<{}> = props => { +export const ChatHistoryView: FC<{}> = props => +{ const [isVisible, setIsVisible] = useState(false); const [searchText, setSearchText] = useState(''); - const {chatHistory = []} = useChatHistory(); + const { chatHistory = [] } = useChatHistory(); const { onClickChat } = useOnClickChat(); const elementRef = useRef(null); const isFirstRender = useRef(true); const prevChatLength = useRef(0); - const filteredChatHistory = useMemo(() => { + const filteredChatHistory = useMemo(() => + { let result = chatHistory; - - if (searchText.length > 0) { + + if (searchText.length > 0) + { const text = searchText.toLowerCase(); - result = chatHistory.filter(entry => - (entry.message && entry.message.toLowerCase().includes(text)) || + result = chatHistory.filter(entry => + (entry.message && entry.message.toLowerCase().includes(text)) || (entry.name && entry.name.toLowerCase().includes(text)) ); } - + return [...result]; }, [chatHistory, searchText]); - useEffect(() => { + useEffect(() => + { if (!elementRef.current || !isVisible) return; const element = elementRef.current; const maxScrollTop = Math.max(0, element.scrollHeight - element.clientHeight); const isAtBottom = maxScrollTop === 0 || Math.abs(element.scrollTop - maxScrollTop) <= 50; - if (isFirstRender.current) { + if (isFirstRender.current) + { element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' }); isFirstRender.current = false; - } else if (filteredChatHistory.length > prevChatLength.current) { + } + else if (filteredChatHistory.length > prevChatLength.current) + { element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' }); } prevChatLength.current = filteredChatHistory.length; }, [filteredChatHistory, isVisible]); - useEffect(() => { + useEffect(() => + { const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => { + linkReceived: (url: string) => + { const parts = url.split('/'); if (parts.length < 2) return; - switch (parts[1]) { + switch (parts[1]) + { case 'show': setIsVisible(true); return; @@ -84,18 +94,18 @@ export const ChatHistoryView: FC<{}> = props => { {row.timestamp} {row.type === ChatEntryType.TYPE_CHAT && ( -
-
+
{row.imageUrl && row.imageUrl.length > 0 && ( -
+
)}
- - + +
diff --git a/src/components/customize/CustomizeNickIconView.tsx b/src/components/customize/CustomizeNickIconView.tsx index d91f0fa..4aae464 100644 --- a/src/components/customize/CustomizeNickIconView.tsx +++ b/src/components/customize/CustomizeNickIconView.tsx @@ -367,38 +367,38 @@ export const CustomizeNickIconView: FC<{}> = () => { activePrefixSubTab === 'library' && <> -
+
Choose a preset or custom prefix for your bubble identity. -
-
- { combinedPrefixes.map(item => ( -
- { item.active && Active } - -
- { item.owned ? (item.active ? 'Owned - Active' : 'Owned') : 'Locked' } - { item.displayName || item.text }{ item.isCustom ? ' - Custom' : '' } - - - { item.points } - -
-
- )) } -
+
+ { combinedPrefixes.map(item => ( +
+ { item.active && Active } + +
+ { item.owned ? (item.active ? 'Owned - Active' : 'Owned') : 'Locked' } + { item.displayName || item.text }{ item.isCustom ? ' - Custom' : '' } + + + { item.points } + +
+ +
+ )) } +
} { activePrefixSubTab === 'custom' && @@ -430,14 +430,14 @@ export const CustomizeNickIconView: FC<{}> = () =>
{ PRESET_COLORS.map(color => ( - + )) }
@@ -572,7 +572,10 @@ export const CustomizeNickIconView: FC<{}> = () => { setCustomPrefixIcon(emoji.native); setShowEmojiPicker(false); } } + onEmojiSelect={ (emoji: { native: string }) => + { + setCustomPrefixIcon(emoji.native); setShowEmojiPicker(false); + } } previewPosition="none" set="native" theme="dark" /> diff --git a/src/components/floorplan-editor/views/FloorplanImportExportView.tsx b/src/components/floorplan-editor/views/FloorplanImportExportView.tsx index 1003e01..4856e64 100644 --- a/src/components/floorplan-editor/views/FloorplanImportExportView.tsx +++ b/src/components/floorplan-editor/views/FloorplanImportExportView.tsx @@ -28,7 +28,7 @@ export const FloorplanImportExportView: FC = pro convertNumbersForSaving(originalFloorplanSettings.thicknessFloor), originalFloorplanSettings.wallHeight - 1 )); - } + }; useEffect(() => { @@ -52,4 +52,4 @@ export const FloorplanImportExportView: FC = pro ); -} +}; diff --git a/src/components/friends/FriendsView.tsx b/src/components/friends/FriendsView.tsx index 031fa82..df3b8bd 100644 --- a/src/components/friends/FriendsView.tsx +++ b/src/components/friends/FriendsView.tsx @@ -7,7 +7,8 @@ import { FriendsMessengerView } from './views/messenger/FriendsMessengerView'; const FRIEND_BAR_TARGET_IDS = [ 'toolbar-friend-bar-container-desktop' ]; -export const FriendsView: FC<{}> = props => { +export const FriendsView: FC<{}> = props => +{ const { settings = null, onlineFriends = [], requests = [] } = useFriends(); const [ portalTarget, setPortalTarget ] = useState(null); diff --git a/src/components/friends/views/friends-bar/FriendBarItemView.tsx b/src/components/friends/views/friends-bar/FriendBarItemView.tsx index 61a6d42..9468103 100644 --- a/src/components/friends/views/friends-bar/FriendBarItemView.tsx +++ b/src/components/friends/views/friends-bar/FriendBarItemView.tsx @@ -5,17 +5,21 @@ import { LayoutAvatarImageView, LayoutBadgeImageView } from '../../../../common' import { useFriends } from '../../../../hooks'; import { motion, AnimatePresence } from 'framer-motion'; -export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => { +export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => +{ const { friend = null } = props; const [isVisible, setVisible] = useState(false); const { followFriend = null } = useFriends(); const elementRef = useRef(null); - useEffect(() => { - const onClick = (event: MouseEvent) => { + useEffect(() => + { + const onClick = (event: MouseEvent) => + { const element = elementRef.current; if (!element) return; - if ((event.target !== element) && !element.contains((event.target as Node))) { + if ((event.target !== element) && !element.contains((event.target as Node))) + { setVisible(false); } }; @@ -23,7 +27,8 @@ export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => { return () => document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick); }, []); - if (!friend) { + if (!friend) + { return (
= props => {
{LocalizeText('friend.bar.find.title')}
- + {isVisible && ( -
{LocalizeText('friend.bar.find.title')}
{LocalizeText('friend.bar.find.text')}
- @@ -88,19 +96,28 @@ export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => { {isVisible && ( -
{friend.name}
-
{ event.stopPropagation(); OpenMessengerChat(friend.id); setVisible(false); }} /> +
+ { + event.stopPropagation(); OpenMessengerChat(friend.id); setVisible(false); + }} /> {friend.online && -
{ event.stopPropagation(); followFriend(friend); setVisible(false); }} />} -
{ event.stopPropagation(); GetUserProfile(friend.id); setVisible(false); }} /> +
+ { + event.stopPropagation(); followFriend(friend); setVisible(false); + }} />} +
+ { + event.stopPropagation(); GetUserProfile(friend.id); setVisible(false); + }} />
)} diff --git a/src/components/friends/views/friends-bar/FriendsBarView.tsx b/src/components/friends/views/friends-bar/FriendsBarView.tsx index 31125b1..7f56628 100644 --- a/src/components/friends/views/friends-bar/FriendsBarView.tsx +++ b/src/components/friends/views/friends-bar/FriendsBarView.tsx @@ -19,7 +19,8 @@ const itemVariants = { exit: { opacity: 0, y: 6, scale: 0.85, transition: { duration: 0.1 } }, }; -export const FriendBarView: FC<{ onlineFriends: MessengerFriend[]; requestsCount?: number }> = props => { +export const FriendBarView: FC<{ onlineFriends: MessengerFriend[]; requestsCount?: number }> = props => +{ const { onlineFriends = [], requestsCount = 0 } = props; const [ indexOffset, setIndexOffset ] = useState(0); const elementRef = useRef(null); @@ -27,8 +28,8 @@ export const FriendBarView: FC<{ onlineFriends: MessengerFriend[]; requestsCount const visibleFriends = onlineFriends.slice(indexOffset, (indexOffset + MAX_DISPLAY_COUNT)); return ( - } -
{ if(indexOffset > 0) setIndexOffset(indexOffset - 1); } } + onClick={ () => + { + if(indexOffset > 0) setIndexOffset(indexOffset - 1); + } } >
@@ -89,9 +93,12 @@ export const FriendBarView: FC<{ onlineFriends: MessengerFriend[]; requestsCount -
MAX_DISPLAY_COUNT) && ((indexOffset + MAX_DISPLAY_COUNT) <= (onlineFriends.length - 1)))) ? 'opacity-30 cursor-not-allowed' : 'cursor-pointer hover:text-white active:scale-95' }` } - onClick={ () => { if((onlineFriends.length > MAX_DISPLAY_COUNT) && ((indexOffset + MAX_DISPLAY_COUNT) <= (onlineFriends.length - 1))) setIndexOffset(indexOffset + 1); } } + onClick={ () => + { + if((onlineFriends.length > MAX_DISPLAY_COUNT) && ((indexOffset + MAX_DISPLAY_COUNT) <= (onlineFriends.length - 1))) setIndexOffset(indexOffset + 1); + } } >
diff --git a/src/components/friends/views/friends-list/FriendsListView.tsx b/src/components/friends/views/friends-list/FriendsListView.tsx index b9ad497..957aaf2 100644 --- a/src/components/friends/views/friends-list/FriendsListView.tsx +++ b/src/components/friends/views/friends-list/FriendsListView.tsx @@ -148,7 +148,10 @@ export const FriendsListView: FC<{}> = props => - { event.stopPropagation(); toggleSelectFriends(onlineFriends.map(friend => friend.id)); } }> + + { + event.stopPropagation(); toggleSelectFriends(onlineFriends.map(friend => friend.id)); + } }> { onlineFriends.length && onlineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) ? LocalizeText('friendlist.unselect_all') : LocalizeText('friendlist.select_all') } @@ -158,7 +161,10 @@ export const FriendsListView: FC<{}> = props => - { event.stopPropagation(); toggleSelectFriends(offlineFriends.map(friend => friend.id)); } }> + + { + event.stopPropagation(); toggleSelectFriends(offlineFriends.map(friend => friend.id)); + } }> { offlineFriends.length && offlineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) ? LocalizeText('friendlist.unselect_all') : LocalizeText('friendlist.select_all') } diff --git a/src/components/furni-editor/FurniEditorView.tsx b/src/components/furni-editor/FurniEditorView.tsx index 428035a..2903d95 100644 --- a/src/components/furni-editor/FurniEditorView.tsx +++ b/src/components/furni-editor/FurniEditorView.tsx @@ -93,9 +93,9 @@ export const FurniEditorView: FC<{}> = () => loadBySpriteId(spriteId); }; - window.addEventListener('furni-editor:open', handler as EventListener); + window.addEventListener('furni-editor:open', handler); - return () => window.removeEventListener('furni-editor:open', handler as EventListener); + return () => window.removeEventListener('furni-editor:open', handler); }, [ isMod, loadBySpriteId ]); const handleSelect = useCallback((id: number) => diff --git a/src/components/groups/views/forums/GroupForumListView.tsx b/src/components/groups/views/forums/GroupForumListView.tsx index 9ac2c5e..5ca54c1 100644 --- a/src/components/groups/views/forums/GroupForumListView.tsx +++ b/src/components/groups/views/forums/GroupForumListView.tsx @@ -58,7 +58,10 @@ export const GroupForumListView: FC = props => @@ -89,7 +92,10 @@ export const GroupForumListView: FC = props => { (forum.lastMessageAuthorId > 0) && <> { LocalizeText('messageboard.last.message') } - { e.stopPropagation(); GetUserProfile(forum.lastMessageAuthorId); } }> + + { + e.stopPropagation(); GetUserProfile(forum.lastMessageAuthorId); + } }> { forum.lastMessageAuthorName } { formatTimeAgo(forum.lastMessageTimeAsSecondsAgo) } diff --git a/src/components/groups/views/forums/GroupForumThreadListView.tsx b/src/components/groups/views/forums/GroupForumThreadListView.tsx index 99eda9e..bc2aa25 100644 --- a/src/components/groups/views/forums/GroupForumThreadListView.tsx +++ b/src/components/groups/views/forums/GroupForumThreadListView.tsx @@ -165,7 +165,10 @@ export const GroupForumThreadListView: FC = props { LocalizeText('messageboard.started.by') } - { e.stopPropagation(); GetUserProfile(thread.authorId); } }> + + { + e.stopPropagation(); GetUserProfile(thread.authorId); + } }> { thread.authorName } - { formatTimeAgo(thread.creationTimeAsSecondsAgo) } @@ -182,7 +185,10 @@ export const GroupForumThreadListView: FC = props } { LocalizeText('messageboard.last.message') } - { e.stopPropagation(); GetUserProfile(thread.lastUserId); } }> + + { + e.stopPropagation(); GetUserProfile(thread.lastUserId); + } }> { thread.lastUserName } { formatTimeAgo(thread.lastCommentTime) } diff --git a/src/components/hotel-view/HotelView.tsx b/src/components/hotel-view/HotelView.tsx index e0a2605..78c1a3c 100644 --- a/src/components/hotel-view/HotelView.tsx +++ b/src/components/hotel-view/HotelView.tsx @@ -37,8 +37,8 @@ function getHourInTimezone(timezone: string): number */ function getTimeOfDay(hour: number): string { - if(hour > 5 && hour <= 9) return 'morning'; - if(hour > 9 && hour <= 16) return 'day'; + if(hour > 5 && hour <= 9) return 'morning'; + if(hour > 9 && hour <= 16) return 'day'; if(hour > 16 && hour <= 19) return 'sunset'; if(hour > 19 && hour <= 23) return 'evening'; @@ -64,8 +64,8 @@ export const HotelView: FC<{}> = props => return getTimeOfDay(hour); }, [ timezone ]); - - /** + + /** const timeOfDay = 'sunset'; For debuging the diff views */ @@ -73,9 +73,9 @@ export const HotelView: FC<{}> = props => const skyColor = SKY_COLORS[timeOfDay] ?? configBgColor ?? '#000'; const containerRef = useRef(null); - const isDragging = useRef(false); - const lastMouseX = useRef(0); - const lastMouseY = useRef(0); + const isDragging = useRef(false); + const lastMouseX = useRef(0); + const lastMouseY = useRef(0); useEffect(() => { @@ -85,7 +85,7 @@ export const HotelView: FC<{}> = props => const centerView = () => { - const viewportWidth = window.innerWidth; + const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight - 55; const lobbyEl = container.querySelector('.nitro-hotel-view-lobby'); @@ -93,18 +93,18 @@ export const HotelView: FC<{}> = props => if(lobbyEl) { const containerRect = container.getBoundingClientRect(); - const lobbyRect = lobbyEl.getBoundingClientRect(); + const lobbyRect = lobbyEl.getBoundingClientRect(); - const lobbyCenterX = (lobbyRect.left - containerRect.left) + container.scrollLeft + lobbyRect.width / 2; - const lobbyCenterY = (lobbyRect.top - containerRect.top) + container.scrollTop + lobbyRect.height / 2; + const lobbyCenterX = (lobbyRect.left - containerRect.left) + container.scrollLeft + lobbyRect.width / 2; + const lobbyCenterY = (lobbyRect.top - containerRect.top) + container.scrollTop + lobbyRect.height / 2; - container.scrollLeft = Math.max(0, lobbyCenterX - viewportWidth / 2); - container.scrollTop = Math.max(0, lobbyCenterY - viewportHeight / 2); + container.scrollLeft = Math.max(0, lobbyCenterX - viewportWidth / 2); + container.scrollTop = Math.max(0, lobbyCenterY - viewportHeight / 2); } else { - container.scrollLeft = Math.max(0, (2600 - viewportWidth) / 2); - container.scrollTop = Math.max(0, (1425 - viewportHeight) / 2); + container.scrollLeft = Math.max(0, (2600 - viewportWidth) / 2); + container.scrollTop = Math.max(0, (1425 - viewportHeight) / 2); } }; @@ -141,7 +141,7 @@ export const HotelView: FC<{}> = props => if(containerRef.current) { containerRef.current.scrollLeft -= dx; - containerRef.current.scrollTop -= dy; + containerRef.current.scrollTop -= dy; } }; diff --git a/src/components/hotel-view/RoomWidgetView.tsx b/src/components/hotel-view/RoomWidgetView.tsx index bc5129f..99c8e0b 100644 --- a/src/components/hotel-view/RoomWidgetView.tsx +++ b/src/components/hotel-view/RoomWidgetView.tsx @@ -5,7 +5,8 @@ import { Base } from '../../common'; export interface RoomWidgetViewProps {} -export const RoomWidgetView: FC = props => { +export const RoomWidgetView: FC = props => +{ const poolId = GetConfigurationValue('hotelview')['room.pool']; const picnicId = GetConfigurationValue('hotelview')['room.picnic']; const rooftopId = GetConfigurationValue('hotelview')['room.rooftop']; diff --git a/src/components/interface-settings/InterfaceColorTabView.tsx b/src/components/interface-settings/InterfaceColorTabView.tsx index 70c9fb6..fccbe1e 100644 --- a/src/components/interface-settings/InterfaceColorTabView.tsx +++ b/src/components/interface-settings/InterfaceColorTabView.tsx @@ -126,7 +126,8 @@ export const InterfaceColorTabView: FC<{}> = () => setImportValue(''); setShowImport(false); } - catch(e) {} + catch(e) + {} }, [ importValue, updateSettings ]); return ( diff --git a/src/components/inventory/views/badge/InventoryBadgeView.tsx b/src/components/inventory/views/badge/InventoryBadgeView.tsx index 1d39b6d..850e6b8 100644 --- a/src/components/inventory/views/badge/InventoryBadgeView.tsx +++ b/src/components/inventory/views/badge/InventoryBadgeView.tsx @@ -107,8 +107,14 @@ export const InventoryBadgeView: FC<{ filteredBadgeCodes?: string[] }> = props = } }, []); - useEffect(() => { refreshOwnCustomBadges(); }, [ refreshOwnCustomBadges ]); - useEffect(() => { ensureCustomBadgeTexts(); }, []); + useEffect(() => + { + refreshOwnCustomBadges(); + }, [ refreshOwnCustomBadges ]); + useEffect(() => + { + ensureCustomBadgeTexts(); + }, []); const baseCodes = (filteredBadgeCodes !== null ? filteredBadgeCodes : badgeCodes); const customCount = useMemo(() => baseCodes.filter(c => isCustomBadgeCode(c)).length, [ baseCodes ]); @@ -138,7 +144,8 @@ export const InventoryBadgeView: FC<{ filteredBadgeCodes?: string[] }> = props = await refreshOwnCustomBadges(); refreshCustomBadgeTexts(); } - catch { /* error already surfaced server-side */ } + catch + { /* error already surfaced server-side */ } }, null, null, null, LocalizeText('inventory.delete.confirm_delete.title') diff --git a/src/components/loading/LoadingView.tsx b/src/components/loading/LoadingView.tsx index c4447f0..30e3c0c 100644 --- a/src/components/loading/LoadingView.tsx +++ b/src/components/loading/LoadingView.tsx @@ -8,7 +8,8 @@ interface LoadingViewProps { homeUrl?: string; } -export const LoadingView: FC = props => { +export const LoadingView: FC = props => +{ const { isError = false, message = '', homeUrl = '' } = props; return ( diff --git a/src/components/login/LoginView.tsx b/src/components/login/LoginView.tsx index 1177dc9..320bdfd 100644 --- a/src/components/login/LoginView.tsx +++ b/src/components/login/LoginView.tsx @@ -27,8 +27,12 @@ const interpolate = (value: string | null | undefined): string => let output = value; - try { output = GetConfiguration().interpolate(value) || value; } - catch {} + try + { + output = GetConfiguration().interpolate(value) || value; + } + catch + {} return output.replace(/\$\{([^}]+)\}/g, (_, key: string) => { @@ -45,7 +49,8 @@ const interpolate = (value: string | null | undefined): string => if(configValue) return configValue; } - catch {} + catch + {} try { @@ -53,7 +58,8 @@ const interpolate = (value: string | null | undefined): string => if(configValue) return configValue; } - catch {} + catch + {} return ''; }); @@ -100,13 +106,20 @@ const readLock = (): AttemptState => if(!raw) return { attempts: 0, firstAt: 0, lockedUntil: 0 }; return JSON.parse(raw); } - catch { return { attempts: 0, firstAt: 0, lockedUntil: 0 }; } + catch + { + return { attempts: 0, firstAt: 0, lockedUntil: 0 }; + } }; const writeLock = (state: AttemptState) => { - try { sessionStorage.setItem(LOCK_KEY, JSON.stringify(state)); } - catch { } + try + { + sessionStorage.setItem(LOCK_KEY, JSON.stringify(state)); + } + catch + { } }; const normalizeLanguageCode = (value: string): string => @@ -150,7 +163,8 @@ const readCachedLocale = (): LoginLocale => if(typeof settings.uiTextLanguage === 'string' && settings.uiTextLanguage.length) return resolveLoginLocale(settings.uiTextLanguage); } - catch {} + catch + {} return getBrowserLocale(); }; @@ -170,7 +184,8 @@ const applyLocaleSelection = (locale: LoginLocale): void => localStorage.setItem(CHAT_TRANSLATION_SETTINGS_KEY, JSON.stringify(nextSettings)); } - catch {} + catch + {} }; const LoginSubmitButton: FC<{ isEntering: boolean; isLocked: boolean; loginPingingServer: boolean }> = ({ isEntering, isLocked, loginPingingServer }) => @@ -220,7 +235,7 @@ export const LoginView: FC = ({ onAuthenticated, isEntering = fa const configuredLoginWidgets = useMemo>(() => (loginViewConfig?.['widgets'] as Record) ?? {}, [ loginViewConfig ]); - + const loginWidgetSlots = useMemo(() => { return Object.entries(configuredLoginWidgets) @@ -411,8 +426,12 @@ export const LoginView: FC = ({ onAuthenticated, isEntering = fa }); let payload: Record = {}; - try { payload = await response.json(); } - catch { } + try + { + payload = await response.json(); + } + catch + { } return { ok: response.ok, status: response.status, payload }; }, []); @@ -705,7 +724,10 @@ export const LoginView: FC = ({ onAuthenticated, isEntering = fa } @@ -957,7 +979,12 @@ const renderAvatarPreview = (figure: string, gender: GenderKey, setType: string) if(resolved) return; resolved = true; if(timer !== null) window.clearTimeout(timer); - try { avatarImage?.dispose(); } catch {} + try + { + avatarImage?.dispose(); + } + catch + {} avatarImage = null; if(url) { @@ -976,17 +1003,26 @@ const renderAvatarPreview = (figure: string, gender: GenderKey, setType: string) const attempt = () => { if(resolved) return; - if(attempts >= AVATAR_PREVIEW_MAX_ATTEMPTS) { finish(''); return; } + if(attempts >= AVATAR_PREVIEW_MAX_ATTEMPTS) + { + finish(''); return; + } attempts++; - try { avatarImage?.dispose(); } catch {} + try + { + avatarImage?.dispose(); + } + catch + {} avatarImage = null; try { avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, { resetFigure: () => attempt(), - dispose: () => {}, + dispose: () => + {}, disposed: false }); } @@ -996,7 +1032,10 @@ const renderAvatarPreview = (figure: string, gender: GenderKey, setType: string) return; } - if(!avatarImage) { finish(''); return; } + if(!avatarImage) + { + finish(''); return; + } if(avatarImage.isPlaceholder()) return; @@ -1036,7 +1075,10 @@ const useAvatarPreview = (figure: string, gender: GenderKey, setType: string): s { if(!cancelled) setUrl(result); }); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, [ figure, gender, setType ]); return url; @@ -1061,7 +1103,10 @@ const AvatarPartRow: FC = ({ setType, selection, gender, onP
- { url && { { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> } + { url && { + { + (e.currentTarget).style.visibility = 'hidden'; + } } /> }
@@ -1108,7 +1153,10 @@ const RegisterDialog: FC = props => const ok = await onCheckServer(); if(!cancelled) setServerReachable(ok); })(); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, [ onCheckServer ]); const resetWidget = useCallback(() => @@ -1117,15 +1165,24 @@ const RegisterDialog: FC = props => setResetSignal(prev => prev + 1); }, []); - useEffect(() => { setLocalError(null); }, [ step ]); + useEffect(() => + { + setLocalError(null); + }, [ step ]); const [ figureData, setFigureData ] = useState(null); const figureDataUrlRaw = GetConfigurationValue('avatar.figuredata.url', ''); const figureDataUrl = useMemo(() => { if(!figureDataUrlRaw) return ''; - try { return GetConfiguration().interpolate(figureDataUrlRaw); } - catch { return figureDataUrlRaw; } + try + { + return GetConfiguration().interpolate(figureDataUrlRaw); + } + catch + { + return figureDataUrlRaw; + } }, [ figureDataUrlRaw ]); useEffect(() => @@ -1134,9 +1191,16 @@ const RegisterDialog: FC = props => let cancelled = false; fetch(figureDataUrl, { credentials: 'omit' }) .then(r => r.ok ? r.json() : null) - .then(json => { if(!cancelled && json) setFigureData(json as FigureData); }) - .catch(() => { }); - return () => { cancelled = true; }; + .then(json => + { + if(!cancelled && json) setFigureData(json as FigureData); + }) + .catch(() => + { }); + return () => + { + cancelled = true; + }; }, [ step, figureData, figureDataUrl ]); const partOptions = useMemo(() => @@ -1162,7 +1226,10 @@ const RegisterDialog: FC = props => { if(!PART_ROWS.includes(st.type)) continue; const palette = figureData.palettes.find(p => p.id === st.paletteId); - if(!palette) { result[st.type] = []; continue; } + if(!palette) + { + result[st.type] = []; continue; + } result[st.type] = palette.colors .filter(c => c.selectable && c.club === 0) .map(c => ({ id: c.id, hex: '#' + c.hexCode.toUpperCase() })); @@ -1199,12 +1266,16 @@ const RegisterDialog: FC = props => const rawGender = typeof entry._gender === 'string' ? entry._gender.toUpperCase() : ''; const figure = typeof entry._figure === 'string' ? entry._figure : ''; if((rawGender !== 'M' && rawGender !== 'F') || !figure) continue; - parsed.push({ gender: rawGender as GenderKey, figure }); + parsed.push({ gender: rawGender, figure }); } if(parsed.length) setHotLooks(parsed); }) - .catch(() => { }); - return () => { cancelled = true; }; + .catch(() => + { }); + return () => + { + cancelled = true; + }; }, [ step, hotLooks.length ]); const applyLook = useCallback((figure: string, lookGender: GenderKey) => @@ -1498,11 +1569,15 @@ const RegisterDialog: FC = props =>
- { previewSrc && Habbo preview { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> } + { previewSrc && Habbo preview + { + (e.currentTarget).style.visibility = 'hidden'; + } } /> }
- { PART_ROWS.map(setType => { + { PART_ROWS.map(setType => + { const fallbackColor = FALLBACK_DEFAULTS[gender][setType]?.colors?.[0] ?? 0; const currentColor = selection[setType]?.colors?.[0] ?? fallbackColor; const swatchHex = hexFor(setType, currentColor); diff --git a/src/components/login/TurnstileWidget.tsx b/src/components/login/TurnstileWidget.tsx index 0542829..2bd1496 100644 --- a/src/components/login/TurnstileWidget.tsx +++ b/src/components/login/TurnstileWidget.tsx @@ -67,7 +67,12 @@ export const TurnstileWidget: FC = props => { if(widgetIdRef.current && window.turnstile) { - try { window.turnstile.remove(widgetIdRef.current); } catch { } + try + { + window.turnstile.remove(widgetIdRef.current); + } + catch + { } widgetIdRef.current = null; } }; @@ -78,7 +83,12 @@ export const TurnstileWidget: FC = props => if(resetSignal <= 0) return; if(widgetIdRef.current && window.turnstile) { - try { window.turnstile.reset(widgetIdRef.current); } catch { } + try + { + window.turnstile.reset(widgetIdRef.current); + } + catch + { } } }, [ resetSignal ]); diff --git a/src/components/login/components/NewsWindow.tsx b/src/components/login/components/NewsWindow.tsx index bd31947..0afd323 100644 --- a/src/components/login/components/NewsWindow.tsx +++ b/src/components/login/components/NewsWindow.tsx @@ -45,7 +45,10 @@ export const NewsWindow: FC = ({ newsUrl }) => useEffect(() => { - if(!newsUrl) { setFailed(true); return; } + if(!newsUrl) + { + setFailed(true); return; + } let cancelled = false; const controller = new AbortController(); @@ -63,7 +66,10 @@ export const NewsWindow: FC = ({ newsUrl }) => : Array.isArray(json) ? (json as RawNewsItem[]) : []; setItems(rawList.map((raw, idx) => normalizeNewsItem(raw, idx + 1))); }) - .catch(() => { if(!cancelled) setFailed(true); }); + .catch(() => + { + if(!cancelled) setFailed(true); + }); return () => { cancelled = true; @@ -87,8 +93,14 @@ export const NewsWindow: FC = ({ newsUrl }) => const current = items[Math.min(index, items.length - 1)]; const hasMany = items.length > 1; const bumpAuto = () => setAutoTick(t => t + 1); - const prev = () => { setIndex(i => (i - 1 + items.length) % items.length); bumpAuto(); }; - const next = () => { setIndex(i => (i + 1) % items.length); bumpAuto(); }; + const prev = () => + { + setIndex(i => (i - 1 + items.length) % items.length); bumpAuto(); + }; + const next = () => + { + setIndex(i => (i + 1) % items.length); bumpAuto(); + }; const safeLinkUrl = resolveNewsLink(current.linkUrl); const safeImageSrc = resolveNewsImage(current.image); @@ -119,7 +131,10 @@ export const NewsWindow: FC = ({ newsUrl }) => { { (e.currentTarget as HTMLImageElement).style.display = 'none'; } } + onError={ e => + { + (e.currentTarget).style.display = 'none'; + } } />
} diff --git a/src/components/login/components/RegisterDialog.tsx b/src/components/login/components/RegisterDialog.tsx index b952c56..42f0e72 100644 --- a/src/components/login/components/RegisterDialog.tsx +++ b/src/components/login/components/RegisterDialog.tsx @@ -72,7 +72,10 @@ export const RegisterDialog: FC = props => const ok = await onCheckServer(); if(!cancelled) setServerReachable(ok); })(); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, [ onCheckServer ]); const resetWidget = useCallback(() => @@ -81,7 +84,10 @@ export const RegisterDialog: FC = props => setResetSignal(prev => prev + 1); }, []); - useEffect(() => { setLocalError(null); }, [ step ]); + useEffect(() => + { + setLocalError(null); + }, [ step ]); const [ roomTemplates, setRoomTemplates ] = useState(null); const [ roomTemplatesError, setRoomTemplatesError ] = useState(null); @@ -92,8 +98,14 @@ export const RegisterDialog: FC = props => const figureDataUrl = useMemo(() => { if(!figureDataUrlRaw) return ''; - try { return GetConfiguration().interpolate(figureDataUrlRaw); } - catch { return figureDataUrlRaw; } + try + { + return GetConfiguration().interpolate(figureDataUrlRaw); + } + catch + { + return figureDataUrlRaw; + } }, [ figureDataUrlRaw ]); useEffect(() => @@ -102,9 +114,16 @@ export const RegisterDialog: FC = props => let cancelled = false; fetch(figureDataUrl, { credentials: 'omit' }) .then(r => r.ok ? r.json() : null) - .then(json => { if(!cancelled && json) setFigureData(json as FigureData); }) - .catch(() => { }); - return () => { cancelled = true; }; + .then(json => + { + if(!cancelled && json) setFigureData(json as FigureData); + }) + .catch(() => + { }); + return () => + { + cancelled = true; + }; }, [ step, figureData, figureDataUrl ]); useEffect(() => @@ -113,23 +132,29 @@ export const RegisterDialog: FC = props => let cancelled = false; setRoomTemplatesError(null); fetch(roomTemplatesUrl, { credentials: 'include' }) - .then(async r => { + .then(async r => + { if(!r.ok) throw new Error(`status ${ r.status }`); return r.json(); }) - .then(json => { + .then(json => + { if(cancelled) return; const list = Array.isArray((json as { templates?: unknown })?.templates) ? (json as { templates: RoomTemplate[] }).templates : []; setRoomTemplates(list); }) - .catch(() => { + .catch(() => + { if(cancelled) return; setRoomTemplates([]); setRoomTemplatesError(t('nitro.login.register.room.error', 'Could not load room options. You can still skip this step.')); }); - return () => { cancelled = true; }; + return () => + { + cancelled = true; + }; }, [ step, roomTemplates, roomTemplatesUrl ]); const partOptions = useMemo(() => @@ -155,7 +180,10 @@ export const RegisterDialog: FC = props => { if(!PART_ROWS.includes(st.type)) continue; const palette = figureData.palettes.find(p => p.id === st.paletteId); - if(!palette) { result[st.type] = []; continue; } + if(!palette) + { + result[st.type] = []; continue; + } result[st.type] = palette.colors .filter(c => c.selectable && c.club === 0) .map(c => ({ id: c.id, hex: '#' + c.hexCode.toUpperCase() })); @@ -192,12 +220,16 @@ export const RegisterDialog: FC = props => const rawGender = typeof entry._gender === 'string' ? entry._gender.toUpperCase() : ''; const figure = typeof entry._figure === 'string' ? entry._figure : ''; if((rawGender !== 'M' && rawGender !== 'F') || !figure) continue; - parsed.push({ gender: rawGender as GenderKey, figure }); + parsed.push({ gender: rawGender, figure }); } if(parsed.length) setHotLooks(parsed); }) - .catch(() => { }); - return () => { cancelled = true; }; + .catch(() => + { }); + return () => + { + cancelled = true; + }; }, [ step, hotLooks.length ]); const applyLook = useCallback((figure: string, lookGender: GenderKey) => @@ -499,14 +531,18 @@ export const RegisterDialog: FC = props =>
- { PART_ROWS.map(setType => { + { PART_ROWS.map(setType => + { const partPreviewSrc = buildPartPreviewUrl(imagingUrl, setType, selection, gender); return (
- { { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> + { + { + (e.currentTarget).style.visibility = 'hidden'; + } } />
@@ -516,11 +552,15 @@ export const RegisterDialog: FC = props =>
- Habbo preview { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> + Habbo preview + { + (e.currentTarget).style.visibility = 'hidden'; + } } />
- { PART_ROWS.map(setType => { + { PART_ROWS.map(setType => + { const fallbackColor = FALLBACK_DEFAULTS[gender][setType]?.colors?.[0] ?? 0; const currentColor = selection[setType]?.colors?.[0] ?? fallbackColor; const swatchHex = hexFor(setType, currentColor); @@ -603,7 +643,10 @@ export const RegisterDialog: FC = props => onChange={ () => setSelectedTemplateId(template.templateId) } /> { template.thumbnail && { { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> } + onError={ e => + { + (e.currentTarget).style.visibility = 'hidden'; + } } /> }
{ template.title }
{ template.description && diff --git a/src/components/login/utils/i18n.ts b/src/components/login/utils/i18n.ts index 58f88f8..03edc3a 100644 --- a/src/components/login/utils/i18n.ts +++ b/src/components/login/utils/i18n.ts @@ -8,7 +8,8 @@ export const t = (key: string, fallback: string, params?: string[], replacements const value = LocalizeText(key, params ?? null, replacements ?? null); if(value && value !== key) return value; } - catch {} + catch + {} if(!params || !replacements) return fallback; let out = fallback; @@ -22,6 +23,12 @@ export const t = (key: string, fallback: string, params?: string[], replacements export const interpolate = (value: string | null | undefined): string => { if(!value) return ''; - try { return GetConfiguration().interpolate(value); } - catch { return value; } + try + { + return GetConfiguration().interpolate(value); + } + catch + { + return value; + } }; diff --git a/src/components/login/utils/lockState.ts b/src/components/login/utils/lockState.ts index ef5a946..62d7c04 100644 --- a/src/components/login/utils/lockState.ts +++ b/src/components/login/utils/lockState.ts @@ -13,11 +13,18 @@ export const readLock = (): AttemptState => if(!raw) return { attempts: 0, firstAt: 0, lockedUntil: 0 }; return JSON.parse(raw); } - catch { return { attempts: 0, firstAt: 0, lockedUntil: 0 }; } + catch + { + return { attempts: 0, firstAt: 0, lockedUntil: 0 }; + } }; export const writeLock = (state: AttemptState) => { - try { sessionStorage.setItem(LOCK_KEY, JSON.stringify(state)); } - catch { } + try + { + sessionStorage.setItem(LOCK_KEY, JSON.stringify(state)); + } + catch + { } }; diff --git a/src/components/login/utils/news.ts b/src/components/login/utils/news.ts index 0fa0c82..2fcd87a 100644 --- a/src/components/login/utils/news.ts +++ b/src/components/login/utils/news.ts @@ -12,8 +12,14 @@ export const resolveNewsImage = (raw: string | null | undefined): string => if(value.startsWith('//')) return window.location.protocol + value; if(value.startsWith('/')) { - try { return new URL(value, window.location.origin).href; } - catch { return window.location.origin + value; } + try + { + return new URL(value, window.location.origin).href; + } + catch + { + return window.location.origin + value; + } } if(value.startsWith('data:')) { @@ -46,5 +52,8 @@ export const resolveNewsLink = (raw: string | null | undefined): string => if(proto !== 'http:' && proto !== 'https:') return ''; return url.href; } - catch { return ''; } + catch + { + return ''; + } }; diff --git a/src/components/mod-tools/views/room/ModToolsChatlogView.tsx b/src/components/mod-tools/views/room/ModToolsChatlogView.tsx index c42320d..b3a4a39 100644 --- a/src/components/mod-tools/views/room/ModToolsChatlogView.tsx +++ b/src/components/mod-tools/views/room/ModToolsChatlogView.tsx @@ -34,7 +34,7 @@ export const ModToolsChatlogView: FC = props => return ( - + { roomChatlog && } diff --git a/src/components/navigator/views/room-settings/NavigatorRoomSettingsAccessTabView.tsx b/src/components/navigator/views/room-settings/NavigatorRoomSettingsAccessTabView.tsx index 57ae347..c842b10 100644 --- a/src/components/navigator/views/room-settings/NavigatorRoomSettingsAccessTabView.tsx +++ b/src/components/navigator/views/room-settings/NavigatorRoomSettingsAccessTabView.tsx @@ -21,7 +21,7 @@ export const NavigatorRoomSettingsAccessTabView: FC { diff --git a/src/components/navigator/views/room-settings/NavigatorRoomSettingsBasicTabView.tsx b/src/components/navigator/views/room-settings/NavigatorRoomSettingsBasicTabView.tsx index 58de23a..cacaa59 100644 --- a/src/components/navigator/views/room-settings/NavigatorRoomSettingsBasicTabView.tsx +++ b/src/components/navigator/views/room-settings/NavigatorRoomSettingsBasicTabView.tsx @@ -59,21 +59,21 @@ export const NavigatorRoomSettingsBasicTabView: FC { if((roomName === roomData.roomName) || (roomName.length < ROOM_NAME_MIN_LENGTH) || (roomName.length > ROOM_NAME_MAX_LENGTH)) return; handleChange('name', roomName); - } + }; const saveRoomDescription = () => { if((roomDescription === roomData.roomDescription) || (roomDescription.length > DESC_MAX_LENGTH)) return; handleChange('description', roomDescription); - } + }; const saveTags = (index: number) => { @@ -86,7 +86,7 @@ export const NavigatorRoomSettingsBasicTabView: FC { @@ -168,7 +168,7 @@ export const NavigatorRoomSettingsBasicTabView: FC{ LocalizeText('navigator.roomsettings.allow_underpass') } - { LocalizeText('navigator.roomsettings.delete') } + { LocalizeText('navigator.roomsettings.delete') } ); diff --git a/src/components/navigator/views/room-settings/NavigatorRoomSettingsModTabView.tsx b/src/components/navigator/views/room-settings/NavigatorRoomSettingsModTabView.tsx index 320be69..100ecad 100644 --- a/src/components/navigator/views/room-settings/NavigatorRoomSettingsModTabView.tsx +++ b/src/components/navigator/views/room-settings/NavigatorRoomSettingsModTabView.tsx @@ -27,12 +27,12 @@ export const NavigatorRoomSettingsModTabView: FC= 0) newValue.splice(index, 1); return newValue; - }) + }); SendMessageComposer(new RoomUnbanUserComposer(userId, roomData.roomId)); setSelectedUserId(-1); - } + }; useMessageEvent(BannedUsersFromRoomEvent, event => { @@ -115,4 +115,4 @@ export const NavigatorRoomSettingsModTabView: FC ); -} +}; diff --git a/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx b/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx index d9eb3f7..eede2d5 100644 --- a/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx +++ b/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx @@ -36,7 +36,7 @@ export const NavigatorRoomSettingsRightsTabView: FC = props => return ( - { if(currentTab === TABS[3]) CreateLinkEvent('habbopages/chat/options'); } } onCloseClick={ onClose } /> + + { + if(currentTab === TABS[3]) CreateLinkEvent('habbopages/chat/options'); + } } onCloseClick={ onClose } /> { TABS.map(tab => { diff --git a/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx b/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx index 40cc451..764ce1e 100644 --- a/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx +++ b/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx @@ -100,8 +100,14 @@ export const NavigatorSearchResultItemInfoView: FC { if(!isControlled) setInternalVisible(true); } } - onMouseLeave={ () => { if(!isControlled) setInternalVisible(false); } } + onMouseOver={ () => + { + if(!isControlled) setInternalVisible(true); + } } + onMouseLeave={ () => + { + if(!isControlled) setInternalVisible(false); + } } /> diff --git a/src/components/nitrobubblehidden/NitrobubbleHiddenView.tsx b/src/components/nitrobubblehidden/NitrobubbleHiddenView.tsx index 6f93c75..67a98a4 100644 --- a/src/components/nitrobubblehidden/NitrobubbleHiddenView.tsx +++ b/src/components/nitrobubblehidden/NitrobubbleHiddenView.tsx @@ -9,7 +9,7 @@ export const NitrobubbleHiddenView: FC<{}> = props => const { chatHistory = [] } = useChatHistory(); const elementRef = useRef(null); - const filteredChatHistory = useMemo(() => + const filteredChatHistory = useMemo(() => { if (searchText.length === 0) return chatHistory; @@ -29,9 +29,9 @@ export const NitrobubbleHiddenView: FC<{}> = props => linkReceived: (url: string) => { const parts = url.split('/'); - + if(parts.length < 2) return; - + switch(parts[1]) { case 'show': @@ -54,6 +54,6 @@ export const NitrobubbleHiddenView: FC<{}> = props => }, []); if(!isVisible) return null; - var stylecssnew = ""; + var stylecssnew = ''; return (
); -} +}; diff --git a/src/components/notification-center/views/alert-layouts/NitroSystemAlertView.tsx b/src/components/notification-center/views/alert-layouts/NitroSystemAlertView.tsx index dd47863..658aeda 100644 --- a/src/components/notification-center/views/alert-layouts/NitroSystemAlertView.tsx +++ b/src/components/notification-center/views/alert-layouts/NitroSystemAlertView.tsx @@ -28,15 +28,15 @@ export const NitroSystemAlertView: FC = props } -
- - - Cool UI - - DuckieTM (Design) - v3.0.0 - - - +
+ + + Cool UI + - DuckieTM (Design) + v3.0.0 + + + diff --git a/src/components/plugins/NitroPluginApi.ts b/src/components/plugins/NitroPluginApi.ts index 1a8d373..d38ccc6 100644 --- a/src/components/plugins/NitroPluginApi.ts +++ b/src/components/plugins/NitroPluginApi.ts @@ -157,7 +157,7 @@ const pluginApi: INitroPluginApi = { // Create overlay container const overlay = document.createElement('div'); overlay.id = `nitro-plugin-window-${id}`; - overlay.style.cssText = `position:fixed;z-index:500;top:50%;left:50%;transform:translate(-50%,-50%)`; + overlay.style.cssText = 'position:fixed;z-index:500;top:50%;left:50%;transform:translate(-50%,-50%)'; // Card wrapper const card = document.createElement('div'); @@ -165,14 +165,14 @@ const pluginApi: INitroPluginApi = { // Header (draggable) const header = document.createElement('div'); - header.style.cssText = `display:flex;align-items:center;justify-content:center;position:relative;min-height:33px;background:linear-gradient(180deg,#3c6a8e 0%,#2a4f6e 100%);cursor:move;user-select:none`; + header.style.cssText = 'display:flex;align-items:center;justify-content:center;position:relative;min-height:33px;background:linear-gradient(180deg,#3c6a8e 0%,#2a4f6e 100%);cursor:move;user-select:none'; const titleEl = document.createElement('span'); titleEl.textContent = title; - titleEl.style.cssText = `color:#fff;font-size:16px;text-shadow:0 1px 2px rgba(0,0,0,0.5)`; + titleEl.style.cssText = 'color:#fff;font-size:16px;text-shadow:0 1px 2px rgba(0,0,0,0.5)'; const closeBtn = document.createElement('div'); - closeBtn.style.cssText = `position:absolute;right:8px;width:20px;height:20px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;border-radius:50%;background:rgba(255,255,255,0.1)`; + closeBtn.style.cssText = 'position:absolute;right:8px;width:20px;height:20px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;border-radius:50%;background:rgba(255,255,255,0.1)'; closeBtn.innerHTML = '✕'; closeBtn.addEventListener('click', () => pluginApi.destroyWindow(id)); @@ -201,7 +201,10 @@ const pluginApi: INitroPluginApi = { overlay.style.top = (e.clientY - offsetY) + 'px'; }; - const onMouseUp = () => { isDragging = false; }; + const onMouseUp = () => + { + isDragging = false; + }; header.addEventListener('mousedown', onMouseDown); document.addEventListener('mousemove', onMouseMove); @@ -209,7 +212,7 @@ const pluginApi: INitroPluginApi = { // Content area const content = document.createElement('div'); - content.style.cssText = `padding:16px`; + content.style.cssText = 'padding:16px'; card.appendChild(header); card.appendChild(content); diff --git a/src/components/purse/PurseView.tsx b/src/components/purse/PurseView.tsx index 0a50441..51ab0c7 100644 --- a/src/components/purse/PurseView.tsx +++ b/src/components/purse/PurseView.tsx @@ -8,7 +8,8 @@ import purseIcon from '../../assets/images/rightside/purse.gif'; import { CurrencyView } from './views/CurrencyView'; import { SeasonalView } from './views/SeasonalView'; -export const PurseView: FC<{}> = props => { +export const PurseView: FC<{}> = props => +{ const { purse = null, hcDisabled = false } = usePurse(); const [ isOpen, setIsOpen ] = useState(true); const [ isCompact, setIsCompact ] = useState(false); @@ -16,7 +17,8 @@ export const PurseView: FC<{}> = props => { const displayedCurrencies = useMemo(() => GetConfigurationValue('system.currency.types', []), []); const currencyDisplayNumberShort = useMemo(() => GetConfigurationValue('currency.display.number.short', false), []); - const getClubText = (() => { + const getClubText = (() => + { if (!purse) return null; const totalDays = ((purse.clubPeriods * 31) + purse.clubDays); @@ -27,11 +29,13 @@ export const PurseView: FC<{}> = props => { else return FriendlyTime.shortFormat(totalDays * 86400); })(); - const currencyTypes = useMemo(() => { + const currencyTypes = useMemo(() => + { if (!purse || !purse.activityPoints || !purse.activityPoints.size) return []; const types = Array.from(purse.activityPoints.keys()).filter(type => (displayedCurrencies.indexOf(type) >= 0)); - types.sort((a, b) => { + types.sort((a, b) => + { if (a === 0) return -1; if (b === 0) return 1; if (a === 5) return -1; @@ -80,7 +84,8 @@ export const PurseView: FC<{}> = props => { body: JSON.stringify({ ssoTicket, rememberToken }) }); } - catch { /* best-effort — proceed with local logout regardless */ } + catch + { /* best-effort — proceed with local logout regardless */ } ClearRememberLogin(); if(window.NitroConfig) window.NitroConfig['sso.ticket'] = ''; @@ -104,13 +109,16 @@ export const PurseView: FC<{}> = props => {
-
-
- - { primaryCurrencies.map(type => ) } -
- { !hcDisabled && -
{ event.stopPropagation(); CreateLinkEvent('habboUI/open/hccenter'); } }> +
+
+ + { primaryCurrencies.map(type => ) } +
+ { !hcDisabled && +
+ { + event.stopPropagation(); CreateLinkEvent('habboUI/open/hccenter'); + } }>
@@ -119,22 +127,31 @@ export const PurseView: FC<{}> = props => { { getClubText }
} -
- - - - -
+
+ + + +
- { seasonalCurrencies.length > 0 && +
+ { seasonalCurrencies.length > 0 &&
{ seasonalCurrencies.map(type => ) }
} diff --git a/src/components/purse/views/CurrencyView.tsx b/src/components/purse/views/CurrencyView.tsx index 47c07ab..5f4ae97 100644 --- a/src/components/purse/views/CurrencyView.tsx +++ b/src/components/purse/views/CurrencyView.tsx @@ -34,4 +34,4 @@ export const CurrencyView: FC = props =>
); -} +}; diff --git a/src/components/purse/views/SeasonalView.tsx b/src/components/purse/views/SeasonalView.tsx index bfc96a7..de942a3 100644 --- a/src/components/purse/views/SeasonalView.tsx +++ b/src/components/purse/views/SeasonalView.tsx @@ -7,33 +7,34 @@ interface SeasonalViewProps { amount: number; } -export const SeasonalView: FC = props => { - const { type = -1, amount = -1 } = props; - const seasonalColor = GetConfigurationValue('currency.seasonal.color', 'blue'); - const formattedAmount = LocalizeFormattedNumber(amount); - const iconUrl = GetConfigurationValue('currency.asset.icon.url', '').replace('%type%', type.toString()); +export const SeasonalView: FC = props => +{ + const { type = -1, amount = -1 } = props; + const seasonalColor = GetConfigurationValue('currency.seasonal.color', 'blue'); + const formattedAmount = LocalizeFormattedNumber(amount); + const iconUrl = GetConfigurationValue('currency.asset.icon.url', '').replace('%type%', type.toString()); - return ( - - - - - - - {LocalizeText(`purse.seasonal.currency.${type}`)} - - - {formattedAmount} - - - - ); + + + + + + {LocalizeText(`purse.seasonal.currency.${type}`)} + + + {formattedAmount} + + + + ); }; diff --git a/src/components/room/RoomView.tsx b/src/components/room/RoomView.tsx index 5b06db7..a1bcec9 100644 --- a/src/components/room/RoomView.tsx +++ b/src/components/room/RoomView.tsx @@ -14,8 +14,8 @@ export const RoomView: FC<{}> = (props) => useEffect(() => { - if(!roomSession) return; - + if(!roomSession) return; + const canvas = GetRenderer().canvas; if(!canvas) return; @@ -109,10 +109,10 @@ export const RoomView: FC<{}> = (props) => }; }, [roomSession]); - return ( + return ( { - = props - Sprite: { (() => { const ro = GetRoomEngine().getRoomObject(roomSession.roomId, avatarInfo.id, avatarInfo.isWallItem ? RoomObjectCategory.WALL : RoomObjectCategory.FLOOR); return ro?.model?.getValue(RoomObjectVariable.FURNITURE_TYPE_ID) ?? '?'; })() } + Sprite: { (() => + { + const ro = GetRoomEngine().getRoomObject(roomSession.roomId, avatarInfo.id, avatarInfo.isWallItem ? RoomObjectCategory.WALL : RoomObjectCategory.FLOOR); return ro?.model?.getValue(RoomObjectVariable.FURNITURE_TYPE_ID) ?? '?'; + })() }
} { (!avatarInfo.isWallItem && canMove) && diff --git a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetPetView.tsx b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetPetView.tsx index 7941c2d..1e1b557 100644 --- a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetPetView.tsx +++ b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetPetView.tsx @@ -39,23 +39,23 @@ interface InfoStandWidgetPetViewProps { } const PetHeader: FC<{ name: string; petType: number; petBreed: number; onClose: () => void }> = ({ name, petType, petBreed, onClose }) => ( -
- - - {name} - - - - - {LocalizeText(`pet.breed.${petType}.${petBreed}`)} - -
-
+
+ + + {name} + + + + + {LocalizeText(`pet.breed.${petType}.${petBreed}`)} + +
+
); const MonsterplantStats: FC<{ @@ -63,281 +63,290 @@ const MonsterplantStats: FC<{ remainingGrowTime: number; remainingTimeToLive: number; }> = ({ avatarInfo, remainingGrowTime, remainingTimeToLive }) => ( - <> - - -
-
-
- {!avatarInfo.dead && ( - - - {LocalizeText('pet.level', ['level', 'maxlevel'], [avatarInfo.level.toString(), avatarInfo.maximumLevel.toString()])} - + <> + + +
- )} - - - {LocalizeText('infostand.pet.text.wellbeing')} - -
-
- - {avatarInfo.dead || remainingTimeToLive <= 0 - ? '00:00:00' - : `${ConvertSeconds(remainingTimeToLive).split(':')[1]}:${ConvertSeconds(remainingTimeToLive).split(':')[2]}:${ConvertSeconds(remainingTimeToLive).split(':')[3]}`} - -
-
+
+ {!avatarInfo.dead && ( + + + {LocalizeText('pet.level', ['level', 'maxlevel'], [avatarInfo.level.toString(), avatarInfo.maximumLevel.toString()])} + + + )} + + + {LocalizeText('infostand.pet.text.wellbeing')} + +
+
+ + {avatarInfo.dead || remainingTimeToLive <= 0 + ? '00:00:00' + : `${ConvertSeconds(remainingTimeToLive).split(':')[1]}:${ConvertSeconds(remainingTimeToLive).split(':')[2]}:${ConvertSeconds(remainingTimeToLive).split(':')[3]}`} + +
+
+
+ + {remainingGrowTime > 0 && ( + + + {LocalizeText('infostand.pet.text.growth')} + + + + )} + + + {LocalizeText('infostand.pet.text.raritylevel', ['level'], [LocalizeText(`infostand.pet.raritylevel.${avatarInfo.rarityLevel}`)])} + + + +
-
- {remainingGrowTime > 0 && ( - - - {LocalizeText('infostand.pet.text.growth')} - - - - )} - - - {LocalizeText('infostand.pet.text.raritylevel', ['level'], [LocalizeText(`infostand.pet.raritylevel.${avatarInfo.rarityLevel}`)])} - - - -
-
-
- - {LocalizeText('pet.age', ['age'], [avatarInfo.age.toString()])} - -
-
- +
+ + {LocalizeText('pet.age', ['age'], [avatarInfo.age.toString()])} + +
+
+ ); // Sub-component: Regular Pet Stats const RegularPetStats: FC<{ avatarInfo: AvatarInfoPet }> = ({ avatarInfo }) => ( - <> -
-
- - - - - - {LocalizeText('pet.level', ['level', 'maxlevel'], [avatarInfo.level.toString(), avatarInfo.maximumLevel.toString()])} - - - - {LocalizeText('infostand.pet.text.happiness')} - -
-
- - {avatarInfo.happyness + '/' + avatarInfo.maximumHappyness} - -
-
+ <> +
+
+ + + + + + {LocalizeText('pet.level', ['level', 'maxlevel'], [avatarInfo.level.toString(), avatarInfo.maximumLevel.toString()])} + + + + {LocalizeText('infostand.pet.text.happiness')} + +
+
+ + {avatarInfo.happyness + '/' + avatarInfo.maximumHappyness} + +
+
+
+ + + + {LocalizeText('infostand.pet.text.experience')} + +
+
+ + {avatarInfo.experience + '/' + avatarInfo.levelExperienceGoal} + +
+
+
+ + + + {LocalizeText('infostand.pet.text.energy')} + +
+
+ + {avatarInfo.energy + '/' + avatarInfo.maximumEnergy} + +
+
+
+ +
-
- - - {LocalizeText('infostand.pet.text.experience')} +
+
+
+ + {LocalizeText('infostand.text.petrespect', ['count'], [avatarInfo.respect.toString()])} -
-
- - {avatarInfo.experience + '/' + avatarInfo.levelExperienceGoal} - -
-
-
- - - - {LocalizeText('infostand.pet.text.energy')} + + {LocalizeText('pet.age', ['age'], [avatarInfo.age.toString()])} -
-
- - {avatarInfo.energy + '/' + avatarInfo.maximumEnergy} - -
-
-
- - -
-
-
-
- - {LocalizeText('infostand.text.petrespect', ['count'], [avatarInfo.respect.toString()])} - - - {LocalizeText('pet.age', ['age'], [avatarInfo.age.toString()])} - -
-
- +
+
+ ); -export const InfoStandWidgetPetView: FC = ({ avatarInfo, onClose }) => { - const [remainingGrowTime, setRemainingGrowTime] = useState(0); - const [remainingTimeToLive, setRemainingTimeToLive] = useState(0); - const { roomSession = null } = useRoom(); - const { petRespectRemaining = 0, respectPet = null } = useSessionInfo(); +export const InfoStandWidgetPetView: FC = ({ avatarInfo, onClose }) => +{ + const [remainingGrowTime, setRemainingGrowTime] = useState(0); + const [remainingTimeToLive, setRemainingTimeToLive] = useState(0); + const { roomSession = null } = useRoom(); + const { petRespectRemaining = 0, respectPet = null } = useSessionInfo(); - useEffect(() => { - setRemainingGrowTime(avatarInfo.remainingGrowTime || 0); - setRemainingTimeToLive(avatarInfo.remainingTimeToLive || 0); - }, [avatarInfo]); - - useEffect(() => { - if (avatarInfo.petType !== PetType.MONSTERPLANT || avatarInfo.dead) return; - - const interval = setInterval(() => { - setRemainingGrowTime((prev) => (prev <= 0 ? 0 : prev - 1)); - setRemainingTimeToLive((prev) => (prev <= 0 ? 0 : prev - 1)); - }, 1000); - - return () => clearInterval(interval); - }, [avatarInfo]); - - const processButtonAction = useCallback( - async (action: string) => { - try { - let hideMenu = true; - if (!action) return; - - switch (action) { - case 'respect': - await respectPet(avatarInfo.id); - if (petRespectRemaining - 1 >= 1) hideMenu = false; - break; - case 'buyfood': - CreateLinkEvent('catalog/open/' + GetConfigurationValue('catalog.links')['pets.buy_food']); - break; - case 'train': - roomSession?.requestPetCommands(avatarInfo.id); - break; - case 'treat': - SendMessageComposer(new PetRespectComposer(avatarInfo.id)); - break; - case 'compost': - roomSession?.compostPlant(avatarInfo.id); - break; - case 'pick_up': - roomSession?.pickupPet(avatarInfo.id); - break; - } - - if (hideMenu) onClose(); - } catch (error) { - console.error(`Failed to process action ${action}:`, error); - } - }, - [avatarInfo, petRespectRemaining, respectPet, roomSession, onClose] - ); - - const buttons = [ + useEffect(() => { - action: 'buyfood', - label: LocalizeText('infostand.button.buyfood'), - condition: avatarInfo.petType !== PetType.MONSTERPLANT, - }, + setRemainingGrowTime(avatarInfo.remainingGrowTime || 0); + setRemainingTimeToLive(avatarInfo.remainingTimeToLive || 0); + }, [avatarInfo]); + + useEffect(() => { - action: 'train', - label: LocalizeText('infostand.button.train'), - condition: avatarInfo.isOwner && avatarInfo.petType !== PetType.MONSTERPLANT, - }, - { - action: 'treat', - label: LocalizeText('infostand.button.pettreat'), - condition: + if (avatarInfo.petType !== PetType.MONSTERPLANT || avatarInfo.dead) return; + + const interval = setInterval(() => + { + setRemainingGrowTime((prev) => (prev <= 0 ? 0 : prev - 1)); + setRemainingTimeToLive((prev) => (prev <= 0 ? 0 : prev - 1)); + }, 1000); + + return () => clearInterval(interval); + }, [avatarInfo]); + + const processButtonAction = useCallback( + async (action: string) => + { + try + { + let hideMenu = true; + if (!action) return; + + switch (action) + { + case 'respect': + await respectPet(avatarInfo.id); + if (petRespectRemaining - 1 >= 1) hideMenu = false; + break; + case 'buyfood': + CreateLinkEvent('catalog/open/' + GetConfigurationValue('catalog.links')['pets.buy_food']); + break; + case 'train': + roomSession?.requestPetCommands(avatarInfo.id); + break; + case 'treat': + SendMessageComposer(new PetRespectComposer(avatarInfo.id)); + break; + case 'compost': + roomSession?.compostPlant(avatarInfo.id); + break; + case 'pick_up': + roomSession?.pickupPet(avatarInfo.id); + break; + } + + if (hideMenu) onClose(); + } + catch (error) + { + console.error(`Failed to process action ${action}:`, error); + } + }, + [avatarInfo, petRespectRemaining, respectPet, roomSession, onClose] + ); + + const buttons = [ + { + action: 'buyfood', + label: LocalizeText('infostand.button.buyfood'), + condition: avatarInfo.petType !== PetType.MONSTERPLANT, + }, + { + action: 'train', + label: LocalizeText('infostand.button.train'), + condition: avatarInfo.isOwner && avatarInfo.petType !== PetType.MONSTERPLANT, + }, + { + action: 'treat', + label: LocalizeText('infostand.button.pettreat'), + condition: !avatarInfo.dead && avatarInfo.petType === PetType.MONSTERPLANT && avatarInfo.energy / avatarInfo.maximumEnergy < 0.98, - }, - { - action: 'compost', - label: LocalizeText('infostand.button.compost'), - condition: roomSession?.isRoomOwner && avatarInfo.petType === PetType.MONSTERPLANT, - }, - { - action: 'pick_up', - label: LocalizeText('inventory.pets.pickup'), - condition: avatarInfo.isOwner, - }, - { - action: 'respect', - label: LocalizeText('infostand.button.petrespect', ['count'], [petRespectRemaining.toString()]), - condition: petRespectRemaining > 0 && avatarInfo.petType !== PetType.MONSTERPLANT, - }, - ]; + }, + { + action: 'compost', + label: LocalizeText('infostand.button.compost'), + condition: roomSession?.isRoomOwner && avatarInfo.petType === PetType.MONSTERPLANT, + }, + { + action: 'pick_up', + label: LocalizeText('inventory.pets.pickup'), + condition: avatarInfo.isOwner, + }, + { + action: 'respect', + label: LocalizeText('infostand.button.petrespect', ['count'], [petRespectRemaining.toString()]), + condition: petRespectRemaining > 0 && avatarInfo.petType !== PetType.MONSTERPLANT, + }, + ]; - if (!avatarInfo) return {LocalizeText('generic.loading')}; + if (!avatarInfo) return {LocalizeText('generic.loading')}; - return ( - - - - - {avatarInfo.petType === PetType.MONSTERPLANT ? ( - - ) : ( - - )} -
-
- - - {LocalizeText('infostand.text.petowner', ['name'], [avatarInfo.ownerName])} - -
-
+ return ( + + + + + {avatarInfo.petType === PetType.MONSTERPLANT ? ( + + ) : ( + + )} +
+
+ + + {LocalizeText('infostand.text.petowner', ['name'], [avatarInfo.ownerName])} + +
+
+
+
+ + {buttons.map( + (button) => + button.condition && ( + + ) + )} +
-
- - {buttons.map( - (button) => - button.condition && ( - - ) - )} - -
- ); + ); }; \ No newline at end of file diff --git a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx index 6ecb092..bec0273 100644 --- a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx +++ b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx @@ -16,286 +16,312 @@ interface InfoStandWidgetUserViewProps { onClose: () => void; } -export const InfoStandWidgetUserView: FC = props => { - const { avatarInfo = null, setAvatarInfo = null, onClose = null } = props; - const [motto, setMotto] = useState(null); - const [isEditingMotto, setIsEditingMotto] = useState(false); - const [relationships, setRelationships] = useState(null); - const [backgroundId, setBackgroundId] = useState(null); - const [standId, setStandId] = useState(null); - const [overlayId, setOverlayId] = useState(null); - const [cardBackgroundId, setCardBackgroundId] = useState(null); - const [isVisible, setIsVisible] = useState(false); - const { roomSession = null } = useRoom(); +export const InfoStandWidgetUserView: FC = props => +{ + const { avatarInfo = null, setAvatarInfo = null, onClose = null } = props; + const [motto, setMotto] = useState(null); + const [isEditingMotto, setIsEditingMotto] = useState(false); + const [relationships, setRelationships] = useState(null); + const [backgroundId, setBackgroundId] = useState(null); + const [standId, setStandId] = useState(null); + const [overlayId, setOverlayId] = useState(null); + const [cardBackgroundId, setCardBackgroundId] = useState(null); + const [isVisible, setIsVisible] = useState(false); + const { roomSession = null } = useRoom(); - const infostandBackgroundClass = `background-${backgroundId ?? 'default'}`; - const infostandStandClass = `stand-${standId ?? 'default'}`; - const infostandOverlayClass = `overlay-${overlayId ?? 'default'}`; - const infostandCardBackgroundClass = cardBackgroundId ? `card-background-${cardBackgroundId}` : ''; - const handleProfileClick = useCallback(() => { GetUserProfile(avatarInfo.webID); }, [avatarInfo.webID]); + const infostandBackgroundClass = `background-${backgroundId ?? 'default'}`; + const infostandStandClass = `stand-${standId ?? 'default'}`; + const infostandOverlayClass = `overlay-${overlayId ?? 'default'}`; + const infostandCardBackgroundClass = cardBackgroundId ? `card-background-${cardBackgroundId}` : ''; + const handleProfileClick = useCallback(() => + { + GetUserProfile(avatarInfo.webID); + }, [avatarInfo.webID]); - const handleEditClick = useCallback((event: React.MouseEvent) => { event.stopPropagation(); setIsVisible(prev => !prev); }, []); + const handleEditClick = useCallback((event: React.MouseEvent) => + { + event.stopPropagation(); setIsVisible(prev => !prev); + }, []); - const saveMotto = (motto: string) => { - if (!isEditingMotto || motto.length > GetConfigurationValue('motto.max.length', 38) || !roomSession) return; + const saveMotto = (motto: string) => + { + if (!isEditingMotto || motto.length > GetConfigurationValue('motto.max.length', 38) || !roomSession) return; - roomSession.sendMottoMessage(motto); - setIsEditingMotto(false); - }; - - const onMottoBlur = (event: FocusEvent) => saveMotto(event.target.value); - - const onMottoKeyDown = (event: KeyboardEvent) => { - event.stopPropagation(); - - switch (event.key) { - case 'Enter': - saveMotto((event.target as HTMLInputElement).value); - return; - } - }; - - useNitroEvent(RoomSessionUserBadgesEvent.RSUBE_BADGES, event => { - if (!avatarInfo || avatarInfo.webID !== event.userId) return; - - // Deduplicate badges from server - const seen = new Set(); - const dedupedBadges = event.badges.map(code => { - if (!code || seen.has(code)) return ''; - seen.add(code); - return code; - }); - - const oldBadges = avatarInfo.badges.join(''); - - if (oldBadges === dedupedBadges.join('')) return; - - setAvatarInfo(prevValue => { - if (!prevValue) return prevValue; - - const newValue = CloneObject(prevValue); - newValue.badges = dedupedBadges; - return newValue; - }); - }); - - useNitroEvent(RoomSessionUserFigureUpdateEvent.USER_FIGURE, event => { - if (!avatarInfo || avatarInfo.roomIndex !== event.roomIndex) return; - - setAvatarInfo(prevValue => { - if (!prevValue) return prevValue; - - const newValue = CloneObject(prevValue); - newValue.figure = event.figure; - newValue.motto = event.customInfo; - newValue.achievementScore = event.activityPoints; - newValue.nickIcon = event.nickIcon; - newValue.prefixText = event.prefixText; - newValue.prefixColor = event.prefixColor; - newValue.prefixIcon = event.prefixIcon; - newValue.prefixEffect = event.prefixEffect; - newValue.displayOrder = event.displayOrder; - newValue.backgroundId = event.backgroundId; - newValue.standId = event.standId; - newValue.overlayId = event.overlayId; - newValue.cardBackgroundId = event.cardBackgroundId ?? 0; - return newValue; - }); - }); - - useNitroEvent(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, event => { - if (!avatarInfo || avatarInfo.roomIndex !== event.roomIndex) return; - - setAvatarInfo(prevValue => { - if (!prevValue) return prevValue; - - const newValue = CloneObject(prevValue); - const clearGroup = (event.status === -1) || (event.habboGroupId <= 0); - - newValue.groupId = clearGroup ? -1 : event.habboGroupId; - newValue.groupName = clearGroup ? null : event.habboGroupName; - newValue.groupBadgeId = clearGroup ? null : GetSessionDataManager().getGroupBadge(event.habboGroupId); - return newValue; - }); - }); - - useMessageEvent(RelationshipStatusInfoEvent, event => { - const parser = event.getParser(); - - if (!avatarInfo || avatarInfo.webID !== parser.userId) return; - - setRelationships(parser); - }); - - useEffect(() => { - setIsEditingMotto(false); - setMotto(avatarInfo.motto); - setBackgroundId(avatarInfo.backgroundId); - setStandId(avatarInfo.standId); - setOverlayId(avatarInfo.overlayId); - setCardBackgroundId(avatarInfo.cardBackgroundId ?? 0); - - SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID)); - - return () => { - setRelationships(null); + roomSession.sendMottoMessage(motto); + setIsEditingMotto(false); }; - }, [avatarInfo]); - if (!avatarInfo) return null; + const onMottoBlur = (event: FocusEvent) => saveMotto(event.target.value); - return ( - <> - - -
-
-
- - -
- -
-
-
-
-
- - - - - - {avatarInfo.type === AvatarInfoUser.OWN_USER && ( - - )} - - { (() => { - const maxSlots = GetConfigurationValue('user.badges.max.slots', 5); - const isOwnUser = avatarInfo.type === AvatarInfoUser.OWN_USER; - const showGroup = maxSlots <= 5; + const onMottoKeyDown = (event: KeyboardEvent) => + { + event.stopPropagation(); - const items: React.ReactNode[] = []; - items.push(); + switch (event.key) + { + case 'Enter': + saveMotto((event.target as HTMLInputElement).value); + return; + } + }; - if(showGroup) { - items.push( - 0} onClick={event => GetGroupInformation(avatarInfo.groupId)}> - {avatarInfo.groupId > 0 && } - - ); - } else { - items.push(); - } + useNitroEvent(RoomSessionUserBadgesEvent.RSUBE_BADGES, event => + { + if (!avatarInfo || avatarInfo.webID !== event.userId) return; - const startIdx = showGroup ? 1 : 2; - for(let i = startIdx; i < maxSlots; i++) { - items.push(); - } + // Deduplicate badges from server + const seen = new Set(); + const dedupedBadges = event.badges.map(code => + { + if (!code || seen.has(code)) return ''; + seen.add(code); + return code; + }); - const rows: React.ReactNode[][] = []; - for(let i = 0; i < items.length; i += 2) { - rows.push(items.slice(i, i + 2)); - } + const oldBadges = avatarInfo.badges.join(''); - return rows.map((row, idx) => ( - {row} - )); - })() } - -
-
-
-
- - {avatarInfo.type !== AvatarInfoUser.OWN_USER && ( - - {motto} - - )} - {avatarInfo.type === AvatarInfoUser.OWN_USER && ( - - - - {!isEditingMotto && ( - setIsEditingMotto(true)}> - {motto}  - + if (oldBadges === dedupedBadges.join('')) return; + + setAvatarInfo(prevValue => + { + if (!prevValue) return prevValue; + + const newValue = CloneObject(prevValue); + newValue.badges = dedupedBadges; + return newValue; + }); + }); + + useNitroEvent(RoomSessionUserFigureUpdateEvent.USER_FIGURE, event => + { + if (!avatarInfo || avatarInfo.roomIndex !== event.roomIndex) return; + + setAvatarInfo(prevValue => + { + if (!prevValue) return prevValue; + + const newValue = CloneObject(prevValue); + newValue.figure = event.figure; + newValue.motto = event.customInfo; + newValue.achievementScore = event.activityPoints; + newValue.nickIcon = event.nickIcon; + newValue.prefixText = event.prefixText; + newValue.prefixColor = event.prefixColor; + newValue.prefixIcon = event.prefixIcon; + newValue.prefixEffect = event.prefixEffect; + newValue.displayOrder = event.displayOrder; + newValue.backgroundId = event.backgroundId; + newValue.standId = event.standId; + newValue.overlayId = event.overlayId; + newValue.cardBackgroundId = event.cardBackgroundId ?? 0; + return newValue; + }); + }); + + useNitroEvent(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, event => + { + if (!avatarInfo || avatarInfo.roomIndex !== event.roomIndex) return; + + setAvatarInfo(prevValue => + { + if (!prevValue) return prevValue; + + const newValue = CloneObject(prevValue); + const clearGroup = (event.status === -1) || (event.habboGroupId <= 0); + + newValue.groupId = clearGroup ? -1 : event.habboGroupId; + newValue.groupName = clearGroup ? null : event.habboGroupName; + newValue.groupBadgeId = clearGroup ? null : GetSessionDataManager().getGroupBadge(event.habboGroupId); + return newValue; + }); + }); + + useMessageEvent(RelationshipStatusInfoEvent, event => + { + const parser = event.getParser(); + + if (!avatarInfo || avatarInfo.webID !== parser.userId) return; + + setRelationships(parser); + }); + + useEffect(() => + { + setIsEditingMotto(false); + setMotto(avatarInfo.motto); + setBackgroundId(avatarInfo.backgroundId); + setStandId(avatarInfo.standId); + setOverlayId(avatarInfo.overlayId); + setCardBackgroundId(avatarInfo.cardBackgroundId ?? 0); + + SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID)); + + return () => + { + setRelationships(null); + }; + }, [avatarInfo]); + + if (!avatarInfo) return null; + + return ( + <> + + +
+
+
+ + +
+ +
+
+
+
+
+ + + + + + {avatarInfo.type === AvatarInfoUser.OWN_USER && ( + + )} + + { (() => + { + const maxSlots = GetConfigurationValue('user.badges.max.slots', 5); + const isOwnUser = avatarInfo.type === AvatarInfoUser.OWN_USER; + const showGroup = maxSlots <= 5; + + const items: React.ReactNode[] = []; + items.push(); + + if(showGroup) + { + items.push( + 0} onClick={event => GetGroupInformation(avatarInfo.groupId)}> + {avatarInfo.groupId > 0 && } + + ); + } + else + { + items.push(); + } + + const startIdx = showGroup ? 1 : 2; + for(let i = startIdx; i < maxSlots; i++) + { + items.push(); + } + + const rows: React.ReactNode[][] = []; + for(let i = 0; i < items.length; i += 2) + { + rows.push(items.slice(i, i + 2)); + } + + return rows.map((row, idx) => ( + {row} + )); + })() } + +
+
+
+
+ + {avatarInfo.type !== AvatarInfoUser.OWN_USER && ( + + {motto} + + )} + {avatarInfo.type === AvatarInfoUser.OWN_USER && ( + + + + {!isEditingMotto && ( + setIsEditingMotto(true)}> + {motto} + + )} + {isEditingMotto && ( + ('motto.max.length', 38)} + type="text" + value={motto} + onBlur={onMottoBlur} + onChange={event => setMotto(event.target.value)} + onKeyDown={onMottoKeyDown} + /> + )} + + + )} + +
+
+
+ + {LocalizeText('infostand.text.achievement_score') + ' ' + avatarInfo.achievementScore} + + {avatarInfo.carryItem > 0 && ( + <> +
+ + {LocalizeText('infostand.text.handitem', ['item'], [LocalizeText('handitem' + avatarInfo.carryItem)])} + + + )} +
+
+ +
+ {GetConfigurationValue('user.tags.enabled') && ( + + + )} - {isEditingMotto && ( - ('motto.max.length', 38)} - type="text" - value={motto} - onBlur={onMottoBlur} - onChange={event => setMotto(event.target.value)} - onKeyDown={onMottoKeyDown} - /> - )} -
-
- )} -
-
-
-
- - {LocalizeText('infostand.text.achievement_score') + ' ' + avatarInfo.achievementScore} - - {avatarInfo.carryItem > 0 && ( - <> -
- - {LocalizeText('infostand.text.handitem', ['item'], [LocalizeText('handitem' + avatarInfo.carryItem)])} - - - )} -
-
- -
- {GetConfigurationValue('user.tags.enabled') && ( - - +
- )} -
-
- {isVisible && avatarInfo.type === AvatarInfoUser.OWN_USER && ( -
- -
- )} - - ); + {isVisible && avatarInfo.type === AvatarInfoUser.OWN_USER && ( +
+ +
+ )} + + ); }; diff --git a/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx b/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx index ec089c3..15f2863 100644 --- a/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx +++ b/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx @@ -11,42 +11,42 @@ interface ChatInputStyleSelectorViewProps export const ChatInputStyleSelectorView: FC = props => { - const { chatStyleIds = null, selectChatStyleId = null } = props; - const [ selectorVisible, setSelectorVisible ] = useState(false); + const { chatStyleIds = null, selectChatStyleId = null } = props; + const [ selectorVisible, setSelectorVisible ] = useState(false); - const selectStyle = (styleId: number) => - { - selectChatStyleId(styleId); - setSelectorVisible(false); - }; + const selectStyle = (styleId: number) => + { + selectChatStyleId(styleId); + setSelectorVisible(false); + }; - return ( - - -
-
-
- - - - - - {chatStyleIds && chatStyleIds.length > 0 && chatStyleIds.map(styleId => ( - selectStyle(styleId)}> -
-
-
- - ))} - - - - - - - ); + return ( + + +
+
+
+ + + + + + {chatStyleIds && chatStyleIds.length > 0 && chatStyleIds.map(styleId => ( + selectStyle(styleId)}> +
+
+
+ + ))} + + + + + + + ); }; diff --git a/src/components/room/widgets/chat-input/ChatInputView.tsx b/src/components/room/widgets/chat-input/ChatInputView.tsx index 4059eef..9aa9491 100644 --- a/src/components/room/widgets/chat-input/ChatInputView.tsx +++ b/src/components/room/widgets/chat-input/ChatInputView.tsx @@ -284,7 +284,10 @@ export const ChatInputView: FC<{}> = props => { setChatValue(':' + cmd.key + ' '); inputRef.current?.focus(); } } + onSelect={ (cmd) => + { + setChatValue(':' + cmd.key + ' '); inputRef.current?.focus(); + } } onHover={ setSelectedIndex } /> }
diff --git a/src/components/room/widgets/choosers/ChooserWidgetView.tsx b/src/components/room/widgets/choosers/ChooserWidgetView.tsx index e144f8d..6fde03f 100644 --- a/src/components/room/widgets/choosers/ChooserWidgetView.tsx +++ b/src/components/room/widgets/choosers/ChooserWidgetView.tsx @@ -69,7 +69,7 @@ export const ChooserWidgetView: FC = props => chooserSelectionVisualizer.clearAll(); } } - } + }; const isChecked = (id: number) => checkedIds.includes(id); @@ -80,7 +80,7 @@ export const ChooserWidgetView: FC = props => setCheckAll(false); chooserSelectionVisualizer.clearAll(); setSelectedItems([]); - } + }; const filteredItems = useMemo(() => { @@ -179,7 +179,10 @@ export const ChooserWidgetView: FC = props => alignItems="center" className={ classNames('rounded p-1', selectedItems.some(item => item.id === row.id) && 'bg-muted') } pointer - onClick={ () => { toggleItemSelection(row); if(pickallFurni) checkedId(row.id); } } + onClick={ () => + { + toggleItemSelection(row); if(pickallFurni) checkedId(row.id); + } } > { pickallFurni && ( = props => type="checkbox" checked={ isChecked(row.id) } onChange={ () => checkedId(row.id) } - onClick={ e => { e.stopPropagation(); toggleItemSelection(row); } } + onClick={ e => + { + e.stopPropagation(); toggleItemSelection(row); + } } /> )} diff --git a/src/components/room/widgets/context-menu/ContextMenuView.tsx b/src/components/room/widgets/context-menu/ContextMenuView.tsx index f7bc10b..c45865f 100644 --- a/src/components/room/widgets/context-menu/ContextMenuView.tsx +++ b/src/components/room/widgets/context-menu/ContextMenuView.tsx @@ -20,133 +20,146 @@ const FADE_LENGTH = 75; const SPACE_AROUND_EDGES = 10; export const ContextMenuView: FC = ({ - objectId = -1, - category = -1, - userType = -1, - fades = false, - onClose, - classNames = [], - style = {}, - children = null, - collapsable = false, - ...rest -}) => { - const [pos, setPos] = useState<{ x: number; y: number }>({ x: null, y: null }); - const [opacity, setOpacity] = useState(1); - const [isFading, setIsFading] = useState(false); - const [isCollapsed, setIsCollapsed] = useState(false); - const elementRef = useRef(null); - const stackRef = useRef(new FixedSizeStack(LOCATION_STACK_SIZE)); - const maxStackRef = useRef(-1000000); + objectId = -1, + category = -1, + userType = -1, + fades = false, + onClose, + classNames = [], + style = {}, + children = null, + collapsable = false, + ...rest +}) => +{ + const [pos, setPos] = useState<{ x: number; y: number }>({ x: null, y: null }); + const [opacity, setOpacity] = useState(1); + const [isFading, setIsFading] = useState(false); + const [isCollapsed, setIsCollapsed] = useState(false); + const elementRef = useRef(null); + const stackRef = useRef(new FixedSizeStack(LOCATION_STACK_SIZE)); + const maxStackRef = useRef(-1000000); - const updatePosition = useCallback( - (bounds: NitroRectangle, location: { x: number; y: number }) => { - if (!bounds || !location || !elementRef.current) return; + const updatePosition = useCallback( + (bounds: NitroRectangle, location: { x: number; y: number }) => + { + if (!bounds || !location || !elementRef.current) return; - let offset = -elementRef.current.offsetHeight; - if (userType > -1 && [RoomObjectType.USER, RoomObjectType.BOT, RoomObjectType.RENTABLE_BOT].includes(userType)) { - offset += bounds.height > 50 ? 15 : 0; - } else { - offset -= 14; - } + let offset = -elementRef.current.offsetHeight; + if (userType > -1 && [RoomObjectType.USER, RoomObjectType.BOT, RoomObjectType.RENTABLE_BOT].includes(userType)) + { + offset += bounds.height > 50 ? 15 : 0; + } + else + { + offset -= 14; + } - stackRef.current.addValue(location.y - bounds.top); - let maxStack = stackRef.current.getMax(); - if (maxStack < maxStackRef.current - BUBBLE_DROP_SPEED) { - maxStack = maxStackRef.current - BUBBLE_DROP_SPEED; - } - maxStackRef.current = maxStack; + stackRef.current.addValue(location.y - bounds.top); + let maxStack = stackRef.current.getMax(); + if (maxStack < maxStackRef.current - BUBBLE_DROP_SPEED) + { + maxStack = maxStackRef.current - BUBBLE_DROP_SPEED; + } + maxStackRef.current = maxStack; - const deltaY = location.y - maxStack; - let x = Math.round(location.x - elementRef.current.offsetWidth / 2); - let y = Math.round(deltaY + offset); + const deltaY = location.y - maxStack; + let x = Math.round(location.x - elementRef.current.offsetWidth / 2); + let y = Math.round(deltaY + offset); - const stage = GetStage(); - const maxLeft = stage.width - elementRef.current.offsetWidth - SPACE_AROUND_EDGES; - const maxTop = stage.height - elementRef.current.offsetHeight - SPACE_AROUND_EDGES; + const stage = GetStage(); + const maxLeft = stage.width - elementRef.current.offsetWidth - SPACE_AROUND_EDGES; + const maxTop = stage.height - elementRef.current.offsetHeight - SPACE_AROUND_EDGES; - x = Math.max(SPACE_AROUND_EDGES, Math.min(x, maxLeft)); - y = Math.max(SPACE_AROUND_EDGES, Math.min(y, maxTop)); + x = Math.max(SPACE_AROUND_EDGES, Math.min(x, maxLeft)); + y = Math.max(SPACE_AROUND_EDGES, Math.min(y, maxTop)); - setPos({ x, y }); - }, - [userType] - ); + setPos({ x, y }); + }, + [userType] + ); - const getClassNames = useMemo(() => { - const classes = [ - 'nitro-context-menu', - 'p-[2px]!', - 'bg-[#1c323f]', - 'border-2', - 'border-[solid]', - 'border-[rgba(255,255,255,.5)]', - 'rounded-[.25rem]', - 'text-[.7875rem]', + const getClassNames = useMemo(() => + { + const classes = [ + 'nitro-context-menu', + 'p-[2px]!', + 'bg-[#1c323f]', + 'border-2', + 'border-[solid]', + 'border-[rgba(255,255,255,.5)]', + 'rounded-[.25rem]', + 'text-[.7875rem]', 'text-white', - 'z-40', - 'pointer-events-auto', - 'absolute', - pos.x !== null ? 'visible' : 'invisible', - ]; - if (isCollapsed) classes.push('menu-hidden'); - return [...classes, ...classNames]; - }, [pos.x, isCollapsed, classNames]); + 'z-40', + 'pointer-events-auto', + 'absolute', + pos.x !== null ? 'visible' : 'invisible', + ]; + if (isCollapsed) classes.push('menu-hidden'); + return [...classes, ...classNames]; + }, [pos.x, isCollapsed, classNames]); - const getStyle = useMemo( - () => ({ - left: pos.x ?? 0, - top: pos.y ?? 0, - transition: isFading ? 'opacity 75ms linear' : undefined, - opacity, - ...style, - }), - [pos, opacity, isFading, style] - ); + const getStyle = useMemo( + () => ({ + left: pos.x ?? 0, + top: pos.y ?? 0, + transition: isFading ? 'opacity 75ms linear' : undefined, + opacity, + ...style, + }), + [pos, opacity, isFading, style] + ); - useEffect(() => { - if (!elementRef.current) return; + useEffect(() => + { + if (!elementRef.current) return; - const update = () => { - if (!elementRef.current) return; - const roomSession = GetRoomSession(); + const update = () => + { + if (!elementRef.current) return; + const roomSession = GetRoomSession(); - if (!roomSession) { - onClose(); - return; - } + if (!roomSession) + { + onClose(); + return; + } - const bounds = GetRoomObjectBounds(roomSession.roomId, objectId, category); - const location = GetRoomObjectScreenLocation(roomSession.roomId, objectId, category); - updatePosition(bounds, location); - }; + const bounds = GetRoomObjectBounds(roomSession.roomId, objectId, category); + const location = GetRoomObjectScreenLocation(roomSession.roomId, objectId, category); + updatePosition(bounds, location); + }; - const ticker = GetTicker(); - ticker.add(update); + const ticker = GetTicker(); + ticker.add(update); - return () => ticker.remove(update); - }, [objectId, category, updatePosition, onClose]); + return () => ticker.remove(update); + }, [objectId, category, updatePosition, onClose]); - useEffect(() => { - if (!fades) return; + useEffect(() => + { + if (!fades) return; - const timeout = setTimeout(() => { - setIsFading(true); - setTimeout(onClose, FADE_LENGTH); - }, FADE_DELAY); + const timeout = setTimeout(() => + { + setIsFading(true); + setTimeout(onClose, FADE_LENGTH); + }, FADE_DELAY); - return () => clearTimeout(timeout); - }, [fades, onClose]); + return () => clearTimeout(timeout); + }, [fades, onClose]); - useEffect(() => { - if (!isFading) return; - setOpacity(0); - }, [isFading]); + useEffect(() => + { + if (!isFading) return; + setOpacity(0); + }, [isFading]); - return ( -
- {!(collapsable && isCollapsed) && children} - {collapsable && setIsCollapsed((prev) => !prev)} />} -
- ); + return ( +
+ {!(collapsable && isCollapsed) && children} + {collapsable && setIsCollapsed((prev) => !prev)} />} +
+ ); }; diff --git a/src/components/room/widgets/furniture/FurnitureExternalImageView.tsx b/src/components/room/widgets/furniture/FurnitureExternalImageView.tsx index 7fe070c..0ee52cf 100644 --- a/src/components/room/widgets/furniture/FurnitureExternalImageView.tsx +++ b/src/components/room/widgets/furniture/FurnitureExternalImageView.tsx @@ -4,16 +4,19 @@ import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../ import { useFurnitureExternalImageWidget, useHelp } from '../../../../hooks'; import { CameraWidgetShowPhotoView } from '../../../camera/views/CameraWidgetShowPhotoView'; -export const FurnitureExternalImageView: FC<{}> = props => { +export const FurnitureExternalImageView: FC<{}> = props => +{ const { objectId = -1, currentPhotoIndex = -1, currentPhotos = null, onClose = null } = useFurnitureExternalImageWidget(); const { report = null } = useHelp(); if (objectId === -1 || currentPhotoIndex === -1) return null; - const handleOpenFullPhoto = () => { + const handleOpenFullPhoto = () => + { const photoUrl = currentPhotos[currentPhotoIndex].w.replace('_small.png', '.png'); - if (photoUrl) { - console.log("Opened photo URL:", photoUrl); + if (photoUrl) + { + console.log('Opened photo URL:', photoUrl); window.open(photoUrl, '_blank'); } }; diff --git a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx index 5105cf5..759835c 100644 --- a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx +++ b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx @@ -7,7 +7,8 @@ import { Text } from '../../../../common'; import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks'; import { getRegisteredPlugins, INitroPlugin, subscribePlugins } from '../../../plugins/NitroPluginApi'; -export const RoomToolsWidgetView: FC<{}> = props => { +export const RoomToolsWidgetView: FC<{}> = props => +{ const [areBubblesMuted, setAreBubblesMuted] = useState(false); const [isZoomedIn, setIsZoomedIn] = useState(false); const [roomName, setRoomName] = useState(null); @@ -27,19 +28,25 @@ export const RoomToolsWidgetView: FC<{}> = props => { return subscribePlugins(() => setPlugins(getRegisteredPlugins())); }, []); - const handleToolClick = (action: string, value?: string) => { - if (!roomSession) return; + const handleToolClick = (action: string, value?: string) => + { + if (!roomSession) return; - switch (action) { + switch (action) + { case 'settings': CreateLinkEvent('navigator/toggle-room-info'); return; case 'zoom': - setIsZoomedIn(prevValue => { - if (GetConfigurationValue('room.zoom.enabled', true)) { + setIsZoomedIn(prevValue => + { + if (GetConfigurationValue('room.zoom.enabled', true)) + { const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1); GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale === 1 ? 0.5 : 1); - } else { + } + else + { const geometry = GetRoomEngine().getRoomInstanceGeometry(roomSession.roomId, 1); if (geometry) geometry.performZoom(); } @@ -77,7 +84,8 @@ export const RoomToolsWidgetView: FC<{}> = props => { } }; - const onChangeRoomHistory = (roomId: number, roomName: string) => { + const onChangeRoomHistory = (roomId: number, roomName: string) => + { let newStorage = JSON.parse(window.localStorage.getItem('nitro.room.history') || '[]'); if (newStorage.some((room: { roomId: number }) => room.roomId === roomId)) return; @@ -88,7 +96,8 @@ export const RoomToolsWidgetView: FC<{}> = props => { SetLocalStorage('nitro.room.history', newStorage); }; - useMessageEvent(GetGuestRoomResultEvent, event => { + useMessageEvent(GetGuestRoomResultEvent, event => + { const parser = event.getParser(); if (!parser.roomEnter || (parser.data.roomId !== roomSession.roomId)) return; @@ -98,18 +107,22 @@ export const RoomToolsWidgetView: FC<{}> = props => { onChangeRoomHistory(parser.data.roomId, parser.data.roomName); }); - useEffect(() => { + useEffect(() => + { setIsOpen(true); const timeout = setTimeout(() => setIsOpen(false), 5000); return () => clearTimeout(timeout); }, [roomName, roomOwner, roomTags]); - useEffect(() => { + useEffect(() => + { setRoomHistory(JSON.parse(window.localStorage.getItem('nitro.room.history') || '[]')); }, []); - useEffect(() => { - const handleTabClose = () => { + useEffect(() => + { + const handleTabClose = () => + { window.localStorage.removeItem('nitro.room.history'); }; window.addEventListener('beforeunload', handleTabClose); @@ -119,10 +132,10 @@ export const RoomToolsWidgetView: FC<{}> = props => { return (
-
handleToolClick('settings')} /> +
handleToolClick('settings')} />
handleToolClick('zoom')} />
handleToolClick('chat_history')} /> -
handleToolClick('hiddenbubbles')} /> +
handleToolClick('hiddenbubbles')} /> {navigatorData.canRate && (
handleToolClick('like_room')} /> diff --git a/src/components/toolbar/ToolbarView.tsx b/src/components/toolbar/ToolbarView.tsx index c06e5e9..6caac21 100644 --- a/src/components/toolbar/ToolbarView.tsx +++ b/src/components/toolbar/ToolbarView.tsx @@ -203,7 +203,10 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props => } - { setMeExpanded(value => !value); event.stopPropagation(); } }> + + { + setMeExpanded(value => !value); event.stopPropagation(); + } }> { (getTotalUnseen > 0) && @@ -239,20 +242,20 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props => exit={ { opacity: 0, x: 10 } } transition={ { type: 'spring', stiffness: 300, damping: 28 } } className={ `fixed bottom-0 z-40 h-[52px] max-w-[calc(50vw-242px)] items-center overflow-visible pr-3 pointer-events-auto ${ desktopFlexClasses } ${ isInRoom ? 'right-0' : 'right-3' }` }> - - - CreateLinkEvent('friends/toggle') } className="tb-icon" /> - { (requests.length > 0) && + + + CreateLinkEvent('friends/toggle') } className="tb-icon" /> + { (requests.length > 0) && } - - { ((iconState === MessengerIconState.SHOW) || (iconState === MessengerIconState.UNREAD)) && + + { ((iconState === MessengerIconState.SHOW) || (iconState === MessengerIconState.UNREAD)) && OpenMessengerChat() } /> } -
-
- +
+
+ = props => className="pointer-events-auto absolute bottom-[calc(100%+10px)] left-1/2 z-[70] -translate-x-1/2"> } - - { setMeExpanded(value => !value); event.stopPropagation(); } }> - - - { (getTotalUnseen > 0) && - } + + + { + setMeExpanded(value => !value); event.stopPropagation(); + } }> + + { (getTotalUnseen > 0) && + } + { (isInRoom && showToolbarButton) && diff --git a/src/components/toolbar/YouTubePlayerView.tsx b/src/components/toolbar/YouTubePlayerView.tsx index 5f1c89c..c95a4c0 100644 --- a/src/components/toolbar/YouTubePlayerView.tsx +++ b/src/components/toolbar/YouTubePlayerView.tsx @@ -1,31 +1,34 @@ -import { ControlYoutubeDisplayPlaybackMessageComposer, YouTubeRoomBroadcastEvent, YouTubeRoomPlayComposer, YouTubeRoomSettingsEvent, YouTubeRoomWatchersEvent, YouTubeRoomWatchingComposer } from "@nitrots/nitro-renderer"; -import { FC, useEffect, useRef, useState } from "react"; -import ReactPlayer from "react-player/youtube"; -import { GetRoomSession, getYoutubeRoomEnabled, GetSessionDataManager, LocalizeText, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from "../../api"; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView, LayoutAvatarImageView } from "../../common"; -import { useFurnitureYoutubeWidget, useMessageEvent } from "../../hooks"; +import { ControlYoutubeDisplayPlaybackMessageComposer, YouTubeRoomBroadcastEvent, YouTubeRoomPlayComposer, YouTubeRoomSettingsEvent, YouTubeRoomWatchersEvent, YouTubeRoomWatchingComposer } from '@nitrots/nitro-renderer'; +import { FC, useEffect, useRef, useState } from 'react'; +import ReactPlayer from 'react-player/youtube'; +import { GetRoomSession, getYoutubeRoomEnabled, GetSessionDataManager, LocalizeText, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from '../../api'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView, LayoutAvatarImageView } from '../../common'; +import { useFurnitureYoutubeWidget, useMessageEvent } from '../../hooks'; const CONTROL_COMMAND_PREVIOUS_VIDEO = 0; const CONTROL_COMMAND_NEXT_VIDEO = 1; const CONTROL_COMMAND_PAUSE_VIDEO = 2; const CONTROL_COMMAND_CONTINUE_VIDEO = 3; -const extractVideoId = (input: string): string => { +const extractVideoId = (input: string): string => +{ const patterns = [ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/|youtube\.com\/shorts\/)([a-zA-Z0-9_-]{11})/, /^([a-zA-Z0-9_-]{11})$/, ]; - for (const pattern of patterns) { + for (const pattern of patterns) + { const match = input.match(pattern); if (match) return match[1]; } return input; }; -export const YouTubePlayerView: FC<{}> = () => { +export const YouTubePlayerView: FC<{}> = () => +{ const [isOpen, setIsOpen] = useState(false); - const [tab, setTab] = useState< | "player" | "playlist" | "spectators" | "settings" | "history" | "share" >("player"); - const [inputValue, setInputValue] = useState(""); + const [tab, setTab] = useState< | 'player' | 'playlist' | 'spectators' | 'settings' | 'history' | 'share' >('player'); + const [inputValue, setInputValue] = useState(''); const [isRoomMode, setIsRoomMode] = useState(false); const [volume, setVolume] = useState(100); const [isMuted, setIsMuted] = useState(false); @@ -38,121 +41,174 @@ export const YouTubePlayerView: FC<{}> = () => { const playerRef = useRef(null); const { objectId: youtubeObjectId, videoId: roomVideoId, currentVideoState, hasControl } = useFurnitureYoutubeWidget(); const [spectators, setSpectators] = useState< { id: number; name: string; look: string }[] >([]); - const [broadcastVideo, setBroadcastVideo] = useState(""); - const [broadcastSender, setBroadcastSender] = useState(""); + const [broadcastVideo, setBroadcastVideo] = useState(''); + const [broadcastSender, setBroadcastSender] = useState(''); const [broadcastPlaylist, setBroadcastPlaylist] = useState([]); const [watcherIds, setWatcherIds] = useState>(new Set()); const [youtubeEnabled, setYoutubeEnabled] = useState(getYoutubeRoomEnabled()); - useMessageEvent(YouTubeRoomSettingsEvent, event => { + useMessageEvent(YouTubeRoomSettingsEvent, event => + { setYoutubeEnabled(event.getParser().youtubeEnabled); }); - useMessageEvent(YouTubeRoomBroadcastEvent, event => { + useMessageEvent(YouTubeRoomBroadcastEvent, event => + { const parser = event.getParser(); setBroadcastVideo(parser.videoId); setBroadcastSender(parser.senderName); setBroadcastPlaylist(parser.playlist); - if (parser.videoId) { + if (parser.videoId) + { setInputValue(parser.videoId); setIsOpen(true); - setTab("player"); - } else { - setInputValue(""); - setBroadcastVideo(""); - setBroadcastSender(""); + setTab('player'); + } + else + { + setInputValue(''); + setBroadcastVideo(''); + setBroadcastSender(''); setBroadcastPlaylist([]); } }); - useMessageEvent(YouTubeRoomWatchersEvent, event => { setWatcherIds(new Set(event.getParser().watcherIds)); loadRoomUsers(); }); + useMessageEvent(YouTubeRoomWatchersEvent, event => + { + setWatcherIds(new Set(event.getParser().watcherIds)); loadRoomUsers(); + }); const sentWatchingRef = useRef(false); const hasVideo = !!(inputValue && extractVideoId(inputValue)); - useEffect(() => { - if (isOpen && hasVideo && !sentWatchingRef.current) { - try { SendMessageComposer(new YouTubeRoomWatchingComposer(true)); } catch(e) {} + useEffect(() => + { + if (isOpen && hasVideo && !sentWatchingRef.current) + { + try + { + SendMessageComposer(new YouTubeRoomWatchingComposer(true)); + } + catch(e) + {} sentWatchingRef.current = true; - } else if ((!isOpen || !hasVideo) && sentWatchingRef.current) { - try { SendMessageComposer(new YouTubeRoomWatchingComposer(false)); } catch(e) {} + } + else if ((!isOpen || !hasVideo) && sentWatchingRef.current) + { + try + { + SendMessageComposer(new YouTubeRoomWatchingComposer(false)); + } + catch(e) + {} sentWatchingRef.current = false; } }, [isOpen, hasVideo]); - const loadRoomUsers = () => { - try { + const loadRoomUsers = () => + { + try + { const roomSession = GetRoomSession(); - if (!roomSession) { setSpectators([]); return; } + if (!roomSession) + { + setSpectators([]); return; + } const users: { id: number; name: string; look: string }[] = []; const seen = new Set(); - for (let i = 0; i < 500; i++) { + for (let i = 0; i < 500; i++) + { const userData = roomSession.userDataManager.getUserDataByIndex(i); - if (userData && userData.name && userData.type === 1 && !seen.has(userData.userId)) { + if (userData && userData.name && userData.type === 1 && !seen.has(userData.userId)) + { seen.add(userData.userId); users.push({ id: userData.userId, name: userData.name, look: userData.figure }); } } setSpectators(users); - } catch (e) { + } + catch (e) + { setSpectators([]); } }; - useEffect(() => { + useEffect(() => + { if (isOpen) loadRoomUsers(); }, [isOpen]); - useEffect(() => { - if (youtubeObjectId && youtubeObjectId !== -1) { + useEffect(() => + { + if (youtubeObjectId && youtubeObjectId !== -1) + { setIsRoomMode(true); - if (roomVideoId) { + if (roomVideoId) + { setInputValue(roomVideoId); } - } else { + } + else + { setIsRoomMode(false); } }, [youtubeObjectId, roomVideoId]); - useEffect(() => { + useEffect(() => + { const handler = () => setIsOpen((p) => !p); - window.addEventListener("youtube:toggle", handler); - return () => window.removeEventListener("youtube:toggle", handler); + window.addEventListener('youtube:toggle', handler); + return () => window.removeEventListener('youtube:toggle', handler); }, []); - useEffect(() => { - const savedHistory = localStorage.getItem("youtube_history"); - if (savedHistory) { - try { + useEffect(() => + { + const savedHistory = localStorage.getItem('youtube_history'); + if (savedHistory) + { + try + { const parsed = JSON.parse(savedHistory); - if (Array.isArray(parsed)) { - setHistory(parsed.map((entry: any) => typeof entry === "string" ? entry : entry?.id).filter(Boolean)); + if (Array.isArray(parsed)) + { + setHistory(parsed.map((entry: any) => typeof entry === 'string' ? entry : entry?.id).filter(Boolean)); } - } catch (e) {} + } + catch (e) + {} } - const savedPlaylist = localStorage.getItem("youtube_playlist"); - if (savedPlaylist) { - try { + const savedPlaylist = localStorage.getItem('youtube_playlist'); + if (savedPlaylist) + { + try + { const parsed = JSON.parse(savedPlaylist); - if (Array.isArray(parsed)) { - setPlaylist(parsed.map((entry: any) => typeof entry === "string" ? entry : entry?.id).filter(Boolean)); + if (Array.isArray(parsed)) + { + setPlaylist(parsed.map((entry: any) => typeof entry === 'string' ? entry : entry?.id).filter(Boolean)); } - } catch (e) {} + } + catch (e) + {} } }, []); - useEffect(() => { + useEffect(() => + { localStorage.setItem( - "youtube_history", + 'youtube_history', JSON.stringify(history.slice(0, 50)), ); }, [history]); - useEffect(() => { - localStorage.setItem("youtube_playlist", JSON.stringify(playlist)); + useEffect(() => + { + localStorage.setItem('youtube_playlist', JSON.stringify(playlist)); }, [playlist]); - const addToHistory = (id: string) => { + const addToHistory = (id: string) => + { if (!id) return; - setHistory((prev) => { + setHistory((prev) => + { const filtered = prev.filter((v) => v !== id); return [id, ...filtered].slice(0, 50); }); @@ -199,9 +255,11 @@ export const YouTubePlayerView: FC<{}> = () => { ), ); - const addToPlaylist = () => { + const addToPlaylist = () => + { const id = extractVideoId(inputValue); - if (id && !playlist.includes(id)) { + if (id && !playlist.includes(id)) + { setPlaylist((p) => [...p, id]); } }; @@ -222,11 +280,12 @@ export const YouTubePlayerView: FC<{}> = () => { label: string; }) => ( @@ -234,55 +293,58 @@ export const YouTubePlayerView: FC<{}> = () => { return ( setIsOpen(false)} />
{watcherIds.size > 0 && ( )}
- {tab === "player" && ( + {tab === 'player' && ( <> {isRoomMode && (
@@ -311,10 +373,13 @@ export const YouTubePlayerView: FC<{}> = () => { {videoId ? ( { playerRef.current = ref; }} + ref={ref => + { + playerRef.current = ref; + }} url={`https://www.youtube.com/watch?v=${videoId}`} width="100%" - height={isFullscreen ? "100%" : 280} + height={isFullscreen ? '100%' : 280} playing muted={isMuted} loop={isLooping} @@ -347,7 +412,7 @@ export const YouTubePlayerView: FC<{}> = () => { } className="px-4 py-1 bg-amber-600 rounded text-white font-bold text-sm" > - {isPlaying ? "⏸" : "â–ļ"} + {isPlaying ? '⏸' : 'â–ļ'}
)} - {tab === "history" && ( + {tab === 'history' && (
@@ -501,9 +576,10 @@ export const YouTubePlayerView: FC<{}> = () => {
{ + onClick={() => + { setInputValue(id); - setTab("player"); + setTab('player'); }} >
@@ -516,7 +592,7 @@ export const YouTubePlayerView: FC<{}> = () => {
)} - {tab === "share" && ( + {tab === 'share' && (
@@ -532,7 +608,8 @@ export const YouTubePlayerView: FC<{}> = () => { className="flex-1 p-2 bg-gray-700 text-white rounded text-sm" />
)} - {tab === "spectators" && (() => { + {tab === 'spectators' && (() => + { const watchers: { id: number; name: string; look: string }[] = []; const rs = GetRoomSession(); - if (rs) { - for (const uid of watcherIds) { + if (rs) + { + for (const uid of watcherIds) + { const ud = rs.userDataManager.getUserData(uid); - if (ud && ud.name) { + if (ud && ud.name) + { watchers.push({ id: ud.userId, name: ud.name, look: ud.figure }); } } } return ( -
-
-
+
+
+
đŸ“ē {watchers.length} watching -
-
+ -
- {watchers.length === 0 ? ( -
+ +
+ {watchers.length === 0 ? ( +
No one is watching -
- ) : ( -
- {watchers.map((user) => ( -
-
- +
+ ) : ( +
+ {watchers.map((user) => ( +
+
+ +
+ + {user.name} + + đŸ“ē
- - {user.name} - - đŸ“ē -
- ))} -
- )} -
+ ))} +
+ )} +
); })()} - {tab === "settings" && ( + {tab === 'settings' && (
@@ -636,7 +719,7 @@ export const YouTubePlayerView: FC<{}> = () => { } className="text-gray-400 text-xs" > - {showVolumeSlider ? "â–ŧ" : "▲"} + {showVolumeSlider ? 'â–ŧ' : '▲'}
{showVolumeSlider && ( @@ -645,7 +728,8 @@ export const YouTubePlayerView: FC<{}> = () => { min="0" max="100" value={volume} - onChange={(e) => { + onChange={(e) => + { setVolume(parseInt(e.target.value)); setVolumePreset( parseInt(e.target.value), @@ -702,19 +786,19 @@ export const YouTubePlayerView: FC<{}> = () => {
â„šī¸ Info
- 📡 Broadcast:{" "} + 📡 Broadcast:{' '} {broadcastVideo ? ✓ Active ({broadcastSender} playing) : ✕ No video}
- 🎮 Controle:{" "} + 🎮 Controle:{' '} {isMyRoom ? ✓ You are the owner : ✕ Viewing only}
- đŸ‘ī¸ Viewers:{" "} + đŸ‘ī¸ Viewers:{' '} {watcherIds.size}
diff --git a/src/components/wired-tools/WiredCreatorToolsView.tsx b/src/components/wired-tools/WiredCreatorToolsView.tsx index b2279db..86c57ff 100644 --- a/src/components/wired-tools/WiredCreatorToolsView.tsx +++ b/src/components/wired-tools/WiredCreatorToolsView.tsx @@ -341,20 +341,20 @@ const VARIABLES_ELEMENTS: VariablesElementButton[] = [ const EDITABLE_FURNI_VARIABLES: string[] = [ '@position_x', '@position_y', '@rotation', '@altitude', '@state', '@wallitem_offset' ]; const EDITABLE_USER_VARIABLES: string[] = [ '@position_x', '@position_y', '@direction' ]; const createVariableDefinition = (key: string, target: 'Furni' | 'User' | 'Global' | 'Context', availability: string = 'Always', canWriteTo = false): VariableDefinition => -({ - key, - target, - type: 'Internal', - hasValue: true, - availability, - canWriteTo, - canCreateDelete: false, - canIntercept: false, - hasCreationTime: false, - hasUpdateTime: false, - isTextConnected: false, - isAlwaysAvailable: (availability === 'Always') -}); + ({ + key, + target, + type: 'Internal', + hasValue: true, + availability, + canWriteTo, + canCreateDelete: false, + canIntercept: false, + hasCreationTime: false, + hasUpdateTime: false, + isTextConnected: false, + isAlwaysAvailable: (availability === 'Always') + }); const VARIABLE_DEFINITIONS: Record = { furni: [ createVariableDefinition('~teleport.target_id', 'Furni', 'Conditional'), @@ -461,27 +461,27 @@ const DIRECTION_NAMES: string[] = [ 'North', 'North-East', 'East', 'South-East', const HOTEL_TIME_FORMATTERS: Map = new Map(); const createEmptyMonitorSnapshot = (): MonitorSnapshot => -({ - usageCurrentWindow: 0, - usageLimitPerWindow: 0, - isHeavy: false, - delayedEventsPending: 0, - delayedEventsLimit: 0, - averageExecutionMs: 0, - peakExecutionMs: 0, - recursionDepthCurrent: 0, - recursionDepthLimit: 0, - killedRemainingSeconds: 0, - usageWindowMs: 0, - overloadAverageThresholdMs: 0, - overloadPeakThresholdMs: 0, - heavyUsageThresholdPercent: 0, - heavyConsecutiveWindowsThreshold: 0, - overloadConsecutiveWindowsThreshold: 0, - heavyDelayedThresholdPercent: 0, - logs: [], - history: [] -}); + ({ + usageCurrentWindow: 0, + usageLimitPerWindow: 0, + isHeavy: false, + delayedEventsPending: 0, + delayedEventsLimit: 0, + averageExecutionMs: 0, + peakExecutionMs: 0, + recursionDepthCurrent: 0, + recursionDepthLimit: 0, + killedRemainingSeconds: 0, + usageWindowMs: 0, + overloadAverageThresholdMs: 0, + overloadPeakThresholdMs: 0, + heavyUsageThresholdPercent: 0, + heavyConsecutiveWindowsThreshold: 0, + overloadConsecutiveWindowsThreshold: 0, + heavyDelayedThresholdPercent: 0, + logs: [], + history: [] + }); const getHotelTimeFormatter = (timeZone: string): Intl.DateTimeFormat => { @@ -3245,7 +3245,7 @@ export const WiredCreatorToolsView: FC<{}> = () => switch(editingVariable) { - case '@position_x': { + case '@position_x': { const parsed = parseInt(editingValue.trim(), 10); if(Number.isNaN(parsed)) @@ -3257,7 +3257,7 @@ export const WiredCreatorToolsView: FC<{}> = () => nextX = parsed; break; } - case '@position_y': { + case '@position_y': { const parsed = parseInt(editingValue.trim(), 10); if(Number.isNaN(parsed)) @@ -3632,7 +3632,7 @@ export const WiredCreatorToolsView: FC<{}> = () => return ( <> - { isVariableHighlightActive && !!variableHighlightOverlays.length && + { isVariableHighlightActive && !!variableHighlightOverlays.length &&
{ variableHighlightOverlays.map(overlay => (
= () =>
)) }
} - - setIsVisible(false) } /> - - { TABS.map(tab => ( - setActiveTab(tab.key) }> - { tab.label } - - )) } - - + + setIsVisible(false) } /> + + { TABS.map(tab => ( + setActiveTab(tab.key) }> + { tab.label } + + )) } + + { (activeTab === 'monitor') &&
@@ -3682,7 +3682,7 @@ export const WiredCreatorToolsView: FC<{}> = () => Monitor preview
-
+
Logs:
@@ -3925,7 +3925,7 @@ export const WiredCreatorToolsView: FC<{}> = () => onChange={ event => setEditingValue(event.target.value) } onKeyDownCapture={ onVariableInputKeyDown } /> } { (editingVariable !== variable.key) && !variable.editable && { variable.value } } - { (editingVariable !== variable.key) && variable.editable && + { (editingVariable !== variable.key) && variable.editable && - + } - { !!selectedManagedVariableEntry && !!selectedVariableDefinition && + { !!selectedManagedVariableEntry && !!selectedVariableDefinition && setSelectedManagedVariableEntry(null) } /> @@ -4459,7 +4459,7 @@ export const WiredCreatorToolsView: FC<{}> = () => } - { !!selectedMonitorErrorInfo && + { !!selectedMonitorErrorInfo && -({ - key, - canUseAsDestination, - canUseAsReference -}); + ({ + key, + canUseAsDestination, + canUseAsReference + }); export const normalizeInternalVariableKey = (key: string) => { @@ -216,30 +216,30 @@ const getRootKey = (key: string) => }; const createInternalEntry = (target: WiredVariablePickerTarget, usage: WiredVariablePickerUsage, meta: IInternalVariableMeta): IWiredVariablePickerEntry => -({ - id: `${ INTERNAL_TOKEN_PREFIX }${ meta.key }`, - token: `${ INTERNAL_TOKEN_PREFIX }${ meta.key }`, - label: meta.key, - displayLabel: meta.key, - searchableText: meta.key, - selectable: getInternalSelectable(usage, meta), - hasValue: meta.canUseAsReference, - kind: 'internal', - target -}); + ({ + id: `${ INTERNAL_TOKEN_PREFIX }${ meta.key }`, + token: `${ INTERNAL_TOKEN_PREFIX }${ meta.key }`, + label: meta.key, + displayLabel: meta.key, + searchableText: meta.key, + selectable: getInternalSelectable(usage, meta), + hasValue: meta.canUseAsReference, + kind: 'internal', + target + }); const createCustomEntry = (target: WiredVariablePickerTarget, usage: WiredVariablePickerUsage, definition: IWiredVariableDefinitionLike): IWiredVariablePickerEntry => -({ - id: `${ CUSTOM_TOKEN_PREFIX }${ definition.itemId }`, - token: `${ CUSTOM_TOKEN_PREFIX }${ definition.itemId }`, - label: definition.name, - displayLabel: definition.name, - searchableText: definition.name, - selectable: getCustomSelectable(usage, definition), - hasValue: !!definition.hasValue, - kind: 'custom', - target -}); + ({ + id: `${ CUSTOM_TOKEN_PREFIX }${ definition.itemId }`, + token: `${ CUSTOM_TOKEN_PREFIX }${ definition.itemId }`, + label: definition.name, + displayLabel: definition.name, + searchableText: definition.name, + selectable: getCustomSelectable(usage, definition), + hasValue: !!definition.hasValue, + kind: 'custom', + target + }); const groupEntries = (entries: IWiredVariablePickerEntry[]) => { diff --git a/src/components/wired/views/actions/WiredActionFurniToFurniView.tsx b/src/components/wired/views/actions/WiredActionFurniToFurniView.tsx index a997fa9..609b217 100644 --- a/src/components/wired/views/actions/WiredActionFurniToFurniView.tsx +++ b/src/components/wired/views/actions/WiredActionFurniToFurniView.tsx @@ -211,6 +211,6 @@ export const WiredActionFurniToFurniView: FC<{}> = () => onSelectionActivate={ () => switchSelection('target') } /> } - /> + /> ); }; diff --git a/src/components/wired/views/actions/WiredActionGiveRewardView.tsx b/src/components/wired/views/actions/WiredActionGiveRewardView.tsx index 3fb239a..4286325 100644 --- a/src/components/wired/views/actions/WiredActionGiveRewardView.tsx +++ b/src/components/wired/views/actions/WiredActionGiveRewardView.tsx @@ -33,12 +33,12 @@ const REWARD_TYPES: { value: RewardType, label: string }[] = [ const SELECTABLE_REWARD_TYPES = REWARD_TYPES.filter(entry => (entry.value !== 'respect')); const createReward = (): RewardEntry => -({ - rewardType: 'furni', - rewardValue: '', - probability: DEFAULT_PROBABILITY, - pointsType: DEFAULT_POINTS_TYPE -}); + ({ + rewardType: 'furni', + rewardValue: '', + probability: DEFAULT_PROBABILITY, + pointsType: DEFAULT_POINTS_TYPE + }); const getRewardValuePlaceholder = (rewardType: RewardType) => { diff --git a/src/components/wired/views/actions/WiredActionSendSignalView.tsx b/src/components/wired/views/actions/WiredActionSendSignalView.tsx index f09264b..5485ace 100644 --- a/src/components/wired/views/actions/WiredActionSendSignalView.tsx +++ b/src/components/wired/views/actions/WiredActionSendSignalView.tsx @@ -40,13 +40,13 @@ const serializeForwardIds = (ids: number[]): string => export const WiredActionSendSignalView: FC<{}> = () => { - const [ furniSource, setFurniSource ] = useState(SOURCE_TRIGGER); - const [ userSource, setUserSource ] = useState(SOURCE_TRIGGER); + const [ furniSource, setFurniSource ] = useState(SOURCE_TRIGGER); + const [ userSource, setUserSource ] = useState(SOURCE_TRIGGER); const [ signalPerFurni, setSignalPerFurni ] = useState(false); - const [ signalPerUser, setSignalPerUser ] = useState(false); - const [ antennaIds, setAntennaIds ] = useState([]); + const [ signalPerUser, setSignalPerUser ] = useState(false); + const [ antennaIds, setAntennaIds ] = useState([]); const [ forwardFurniIds, setForwardFurniIds ] = useState([]); - const [ selectionMode, setSelectionMode ] = useState('antenna'); + const [ selectionMode, setSelectionMode ] = useState('antenna'); const highlightedIds = useRef([]); const { trigger = null, furniIds = [], setFurniIds = null, setIntParams = null, setStringParam = null } = useWired(); @@ -194,7 +194,8 @@ export const WiredActionSendSignalView: FC<{}> = () => selectionCount={ antennaIds.length } selectionLimit={ selectionLimit } selectionEnabledValues={ [ SOURCE_SELECTED ] } - onChange={ () => {} } + onChange={ () => + {} } onSelectionActivate={ () => switchSelection('antenna') } /> = () => onChange={ setUserSource } /> } - > + >
{ LocalizeText('wiredfurni.params.signal.options') }
diff --git a/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx b/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx index 2b8ed1c..7187ae9 100644 --- a/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx +++ b/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx @@ -221,7 +221,7 @@ export const WiredConditionFurniIsOfTypeView: FC switchSelection('secondary') } />
} - > + >
{ LocalizeText('wiredfurni.params.quantifier_selection') } { [ 0, 1 ].map(value => ( diff --git a/src/components/wired/views/extras/WiredExtraFilterByVariableView.tsx b/src/components/wired/views/extras/WiredExtraFilterByVariableView.tsx index a1f9494..8d496a1 100644 --- a/src/components/wired/views/extras/WiredExtraFilterByVariableView.tsx +++ b/src/components/wired/views/extras/WiredExtraFilterByVariableView.tsx @@ -127,7 +127,7 @@ export const WiredExtraFilterByVariableView: FC (entry.token === variableToken))) return mainEntries; - const fallbackEntry = createFallbackVariableEntry(target as WiredVariablePickerTarget, variableToken); + const fallbackEntry = createFallbackVariableEntry(target, variableToken); return fallbackEntry ? [ fallbackEntry, ...mainEntries ] : mainEntries; }, [ mainEntries, target, variableToken ]); diff --git a/src/components/wired/views/extras/WiredExtraTextInputVariableView.tsx b/src/components/wired/views/extras/WiredExtraTextInputVariableView.tsx index 41ac5e3..45e3c65 100644 --- a/src/components/wired/views/extras/WiredExtraTextInputVariableView.tsx +++ b/src/components/wired/views/extras/WiredExtraTextInputVariableView.tsx @@ -79,7 +79,7 @@ export const WiredExtraTextInputVariableView: FC<{}> = () => const itemId = getCustomVariableItemId(variableToken); - return (targetDefinitions.find(definition => (definition.itemId === itemId)) ?? null) as IVariableDefinition | null; + return (targetDefinitions.find(definition => (definition.itemId === itemId)) ?? null); }, [ targetDefinitions, variableToken ]); const canUseTextDisplay = !!selectedVariableDefinition?.isTextConnected; diff --git a/src/components/wired/views/selectors/WiredActionFurniAreaView.tsx b/src/components/wired/views/selectors/WiredActionFurniAreaView.tsx index 9eb8777..a80b3a6 100644 --- a/src/components/wired/views/selectors/WiredActionFurniAreaView.tsx +++ b/src/components/wired/views/selectors/WiredActionFurniAreaView.tsx @@ -101,7 +101,7 @@ export const WiredActionFurniAreaView: FC<{}> = props => : 0; return ( - +
{ LocalizeText('wiredfurni.params.area_selection') } { LocalizeText('wiredfurni.params.area_selection.info') } diff --git a/src/components/wired/views/selectors/WiredSelectorFurniByTypeView.tsx b/src/components/wired/views/selectors/WiredSelectorFurniByTypeView.tsx index 7ee4bff..d689b72 100644 --- a/src/components/wired/views/selectors/WiredSelectorFurniByTypeView.tsx +++ b/src/components/wired/views/selectors/WiredSelectorFurniByTypeView.tsx @@ -4,13 +4,13 @@ import { Text } from '../../../../common'; import { useWired } from '../../../../hooks'; import { WiredSelectorBaseView } from './WiredSelectorBaseView'; -const SOURCE_FURNI_PICKED = 0; +const SOURCE_FURNI_PICKED = 0; export const WiredSelectorFurniByTypeView: FC<{}> = () => { - const [ matchState, setMatchState ] = useState(false); + const [ matchState, setMatchState ] = useState(false); const [ filterExisting, setFilterExisting ] = useState(false); - const [ invert, setInvert ] = useState(false); + const [ invert, setInvert ] = useState(false); const { trigger = null, setIntParams } = useWired(); @@ -28,9 +28,9 @@ export const WiredSelectorFurniByTypeView: FC<{}> = () => { setIntParams([ SOURCE_FURNI_PICKED, - matchState ? 1 : 0, - filterExisting ? 1 : 0, - invert ? 1 : 0, + matchState ? 1 : 0, + filterExisting ? 1 : 0, + invert ? 1 : 0, ]); }, [ matchState, filterExisting, invert, setIntParams ]); diff --git a/src/components/wired/views/selectors/WiredSelectorWithVariableView.tsx b/src/components/wired/views/selectors/WiredSelectorWithVariableView.tsx index 54b85fc..68dcd67 100644 --- a/src/components/wired/views/selectors/WiredSelectorWithVariableView.tsx +++ b/src/components/wired/views/selectors/WiredSelectorWithVariableView.tsx @@ -137,7 +137,7 @@ export const WiredSelectorWithVariableView: FC (entry.token === variableToken))) return mainEntries; - const fallbackEntry = createFallbackVariableEntry(selectorTarget as WiredVariablePickerTarget, variableToken); + const fallbackEntry = createFallbackVariableEntry(selectorTarget, variableToken); return fallbackEntry ? [ fallbackEntry, ...mainEntries ] : mainEntries; }, [ mainEntries, selectorTarget, variableToken ]); const selectedMainEntry = useMemo(() => flattenWiredVariablePickerEntries(resolvedMainEntries).find(entry => (entry.token === variableToken)) || null, [ resolvedMainEntries, variableToken ]); diff --git a/src/hooks/avatar-editor/useAvatarEditor.ts b/src/hooks/avatar-editor/useAvatarEditor.ts index 06285c7..7ee02b9 100644 --- a/src/hooks/avatar-editor/useAvatarEditor.ts +++ b/src/hooks/avatar-editor/useAvatarEditor.ts @@ -320,7 +320,7 @@ const useAvatarEditorState = () => newAvatarModels[AvatarEditorFigureCategory.TORSO] = [ AvatarFigurePartType.CHEST, AvatarFigurePartType.CHEST_PRINT, AvatarFigurePartType.COAT_CHEST, AvatarFigurePartType.CHEST_ACCESSORY ].map(setType => buildCategory(setType, buildModeDefault)); newAvatarModels[AvatarEditorFigureCategory.LEGS] = [ AvatarFigurePartType.LEGS, AvatarFigurePartType.SHOES, AvatarFigurePartType.WAIST_ACCESSORY ].map(setType => buildCategory(setType, buildModeDefault)); newAvatarModels[AvatarEditorFigureCategory.PETS] = [ AvatarFigurePartType.PET ].map(setType => buildCategory(setType)).filter(Boolean); - newAvatarModels[AvatarEditorFigureCategory.MISC] = [ AvatarFigurePartType.MISC ].map(setType => buildCategory(setType)).filter(Boolean); + newAvatarModels[AvatarEditorFigureCategory.MISC] = [ AvatarFigurePartType.MISC ].map(setType => buildCategory(setType)).filter(Boolean); newAvatarModels[AvatarEditorFigureCategory.NFT] = [ AvatarFigurePartType.HEAD, AvatarFigurePartType.HAIR, diff --git a/src/hooks/furni-editor/useFurniEditor.ts b/src/hooks/furni-editor/useFurniEditor.ts index cd95ec4..cb62d86 100644 --- a/src/hooks/furni-editor/useFurniEditor.ts +++ b/src/hooks/furni-editor/useFurniEditor.ts @@ -146,7 +146,8 @@ export const useFurniEditor = () => furniData = JSON.parse(parser.furniDataJson); } } - catch(e) {} + catch(e) + {} setFurniDataEntry(furniData); }); diff --git a/src/hooks/inventory/useInventoryBots.ts b/src/hooks/inventory/useInventoryBots.ts index ac97b71..08b37eb 100644 --- a/src/hooks/inventory/useInventoryBots.ts +++ b/src/hooks/inventory/useInventoryBots.ts @@ -59,7 +59,7 @@ const useInventoryBotsState = () => for(const botData of addedDatas) { - const botItem = { botData } as IBotItem; + const botItem = { botData }; const unseen = isUnseen(UnseenItemCategory.BOT, botData.id); if(unseen) newValue.unshift(botItem); @@ -82,7 +82,7 @@ const useInventoryBotsState = () => if(index >= 0) return prevValue; - const botItem = { botData: parser.item } as IBotItem; + const botItem = { botData: parser.item }; const unseen = isUnseen(UnseenItemCategory.BOT, botItem.botData.id); if(unseen) newValue.unshift(botItem); diff --git a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts index 0cf0238..6296326 100644 --- a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts +++ b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts @@ -401,8 +401,8 @@ const useAvatarInfoWidgetState = () => useEffect(() => { - if(!roomSession) return; - + if(!roomSession) return; + roomSession.isDecorating = isDecorating; }, [ roomSession, isDecorating ]); diff --git a/src/hooks/rooms/widgets/useUserChooserWidget.ts b/src/hooks/rooms/widgets/useUserChooserWidget.ts index 8d0113a..7cbac46 100644 --- a/src/hooks/rooms/widgets/useUserChooserWidget.ts +++ b/src/hooks/rooms/widgets/useUserChooserWidget.ts @@ -13,7 +13,7 @@ const resolveUserType = (userType: number): string => case 3: return 'Bot'; default: return '-'; } -} +}; const useUserChooserWidgetState = () => { diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts index 62576e8..cd73ced 100644 --- a/src/hooks/useLocalStorage.ts +++ b/src/hooks/useLocalStorage.ts @@ -7,12 +7,12 @@ const userId = new URLSearchParams(window.location.search).get('userid') || 0; const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch>] => { key = userId ? `${ key }.${ userId }` : key; - + const [ storedValue, setStoredValue ] = useState(() => { try { - const item = typeof window !== 'undefined' ? GetLocalStorage(key) as T : undefined; + const item = typeof window !== 'undefined' ? GetLocalStorage(key) : undefined; return item ?? initialValue; } @@ -37,9 +37,9 @@ const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch { if(!furniData) return null; - const rawValue = (furniData as any).interactionType - ?? (furniData as any).interactionTypeName - ?? (furniData as any).interactionTypeId; + const rawValue = (furniData).interactionType + ?? (furniData).interactionTypeName + ?? (furniData).interactionTypeId; if(rawValue === undefined || rawValue === null) return null; if(typeof rawValue !== 'string') return null; @@ -83,9 +83,9 @@ const useWiredState = () => const values = [ getInteractionTypeName(furniData), - (typeof (furniData as any).className === 'string') ? (furniData as any).className.toLowerCase() : null, - (typeof (furniData as any).fullName === 'string') ? (furniData as any).fullName.toLowerCase() : null, - (typeof (furniData as any).name === 'string') ? (furniData as any).name.toLowerCase() : null + (typeof (furniData).className === 'string') ? (furniData).className.toLowerCase() : null, + (typeof (furniData).fullName === 'string') ? (furniData).fullName.toLowerCase() : null, + (typeof (furniData).name === 'string') ? (furniData).name.toLowerCase() : null ]; return values.filter((value, index, array): value is string => !!value && (array.indexOf(value) === index)); diff --git a/src/secure-assets.ts b/src/secure-assets.ts index f8ea08c..7f7c170 100644 --- a/src/secure-assets.ts +++ b/src/secure-assets.ts @@ -26,14 +26,16 @@ const getDeployBaseUrl = (): string => const loaderBase = (window as any).__nitroLoaderBase; if(typeof loaderBase === 'string' && loaderBase.length) return new URL('..', loaderBase).toString(); } - catch {} + catch + {} try { const moduleUrl = (import.meta as any).url; if(typeof moduleUrl === 'string' && moduleUrl.length) return new URL('..', new URL('.', moduleUrl)).toString(); } - catch {} + catch + {} try { @@ -44,7 +46,8 @@ const getDeployBaseUrl = (): string => return trimmed ? `${ window.location.origin }/${ trimmed }/` : `${ window.location.origin }/`; } } - catch {} + catch + {} return `${ window.location.origin }/`; }; @@ -101,7 +104,8 @@ const setDebugState = (message: string): void => node.textContent = (window as any).__nitroSecureDebugLog.slice(-8).join('\n'); document.body.appendChild(node); } - catch {} + catch + {} }; const textEncoder = new TextEncoder(); @@ -137,7 +141,8 @@ export const getClientMode = (): NitroClientMode => }; } } - catch {} + catch + {} return { ...CLIENT_MODE_DEFAULTS }; }; @@ -574,7 +579,8 @@ export const installSecureFetch = (): void => scheduleSecureRekey(); } } - catch {} + catch + {} return decrypted; }