From b52d429175aa2e66748146f511200f8f3c05fb6a Mon Sep 17 00:00:00 2001 From: duckietm Date: Thu, 16 May 2024 09:31:49 +0200 Subject: [PATCH] :up: Camera Fix --- .../images/inventory/trading/locked-icon.png | Bin 0 -> 2448 bytes .../inventory/trading/unlocked-icon.png | Bin 0 -> 2078 bytes src/components/camera/CameraWidgetView.scss | 17 ++++++++++ src/components/camera/CameraWidgetView.tsx | 27 ++++++++++++--- .../camera/views/CameraWidgetCaptureView.tsx | 3 +- .../camera/views/CameraWidgetCheckoutView.tsx | 20 +++++++++-- .../views/CameraWidgetShowPhotoView.tsx | 31 ++++++++---------- .../views/bubble-layouts/GetBubbleLayout.tsx | 13 +++++--- 8 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/assets/images/inventory/trading/locked-icon.png create mode 100644 src/assets/images/inventory/trading/unlocked-icon.png diff --git a/src/assets/images/inventory/trading/locked-icon.png b/src/assets/images/inventory/trading/locked-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7d9a3cb9b012da357b164a091a125d6c5f0f74fb GIT binary patch literal 2448 zcmcImX;2hr8g4`gOrnq!9uX*;b_^)=bWaa+H5s{v1fs(+qCr-&)6@M8Oq`i+rW=N% z%(A%VsHnKC0T&HPmCK=_AjT_-Ms%$Ttl7mF3>r<;tRO{2a1~-=blq<_W>Z^<#h>l! zuJ7pQd*0_g`mKH|JM+akvPCikLFQzn8_jT(!zV5%(7UsG(KsA}h4ghIg3Mp)ef%=a z^4ka!aL%5aC*_$|(Jb#&FdT0MiZZ7F(FpQ;iDbZ_)=4Lvf{)fEP6Y~vj3{FSLa89VPE7+%rpH5_P9Iv7(n_I~DZRf) zEasLAfG`7*FLARVtrWPVCDX<@)^}DYaXThFOgFmDu2#^aPKmsHUz zcxz)xiYCcPs0r2r$4Jb~z&vNSmCpofGSL|>QDR&y$S@i(C`w_sb9B6#RjN3p9%qzR zH6G7V0N3l{HMmZzWJ#?CP(Y`h&;`#MdA7tGK=1j<(&cy-a`<9IYXGcvR!89)n})&l zs(3Zda2n_>XVoh8TD_WM)YEKPZae&X7{||9y{b6K2-I3i#Ze^AQW_f`uUA7dttuWT z^?D_+YDg_b>M)dJX&di$GO$wYPNonLf~yci|EngIckpf#&%v0hy!8y(p%>|P5hkyE z>I+#7il=4{J33KzG{btU-GH&)Gy@Ks+P42f^k$}WlGalMAn9Y0KM50go8)2KAh{4m zdIsf1{F;1`DSf>7nWg^!Dt;=oY!Txs1h9b;nAaV`+h`^eL;P>fCf@z5DNVy+r}IvI zO%^VEZ5p^BwHr3!4;FqCjv)TF3}bR`-sTfKlUGJ4!#;h~G4JV+>Lb>Wx`O<$+4cYE z*%kK0rInv=THFnHckbLRqp`8EvbbI`U|#KtJNPi| zal|0qcO#Hqlbl%J@w*6}gjqgjjn`gCVDZCqQw^6=Z=A2-VRF9(GK znwI;!)n~Syss8xjp+ilBU-}`}1}=LBl8o{npKa=>jXS%&d2dd4>4*DD!&Ca-doM98 zmto~tPqJ2{ky+YL7v$&9LLwF~4!^Y~^w`3|3pYD1oL$i?21PwZCTvX!;-l9$TbxUZZwYcIVvUz@tCNg68 zyOx(T`O(h}$ISnfT3-5nL*MKtuKu<$0Fi3ibF=GXRh0{>0-LJFzSi{x|D<^K50ERQ ztvB2mSNiwXsD9f#>=Q9^TckVSNK>cg1>>E|Z)m?cb?Ymn@k+LzTI;yCeskMs-|Qqm ze3hy1^pK~g{X3$U_8TiMsdzY$@RuD~>KoO?M{^FZcb*FkMIO|=-uK17AB>#37=3Z; z!+~}FZIu$(@&&V?CHh3v59b@V&VGMr`$*Nzxt?OxU9y>GqrV&jvigL4lr z8xGyIYuAuOBURUhi@F~yWS4~${P(9Sf(oLeqmlQ!tXK323I52Inwkao!_Ey~Z+dly zxw`efqbo3c?i+`MHE1B*T-sK@vG#a61vAQsB3bMnrtaSAI)lg x#!*?B5M(UT=zEAi`VBsLXLnLuqi)Ffh?ukHcLm)KM<@Q7GSV`Q?J1V({{ZaWe$)T} literal 0 HcmV?d00001 diff --git a/src/assets/images/inventory/trading/unlocked-icon.png b/src/assets/images/inventory/trading/unlocked-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..39bd355d90d4a99b3f7691baf0ceefd4ed84b561 GIT binary patch literal 2078 zcmcIlYf#iy7+qRGaB!-2RH`zKv8_^?O*YwO*}#Hy7X@*VA|r@k%_eu*$Zisn01GJA zw_>$3YPI8o7F4Rvpw=IXj}~p!(Y8#nK1Z}&tu50!6toYm(#H)fTc@KAf0~(_+?#vu z`Of#qmsQzWQ-%y4Jy@sH4arEi=fGzS9B~oh@V<2ak{0-gl+tG@I^D>ZwGon$^HR4? z7uLq-=BxRRX*4T(^$aIEf!^npAX=wOO7TeyTLM(X35t2aigq1sK@py_qIo6<;gD>= z&8Jt%U`AC|E?ZT?S~xT%8Ai4{%N3?liC zY{VwY05R(g7)uZYVz%g=ge$=bEW~RFNstEIK;i}yMjB|+L>o*<;6kB2nRC%O_Q?Tj zaAif^sw&YqUQtn@ub}jzT#Oqm77I?0I7wmL~IBf!q6z>31Wkr-jbNGg}0Xo{pw#yEnc38D|` zfVIFeDl;&!$nmbqfj}J&Izv!YMqojP-HJj{dY2e|qIf5~wS;j?~5-d)P0wyO$nvDQs0BOO@q=_&a zNy@+iw%1F@HeKf7*TZ-oWz|%1kP(>K1PjA)7zs!-W^~4L7(*p+80$%yml*uNIqThfq$%~oVW-ok!6pkA!8Q#9NG-!AJfZr* z4xKLK*9?1VZvL{)D=8(PPKplip3qc1v8eX@p6QNGz#5VmaSrMa6MSAG|rvv(@BciZj`hte?XPC-P-&JCui zcHLV@{zlie2fxYD*F5o)-|KpKs>Z%FVQpsnn(Xj*Yp1OkB^AB>#?FST)JOXHr_Cqw z8r|>zF=gR|J-MN=d7EtOx!c`r^1=%T$Gl0#|2S{>=&E^nH-@(QA11F%kE;*+{7QR! zTwPsV$#W;!BenK*o|vz;{IH^>WVioCXVDGAE57#l;-s20t6UL_b;qYCKJ!8A!Jln+ zqR-#mRloIBVfgGq8@|Zg&~Y;HoZ>&dD|Sv%=1zXkjZ5w^`lZL`{}qv3mox0r?TXIY z=1&eEu72U2uBLND)Uf5_My?JkyqvZXoH-En@Xt{jYWKGW^!GpX9}7=D^2HVZ#jty4o0^8~n|=LR?C = 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.ENDED, event => setMode(MODE_NONE)); diff --git a/src/components/camera/views/CameraWidgetCaptureView.tsx b/src/components/camera/views/CameraWidgetCaptureView.tsx index 308bb83..c3fc015 100644 --- a/src/components/camera/views/CameraWidgetCaptureView.tsx +++ b/src/components/camera/views/CameraWidgetCaptureView.tsx @@ -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 = props = { selectedPicture && }
+
CreateLinkEvent('habbopages/camera') }>
diff --git a/src/components/camera/views/CameraWidgetCheckoutView.tsx b/src/components/camera/views/CameraWidgetCheckoutView.tsx index 6ee92f5..23d581b 100644 --- a/src/components/camera/views/CameraWidgetCheckoutView.tsx +++ b/src/components/camera/views/CameraWidgetCheckoutView.tsx @@ -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 = props const [ wasPicturePublished, setWasPicturePublished ] = useState(false); const [ isWaiting, setIsWaiting ] = useState(false); const [ publishCooldown, setPublishCooldown ] = useState(0); + const { simpleAlert } = useNotification(); const publishDisabled = useMemo(() => GetConfiguration('camera.publish.disabled', false), []); @@ -34,6 +35,8 @@ export const CameraWidgetCheckoutView: FC = 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 = props setPictureUrl(GetConfiguration('camera.url') + '/' + parser.url); }); + useMessageEvent(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) diff --git a/src/components/camera/views/CameraWidgetShowPhotoView.tsx b/src/components/camera/views/CameraWidgetShowPhotoView.tsx index 0825c60..c01ea07 100644 --- a/src/components/camera/views/CameraWidgetShowPhotoView.tsx +++ b/src/components/camera/views/CameraWidgetShowPhotoView.tsx @@ -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 = 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 = pro setImageIndex(prevValue => { let newIndex = (prevValue + 1); - if(newIndex >= currentPhotos.length) newIndex = 0; - return newIndex; }); } @@ -33,36 +31,35 @@ export const CameraWidgetShowPhotoView: FC = 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(RoomObjectVariable.FURNITURE_OWNER_NAME) : roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); + } + + useEffect(() => { setImageIndex(currentIndex); }, [ currentIndex ]); if(!currentImage) return null; return ( - { !currentImage.w && - { LocalizeText('camera.loading') } } + { !currentImage.w && { LocalizeText('camera.loading') } } - { currentImage.m && currentImage.m.length && - { currentImage.m } } + { currentImage.m && currentImage.m.length && { currentImage.m } } - { (currentImage.n || '') } - { new Date(currentImage.t * 1000).toLocaleDateString() } + { new Date(currentImage.t * 1000).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' }) } + GetUserProfile(Number(getUserData(currentImage.s, Number(currentImage.u), 'id')))}> { getUserData(currentImage.s, Number(currentImage.u), 'username') } { (currentPhotos.length > 1) && - GetUserProfile(currentImage.oi) }>{ currentImage.o } } diff --git a/src/components/notification-center/views/bubble-layouts/GetBubbleLayout.tsx b/src/components/notification-center/views/bubble-layouts/GetBubbleLayout.tsx index f4f9d24..8e4e262 100644 --- a/src/components/notification-center/views/bubble-layouts/GetBubbleLayout.tsx +++ b/src/components/notification-center/views/bubble-layouts/GetBubbleLayout.tsx @@ -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 }; @@ -14,4 +19,4 @@ export const GetBubbleLayout = ( item: NotificationBubbleItem, onClose: () => vo default: return ; } -}; \ No newline at end of file +};