🆙 Camera Fix

This commit is contained in:
duckietm 2024-05-16 09:31:49 +02:00
parent 8a9ed64f20
commit b52d429175
8 changed files with 83 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -26,6 +26,23 @@
}
}
.info-camera {
top: 8px;
right: 36px;
cursor: pointer;
background-image: url("@/assets/images/boxes/card/questionmark.png");
width: 19px;
height: 20px;
&:hover {
background-image: url("@/assets/images/boxes/card/questionmark_hover.png");
&:active {
background-image: url("@/assets/images/boxes/card/questionmark_click.png");
}
}
}
.camera-area {
position: absolute;
top: 37px;

View File

@ -44,10 +44,29 @@ export const CameraWidgetView: FC<{}> = props =>
}
const checkoutPictureUrl = (pictureUrl: string) =>
{
setSavedPictureUrl(pictureUrl);
setMode(MODE_CHECKOUT);
}
{
const expectedPrefix = 'data:image/';
if (!pictureUrl.startsWith(expectedPrefix)) {
return;
}
const sanitizedUrl = sanitizeImageUrl(pictureUrl);
if (!sanitizedUrl) {
return;
}
setSavedPictureUrl(sanitizedUrl);
setMode(MODE_CHECKOUT);
}
const sanitizeImageUrl = (imageUrl: string): string | null => {
if (!imageUrl.startsWith('data:image/')) {
return null;
}
return imageUrl;
}
useRoomSessionManagerEvent<RoomSessionEvent>(RoomSessionEvent.ENDED, event => setMode(MODE_NONE));

View File

@ -1,7 +1,7 @@
import { NitroRectangle, TextureUtils } from '@nitrots/nitro-renderer';
import { FC, useRef } from 'react';
import { FaTimes } from 'react-icons/fa';
import { CameraPicture, GetRoomEngine, GetRoomSession, LocalizeText, PlaySound, SoundNames } from '../../../api';
import { CameraPicture, CreateLinkEvent, GetRoomEngine, GetRoomSession, LocalizeText, PlaySound, SoundNames } from '../../../api';
import { Column, DraggableWindow, Flex } from '../../../common';
import { useCamera, useNotification } from '../../../hooks';
@ -62,6 +62,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
<Column center className="nitro-camera-capture" gap={ 0 }>
{ selectedPicture && <img alt="" className="camera-area" src={ selectedPicture.imageUrl } /> }
<div className="camera-canvas drag-handler">
<div className="position-absolute info-camera" onClick={ () => CreateLinkEvent('habbopages/camera') }></div>
<div className="position-absolute header-close" onClick={ onClose }>
<FaTimes className="fa-icon" />
</div>

View File

@ -1,8 +1,8 @@
import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer';
import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, NotEnoughBalanceMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { CreateLinkEvent, GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../api';
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
import { useMessageEvent } from '../../../hooks';
import { useMessageEvent, useNotification } from '../../../hooks';
export interface CameraWidgetCheckoutViewProps
{
@ -21,6 +21,7 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
const [ wasPicturePublished, setWasPicturePublished ] = useState(false);
const [ isWaiting, setIsWaiting ] = useState(false);
const [ publishCooldown, setPublishCooldown ] = useState(0);
const { simpleAlert } = useNotification();
const publishDisabled = useMemo(() => GetConfiguration<boolean>('camera.publish.disabled', false), []);
@ -34,6 +35,8 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
{
const parser = event.getParser();
if (!parser.ok) simpleAlert(LocalizeText('camera.publish.wait', [ 'minutes' ], [ Math.floor(parser.secondsToWait / 60).toString().replace('-', '') ]), null, null, null, LocalizeText('camera.purchase.pleasewait'));
setPublishUrl(parser.extraDataId);
setPublishCooldown(parser.secondsToWait);
setWasPicturePublished(parser.ok);
@ -47,6 +50,19 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
setPictureUrl(GetConfiguration<string>('camera.url') + '/' + parser.url);
});
useMessageEvent<NotEnoughBalanceMessageEvent>(NotEnoughBalanceMessageEvent, event =>
{
const parser = event.getParser();
if (!parser) return null;
if (parser.notEnoughCredits && !parser.notEnoughActivityPoints) simpleAlert(LocalizeText('catalog.alert.notenough.credits.description'), null, null, null, LocalizeText('catalog.alert.notenough.title'));
if (!parser.notEnoughCredits && parser.notEnoughActivityPoints) simpleAlert(LocalizeText(`catalog.alert.notenough.activitypoints.description.${ parser.activityPointType }`), null, null, null, LocalizeText(`catalog.alert.notenough.activitypoints.title.${ parser.activityPointType }`));
setIsWaiting(false);
});
const processAction = (type: string, value: string | number = null) =>
{
switch(type)

View File

@ -1,6 +1,7 @@
import { RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { FaArrowLeft, FaArrowRight } from 'react-icons/fa';
import { GetUserProfile, IPhotoData, LocalizeText } from '../../../api';
import { GetRoomEngine, GetUserProfile, IPhotoData, LocalizeText } from '../../../api';
import { Flex, Grid, Text } from '../../../common';
export interface CameraWidgetShowPhotoViewProps
@ -13,7 +14,6 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
{
const { currentIndex = -1, currentPhotos = null } = props;
const [ imageIndex, setImageIndex ] = useState(0);
const currentImage = (currentPhotos && currentPhotos.length) ? currentPhotos[imageIndex] : null;
const next = () =>
@ -21,9 +21,7 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
setImageIndex(prevValue =>
{
let newIndex = (prevValue + 1);
if(newIndex >= currentPhotos.length) newIndex = 0;
return newIndex;
});
}
@ -33,36 +31,35 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
setImageIndex(prevValue =>
{
let newIndex = (prevValue - 1);
if(newIndex < 0) newIndex = (currentPhotos.length - 1);
return newIndex;
});
}
useEffect(() =>
const getUserData = (roomId: number, objectId: number, type: string): number | string =>
{
setImageIndex(currentIndex);
}, [ currentIndex ]);
const roomObject = GetRoomEngine().getRoomObject(roomId, objectId, RoomObjectCategory.WALL);
if (!roomObject) return;
return type == 'username' ? roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_NAME) : roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
}
useEffect(() => { setImageIndex(currentIndex); }, [ currentIndex ]);
if(!currentImage) return null;
return (
<Grid style={ { display: 'flex', flexDirection: 'column' } }>
<Flex center className="picture-preview border border-black" style={ currentImage.w ? { backgroundImage: 'url(' + currentImage.w + ')' } : {} }>
{ !currentImage.w &&
<Text bold>{ LocalizeText('camera.loading') }</Text> }
{ !currentImage.w && <Text bold>{ LocalizeText('camera.loading') }</Text> }
</Flex>
{ currentImage.m && currentImage.m.length &&
<Text center>{ currentImage.m }</Text> }
{ currentImage.m && currentImage.m.length && <Text center>{ currentImage.m }</Text> }
<Flex alignItems="center" justifyContent="between">
<Text>{ (currentImage.n || '') }</Text>
<Text>{ new Date(currentImage.t * 1000).toLocaleDateString() }</Text>
<Text> { new Date(currentImage.t * 1000).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' }) } </Text>
<Text className="username" onClick={() => GetUserProfile(Number(getUserData(currentImage.s, Number(currentImage.u), 'id')))}> { getUserData(currentImage.s, Number(currentImage.u), 'username') } </Text>
</Flex>
{ (currentPhotos.length > 1) &&
<Flex className="picture-preview-buttons">
<FaArrowLeft className="cursor-pointer" onClick={ previous } />
<Text underline className="cursor-pointer" onClick={ event => GetUserProfile(currentImage.oi) }>{ currentImage.o }</Text>
<FaArrowRight className="cursor-pointer" onClick={ next } />
</Flex>
}

View File

@ -1,9 +1,14 @@
import { NotificationBubbleItem, NotificationBubbleType } from "../../../../api";
import {
NotificationBubbleItem,
NotificationBubbleType,
} from "../../../../api";
import { NotificationClubGiftBubbleView } from "./NotificationClubGiftBubbleView";
import { NotificationDefaultBubbleView } from "./NotificationDefaultBubbleView";
export const GetBubbleLayout = ( item: NotificationBubbleItem, onClose: () => void ) => {
export const GetBubbleLayout = (
item: NotificationBubbleItem,
onClose: () => void
) => {
if (!item) return null;
const props = { key: item.id, item, onClose };