From 20cd6fc28f31d36be17533e0d3f64a49b1489c43 Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 13 Sep 2024 08:06:26 +0200 Subject: [PATCH] :up: Camera fix and some small updates --- public/renderer-config.json | 15 +++--- src/App.tsx | 3 +- .../room/widgets/FurnitureDimmerUtilities.ts | 11 +++- src/components/camera/CameraWidgetView.tsx | 12 ++--- .../camera/views/CameraWidgetCaptureView.tsx | 10 ++-- .../camera/views/CameraWidgetCheckoutView.tsx | 4 +- .../views/CameraWidgetShowPhotoView.tsx | 6 +-- .../views/editor/CameraWidgetEditorView.tsx | 54 +++++++++---------- .../CameraWidgetEffectListItemView.tsx | 2 +- .../CameraWidgetEffectListView.tsx | 4 +- .../room/widgets/RoomWidgetsView.tsx | 2 +- .../room-tools/RoomToolsWidgetView.tsx | 17 +++--- src/hooks/camera/useCamera.ts | 15 +++--- src/hooks/rooms/widgets/useChatInputWidget.ts | 13 +---- 14 files changed, 84 insertions(+), 84 deletions(-) diff --git a/public/renderer-config.json b/public/renderer-config.json index 88dd98f..c89c910 100644 --- a/public/renderer-config.json +++ b/public/renderer-config.json @@ -11,17 +11,17 @@ "${gamedata.url}//config/UITexts.json" ], "external.samples.url": "${hof.furni.url}/mp3/sound_machine_sample_%sample%.mp3", - "furnidata.url": "${gamedata.url}/config/FurnitureData.json", - "productdata.url": "${gamedata.url}/config/ProductData.json", - "avatar.actions.url": "${gamedata.url}/config/HabboAvatarActions.json", - "avatar.figuredata.url": "${gamedata.url}/config/FigureData.json", - "avatar.figuremap.url": "${gamedata.url}/config/FigureMap.json", - "avatar.effectmap.url": "${gamedata.url}/config/EffectMap.json", + "furnidata.url": "${gamedata.url}/config/FurnitureData.json?v=1", + "productdata.url": "${gamedata.url}/config/ProductData.json?v=1", + "avatar.actions.url": "${gamedata.url}/config/HabboAvatarActions.json?v=1", + "avatar.figuredata.url": "${gamedata.url}/config/FigureData.json?v=1", + "avatar.figuremap.url": "${gamedata.url}/config/FigureMap.json?v=1", + "avatar.effectmap.url": "${gamedata.url}/config/EffectMap.json?v=1", "avatar.asset.url": "${asset.url}/clothes/%libname%.nitro", "avatar.asset.effect.url": "${asset.url}/effect/%libname%.nitro", "furni.asset.url": "${asset.url}/furniture/%libname%.nitro", "furni.asset.icon.url": "${gamedata.url}/icons/%libname%%param%_icon.png", - "pet.asset.url": "${asset.url}/pet/%libname%.nitro", + "pet.asset.url": "${asset.url}/pets/%libname%.nitro", "generic.asset.url": "${asset.url}/generic/%libname%.nitro", "badge.asset.url": "${image.library.url}album1584/%badgename%.gif", "furni.rotation.bounce.steps": 20, @@ -38,6 +38,7 @@ "system.pong.interval.ms": 20000, "room.color.skip.transition": true, "room.landscapes.enabled": true, + "room.zoom.enabled": true, "avatar.mandatory.libraries": [ "bd:1", "li:0" diff --git a/src/App.tsx b/src/App.tsx index 1c8e72c..44d58e5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomCameraWidgetManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer'; +import { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; import { GetUIVersion } from './api'; import { Base } from './common'; @@ -57,7 +57,6 @@ export const App: FC<{}> = props => GetSoundManager().init(), GetSessionDataManager().init(), GetRoomSessionManager().init(), - GetRoomCameraWidgetManager().init() ] ); diff --git a/src/api/room/widgets/FurnitureDimmerUtilities.ts b/src/api/room/widgets/FurnitureDimmerUtilities.ts index f55fc87..f040754 100644 --- a/src/api/room/widgets/FurnitureDimmerUtilities.ts +++ b/src/api/room/widgets/FurnitureDimmerUtilities.ts @@ -19,10 +19,17 @@ export class FurnitureDimmerUtilities } public static previewDimmer(color: number, brightness: number, bgOnly: boolean): void - { - GetRoomEngine().updateObjectRoomColor(GetRoomSession().roomId, color, brightness, bgOnly); +{ + const roomSession = GetRoomSession(); + + if (!roomSession || !roomSession.roomId) { + console.error('Room session or roomId is not available.'); + return; } + GetRoomEngine().updateObjectRoomColor(roomSession.roomId, color, brightness, bgOnly); +} + public static scaleBrightness(value: number): number { return ~~((((value - this.MIN_BRIGHTNESS) * (100 - 0)) / (this.MAX_BRIGHTNESS - this.MIN_BRIGHTNESS)) + 0); diff --git a/src/components/camera/CameraWidgetView.tsx b/src/components/camera/CameraWidgetView.tsx index 62af9ca..68e394e 100644 --- a/src/components/camera/CameraWidgetView.tsx +++ b/src/components/camera/CameraWidgetView.tsx @@ -14,7 +14,7 @@ export const CameraWidgetView: FC<{}> = props => { const [ mode, setMode ] = useState(MODE_NONE); const [ base64Url, setSavedPictureUrl ] = useState(null); - const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 }} = useCamera(); + const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 } } = useCamera(); const processAction = (type: string) => { @@ -40,13 +40,13 @@ export const CameraWidgetView: FC<{}> = props => setMode(MODE_CAPTURE); return; } - } + }; const checkoutPictureUrl = (pictureUrl: string) => { setSavedPictureUrl(pictureUrl); setMode(MODE_CHECKOUT); - } + }; useNitroEvent(RoomSessionEvent.ENDED, event => setMode(MODE_NONE)); @@ -56,9 +56,9 @@ export const CameraWidgetView: FC<{}> = props => linkReceived: (url: string) => { const parts = url.split('/'); - + if(parts.length < 2) return; - + switch(parts[1]) { case 'show': @@ -93,4 +93,4 @@ export const CameraWidgetView: FC<{}> = props => { (mode === MODE_CHECKOUT) && processAction('close') } onCancelClick={ () => processAction('editor_cancel') } price={ price }> } ); -} +}; diff --git a/src/components/camera/views/CameraWidgetCaptureView.tsx b/src/components/camera/views/CameraWidgetCaptureView.tsx index ef92884..df90cb5 100644 --- a/src/components/camera/views/CameraWidgetCaptureView.tsx +++ b/src/components/camera/views/CameraWidgetCaptureView.tsx @@ -28,9 +28,9 @@ export const CameraWidgetCaptureView: FC = props = if(!elementRef || !elementRef.current) return null; const frameBounds = elementRef.current.getBoundingClientRect(); - + return new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height)); - } + }; const takePicture = async () => { @@ -55,7 +55,7 @@ export const CameraWidgetCaptureView: FC = props = clone.push(new CameraPicture(texture, await TextureUtils.generateImageUrl(texture))); setCameraRoll(clone); - } + }; return ( @@ -66,7 +66,7 @@ export const CameraWidgetCaptureView: FC = props = { !selectedPicture &&
} - { selectedPicture && + { selectedPicture &&
@@ -87,4 +87,4 @@ export const CameraWidgetCaptureView: FC = props = ); -} +}; diff --git a/src/components/camera/views/CameraWidgetCheckoutView.tsx b/src/components/camera/views/CameraWidgetCheckoutView.tsx index 100e076..4d23e0e 100644 --- a/src/components/camera/views/CameraWidgetCheckoutView.tsx +++ b/src/components/camera/views/CameraWidgetCheckoutView.tsx @@ -70,7 +70,7 @@ export const CameraWidgetCheckoutView: FC = props onCancelClick(); return; } - } + }; useEffect(() => { @@ -156,4 +156,4 @@ export const CameraWidgetCheckoutView: FC = props ); -} +}; diff --git a/src/components/camera/views/CameraWidgetShowPhotoView.tsx b/src/components/camera/views/CameraWidgetShowPhotoView.tsx index 8614695..4f4a59f 100644 --- a/src/components/camera/views/CameraWidgetShowPhotoView.tsx +++ b/src/components/camera/views/CameraWidgetShowPhotoView.tsx @@ -26,7 +26,7 @@ export const CameraWidgetShowPhotoView: FC = pro return newIndex; }); - } + }; const previous = () => { @@ -38,7 +38,7 @@ export const CameraWidgetShowPhotoView: FC = pro return newIndex; }); - } + }; useEffect(() => { @@ -68,4 +68,4 @@ export const CameraWidgetShowPhotoView: FC = pro } ); -} +}; diff --git a/src/components/camera/views/editor/CameraWidgetEditorView.tsx b/src/components/camera/views/editor/CameraWidgetEditorView.tsx index 383bd8f..35f1464 100644 --- a/src/components/camera/views/editor/CameraWidgetEditorView.tsx +++ b/src/components/camera/views/editor/CameraWidgetEditorView.tsx @@ -1,5 +1,5 @@ -import { GetRoomCameraWidgetManager, IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { GetRoomCameraWidgetManager, IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, NitroLogger, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { FaSave, FaSearchMinus, FaSearchPlus, FaTrash } from 'react-icons/fa'; import ReactSlider from 'react-slider'; import { CameraEditorTabs, CameraPicture, CameraPictureThumbnail, LocalizeText } from '../../../../api'; @@ -27,6 +27,7 @@ export const CameraWidgetEditorView: FC = props => const [ effectsThumbnails, setEffectsThumbnails ] = useState([]); const [ isZoomed, setIsZoomed ] = useState(false); const [ currentPictureUrl, setCurrentPictureUrl ] = useState(''); + const isBusy = useRef(false); const getColorMatrixEffects = useMemo(() => { @@ -104,7 +105,7 @@ export const CameraWidgetEditorView: FC = props => let existingIndex = getSelectedEffectIndex(effectName); if(existingIndex >= 0) return; - + const effect = availableEffects.find(effect => (effect.name === effectName)); if(!effect) return; @@ -142,9 +143,9 @@ export const CameraWidgetEditorView: FC = props => (async () => { const image = new Image(); - + image.src = currentPictureUrl; - + const newWindow = window.open(''); newWindow.document.write(image.outerHTML); })(); @@ -158,29 +159,28 @@ export const CameraWidgetEditorView: FC = props => useEffect(() => { - (async () => + const processThumbnails = async () => { - const thumbnails: CameraPictureThumbnail[] = []; - - for await (const effect of availableEffects) - { - const image = await GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false); + const renderedEffects = await Promise.all(availableEffects.map(effect => GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false))); - thumbnails.push(new CameraPictureThumbnail(effect.name, image.src)); - } + setEffectsThumbnails(renderedEffects.map((image, index) => new CameraPictureThumbnail(availableEffects[index].name, image.src))); + }; - setEffectsThumbnails(thumbnails); - })(); + processThumbnails(); }, [ picture, availableEffects ]); useEffect(() => { - (async () => - { - const imageUrl = await GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed); - - setCurrentPictureUrl(imageUrl.src); - })(); + GetRoomCameraWidgetManager() + .applyEffects(picture.texture, selectedEffects, isZoomed) + .then(imageElement => + { + setCurrentPictureUrl(imageElement.src); + }) + .catch(error => + { + NitroLogger.error('Failed to apply effects to picture', error); + }); }, [ picture, selectedEffects, isZoomed ]); return ( @@ -189,7 +189,7 @@ export const CameraWidgetEditorView: FC = props => { TABS.map(tab => { - return processAction('change_tab', tab) }> + return processAction('change_tab', tab) }>; }) } @@ -205,12 +205,12 @@ export const CameraWidgetEditorView: FC = props => { LocalizeText('camera.effect.name.' + selectedEffectName) }
{ state.valueNow }
} + max={ 1 } step={ 0.01 } - value={ getCurrentEffect.alpha } - onChange={ event => setSelectedEffectAlpha(event) } /> + value={ getCurrentEffect.strength } + onChange={ event => setSelectedEffectAlpha(event) } + renderThumb={ ({ key, ...props }, state) =>
{ state.valueNow }
} /> } @@ -240,4 +240,4 @@ export const CameraWidgetEditorView: FC = props =>
); -} \ No newline at end of file +}; diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx index cac3a34..d090889 100644 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx +++ b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx @@ -37,4 +37,4 @@ export const CameraWidgetEffectListItemView: FC } ); -} +}; diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx index 1db466e..1cceefd 100644 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx +++ b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx @@ -24,8 +24,8 @@ export const CameraWidgetEffectListView: FC = p const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name))); 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) } />; }) } ); -}; \ No newline at end of file +}; diff --git a/src/components/room/widgets/RoomWidgetsView.tsx b/src/components/room/widgets/RoomWidgetsView.tsx index 31bd911..3f8cdf5 100644 --- a/src/components/room/widgets/RoomWidgetsView.tsx +++ b/src/components/room/widgets/RoomWidgetsView.tsx @@ -21,7 +21,7 @@ export const RoomWidgetsView: FC<{}> = props => const { roomSession = null } = useRoom(); const { simpleAlert = null } = useNotification(); - useNitroEvent(RoomZoomEvent.ROOM_ZOOM, event => GetRoomEngine().setRoomInstanceRenderingCanvasScale(event.roomId, 1, event.level, null, null, false, event.asDelta)); + useNitroEvent(RoomZoomEvent.ROOM_ZOOM, event => GetRoomEngine().setRoomInstanceRenderingCanvasScale(event.roomId, 1, (((event.level)<1) ? 0.5 : (1 << (Math.floor(event.level) - 1))), null, null, event.isFlipForced)); useNitroEvent( [ diff --git a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx index 695a680..4e8f5b1 100644 --- a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx +++ b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx @@ -1,7 +1,7 @@ import { CreateLinkEvent, GetGuestRoomResultEvent, GetRoomEngine, NavigatorSearchComposer, RateFlatMessageComposer, RoomDataParser } from '@nitrots/nitro-renderer'; import { AnimatePresence, motion } from 'framer-motion'; import { FC, useEffect, useState } from 'react'; -import { LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom } from '../../../../api'; +import { GetConfigurationValue, LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom } from '../../../../api'; import { Base, Column, Flex, Text, classNames } from '../../../../common'; import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks'; @@ -31,12 +31,17 @@ export const RoomToolsWidgetView: FC<{}> = props => case 'zoom': setIsZoomedIn(prevValue => { - let scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1); + if(GetConfigurationValue('room.zoom.enabled', true)) + { + const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1); + GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale === 1 ? 0.5 : 1); + } + else + { + const geometry = GetRoomEngine().getRoomInstanceGeometry(roomSession.roomId, 1); - if(!prevValue) scale /= 2; - else scale *= 2; - - GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale); + if(geometry) geometry.performZoom(); + } return !prevValue; }); diff --git a/src/hooks/camera/useCamera.ts b/src/hooks/camera/useCamera.ts index 78b2eb4..45cb8ea 100644 --- a/src/hooks/camera/useCamera.ts +++ b/src/hooks/camera/useCamera.ts @@ -20,23 +20,20 @@ const useCameraState = () => useMessageEvent(InitCameraMessageEvent, event => { const parser = event.getParser(); - + setPrice({ credits: parser.creditPrice, duckets: parser.ducketPrice, publishDucketPrice: parser.publishDucketPrice }); }); useEffect(() => { - if(!GetRoomCameraWidgetManager().isLoaded) - { - GetRoomCameraWidgetManager().init(); + if(GetRoomCameraWidgetManager().isLoaded) return; - SendMessageComposer(new RequestCameraConfigurationComposer()); + GetRoomCameraWidgetManager().init(); - return; - } + SendMessageComposer(new RequestCameraConfigurationComposer()); }, []); return { availableEffects, cameraRoll, setCameraRoll, selectedPictureIndex, setSelectedPictureIndex, myLevel, price }; -} +}; -export const useCamera = () => useBetween(useCameraState); +export const useCamera = () => useBetween(useCameraState); \ No newline at end of file diff --git a/src/hooks/rooms/widgets/useChatInputWidget.ts b/src/hooks/rooms/widgets/useChatInputWidget.ts index 7efedbd..7b9dc3c 100644 --- a/src/hooks/rooms/widgets/useChatInputWidget.ts +++ b/src/hooks/rooms/widgets/useChatInputWidget.ts @@ -108,17 +108,8 @@ const useChatInputWidgetState = () => return null; case ':zoom': - let requestedZoomLevel = parseFloat(secondPart); - if (isNaN(requestedZoomLevel)) { - requestedZoomLevel = 1; - } - if (requestedZoomLevel >= 1 && requestedZoomLevel <= 5) { - GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, requestedZoomLevel, false)); - } else if (requestedZoomLevel === 0) { - GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, 1, false)); - } else { - GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, 1, false)); - }; + GetEventDispatcher().dispatchEvent(new RoomZoomEvent(roomSession.roomId, parseInt(secondPart))); + return null; case ':screenshot': const texture = GetRoomEngine().createTextureFromRoom(roomSession.roomId, 1);