diff --git a/src/common/card/NitroCardHeaderView.tsx b/src/common/card/NitroCardHeaderView.tsx index 6805427a2..31e0795e8 100644 --- a/src/common/card/NitroCardHeaderView.tsx +++ b/src/common/card/NitroCardHeaderView.tsx @@ -6,14 +6,16 @@ interface NitroCardHeaderViewProps extends ColumnProps { headerText: string; isGalleryPhoto?: boolean; + isInfoToHabboPages?: boolean; noCloseButton?: boolean; onReportPhoto?: (event: MouseEvent) => void; + onClickInfoHabboPages?: (event: MouseEvent) => void; onCloseClick: (event: MouseEvent) => void; } export const NitroCardHeaderView: FC = props => { - const { headerText = null, isGalleryPhoto = false, noCloseButton = false, onReportPhoto = null, onCloseClick = null, justifyContent = 'center', alignItems = 'center', classNames = [], children = null, ...rest } = props; + const { headerText = null, isGalleryPhoto = false, isInfoToHabboPages = false, noCloseButton = false, onReportPhoto = null, onClickInfoHabboPages = null, onCloseClick = null, justifyContent = 'center', alignItems = 'center', classNames = [], children = null, ...rest } = props; const getClassNames = useMemo(() => { @@ -39,6 +41,11 @@ export const NitroCardHeaderView: FC = props => } + { isInfoToHabboPages && + + + + } diff --git a/src/common/card/NitroCardView.scss b/src/common/card/NitroCardView.scss index b5e7f21b4..3752ce7b2 100644 --- a/src/common/card/NitroCardView.scss +++ b/src/common/card/NitroCardView.scss @@ -68,6 +68,30 @@ $nitro-card-tabs-height: 33px; filter: brightness(0.8); } } + + .nitro-card-header-info-habbopages { + cursor: pointer; + padding: 1px 3px; + line-height: 1; + border-radius: $border-radius; + box-shadow: 0 0 0 1.6px $white; + border: 2px solid #1E7295; + background: repeating-linear-gradient( + rgba(30, 114, 149), + rgba(30, 114, 149) 50%, + rgb(9, 102, 133) 50%, + rgb(25, 96, 126) 100% + ); + margin-right: 10px; + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } + } } .nitro-card-tabs { @@ -190,6 +214,31 @@ $nitro-card-tabs-height: 33px; filter: brightness(0.8); } } + + .nitro-card-header-info-habbopages { + cursor: pointer; + padding: 0px 2px; + margin-right: 4px; + line-height: 1; + @include font-size($h7-font-size); + border-radius: $border-radius; + box-shadow: 0 0 0 1.6px $white; + border: 2px solid #1E7295; + background: repeating-linear-gradient( + rgba(30, 114, 149), + rgba(30, 114, 149) 50%, + rgb(9, 102, 133) 50%, + rgb(25, 96, 126) 100% + ); + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } + } } .nitro-card-tabs { diff --git a/src/components/camera/CameraWidgetView.scss b/src/components/camera/CameraWidgetView.scss index 18b18d8a8..ae4dfcb85 100644 --- a/src/components/camera/CameraWidgetView.scss +++ b/src/components/camera/CameraWidgetView.scss @@ -26,6 +26,31 @@ } } + .info-camera { + top: 8px; + right: 36px; + border-radius: $border-radius; + box-shadow: 0 0 0 1.5px $white; + border: 2px solid #1E7295; + background: repeating-linear-gradient( + rgba(30, 114, 149), + rgba(30, 114, 149) 50%, + rgb(9, 102, 133) 50%, + rgb(25, 96, 126) 100% + ); + cursor: pointer; + line-height: 1; + padding: 1px 3px; + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } + } + .camera-area { position: absolute; top: 37px; diff --git a/src/components/camera/views/CameraWidgetCaptureView.tsx b/src/components/camera/views/CameraWidgetCaptureView.tsx index b104c5037..b943e9aa8 100644 --- a/src/components/camera/views/CameraWidgetCaptureView.tsx +++ b/src/components/camera/views/CameraWidgetCaptureView.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { NitroRectangle, TextureUtils } from '@nitrots/nitro-renderer'; import { FC, useRef } from 'react'; -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'; @@ -28,7 +28,7 @@ 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)); } @@ -62,11 +62,14 @@ export const CameraWidgetCaptureView: FC = props = { selectedPicture && }
+
CreateLinkEvent('habbopages/camera') }> + +
{ !selectedPicture &&
} - { selectedPicture && + { selectedPicture &&
diff --git a/src/components/catalog/views/targeted-offer/OfferBubbleView.tsx b/src/components/catalog/views/targeted-offer/OfferBubbleView.tsx index 003b8a18a..81b841bcc 100644 --- a/src/components/catalog/views/targeted-offer/OfferBubbleView.tsx +++ b/src/components/catalog/views/targeted-offer/OfferBubbleView.tsx @@ -10,7 +10,7 @@ export const OfferBubbleView = (props: { offer: TargetedOfferData, setOpen: Disp if (!offer) return; return setOpen(true) } gap={ 2 }> - + { offer.title } ; } diff --git a/src/components/hc-center/HcCenterView.tsx b/src/components/hc-center/HcCenterView.tsx index 2c94d3954..d5308f4ae 100644 --- a/src/components/hc-center/HcCenterView.tsx +++ b/src/components/hc-center/HcCenterView.tsx @@ -19,12 +19,12 @@ export const HcCenterView: FC<{}> = props => const getClubText = () => { if(purse.clubDays <= 0) return LocalizeText('purse.clubdays.zero.amount.text'); - + if((purse.minutesUntilExpiration > -1) && (purse.minutesUntilExpiration < (60 * 24))) { return FriendlyTime.shortFormat(purse.minutesUntilExpiration * 60); } - + return FriendlyTime.shortFormat(((purse.clubPeriods * 31) + purse.clubDays) * 86400); } @@ -64,9 +64,9 @@ export const HcCenterView: FC<{}> = props => linkReceived: (url: string) => { const parts = url.split('/'); - + if(parts.length < 2) return; - + switch(parts[1]) { case 'open': @@ -80,7 +80,7 @@ export const HcCenterView: FC<{}> = props => } } return; - } + } }, eventUrlPrefix: 'habboUI/' }; @@ -130,7 +130,7 @@ export const HcCenterView: FC<{}> = props => return ( - setIsVisible(false) } /> + CreateLinkEvent('habbopages/' + GetConfiguration('hc.center')['benefits.habbopage']) } onCloseClick={ () => setIsVisible(false) } />
@@ -154,7 +154,7 @@ export const HcCenterView: FC<{}> = props => { GetConfiguration('hc.center')['payday.info'] && - +

{ LocalizeText('hccenter.special.title') }

{ LocalizeText('hccenter.special.info') }
diff --git a/src/components/navigator/NavigatorView.tsx b/src/components/navigator/NavigatorView.tsx index dcc2f9eb2..90e477237 100644 --- a/src/components/navigator/NavigatorView.tsx +++ b/src/components/navigator/NavigatorView.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RoomSessionEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api'; +import { AddEventLinkTracker, CreateLinkEvent, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api'; import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; import { useNavigator, useRoomSessionManagerEvent } from '../../hooks'; import { NavigatorDoorStateView } from './views/NavigatorDoorStateView'; @@ -77,9 +77,9 @@ export const NavigatorView: FC<{}> = props => linkReceived: (url: string) => { const parts = url.split('/'); - + if(parts.length < 2) return; - + switch(parts[1]) { case 'show': { @@ -94,10 +94,10 @@ export const NavigatorView: FC<{}> = props => if(isVisible) { setIsVisible(false); - + return; } - + setIsVisible(true); setNeedsSearch(true); return; @@ -110,17 +110,17 @@ export const NavigatorView: FC<{}> = props => return; case 'goto': if(parts.length <= 2) return; - + switch(parts[2]) { case 'home': if(navigatorData.homeRoomId <= 0) return; - + TryVisitRoom(navigatorData.homeRoomId); break; default: { const roomId = parseInt(parts[2]); - + TryVisitRoom(roomId); } } @@ -133,13 +133,13 @@ export const NavigatorView: FC<{}> = props => if(parts.length > 2) { const topLevelContextCode = parts[2]; - + let searchValue = ''; - + if(parts.length > 3) searchValue = parts[3]; - + pendingSearch.current = { value: searchValue, code: topLevelContextCode }; - + setIsVisible(true); setNeedsSearch(true); } @@ -197,7 +197,7 @@ export const NavigatorView: FC<{}> = props => <> { isVisible && - setIsVisible(false) } /> + CreateLinkEvent('habbopages/navigator') } onCloseClick={ event => setIsVisible(false) } /> { topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) => { diff --git a/src/components/room/widgets/chat-input/ChatInputView.scss b/src/components/room/widgets/chat-input/ChatInputView.scss index f650fa622..b02f7a356 100644 --- a/src/components/room/widgets/chat-input/ChatInputView.scss +++ b/src/components/room/widgets/chat-input/ChatInputView.scss @@ -37,7 +37,7 @@ vertical-align: top; height: 100%; padding: 0 10px; - + &::after, input, textarea { @@ -51,7 +51,7 @@ border: none; outline: none; } - + &::after { content: attr(data-value) ' '; visibility: hidden; @@ -82,3 +82,26 @@ } } } + +.info-habbopages { + cursor: pointer; + line-height: 1; + border-radius: $border-radius; + box-shadow: 0 0 0 1.6px $white; + border: 2px solid #1E7295; + background: repeating-linear-gradient( + rgba(30, 114, 149), + rgba(30, 114, 149) 50%, + rgb(9, 102, 133) 50%, + rgb(25, 96, 126) 100% + ); + margin-left: 6px; + + &:hover { + filter: brightness(1.2); + } + + &:active { + filter: brightness(0.8); + } +} diff --git a/src/components/room/widgets/chat-input/ChatInputView.tsx b/src/components/room/widgets/chat-input/ChatInputView.tsx index f5db0f434..c299b592a 100644 --- a/src/components/room/widgets/chat-input/ChatInputView.tsx +++ b/src/components/room/widgets/chat-input/ChatInputView.tsx @@ -1,14 +1,16 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { HabboClubLevelEnum, RoomControllerLevel } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; -import { ChatMessageTypeEnum, GetClubMemberLevel, GetConfiguration, GetRoomSession, GetSessionDataManager, LocalizeText, RoomWidgetUpdateChatInputContentEvent } from '../../../../api'; -import { Text } from '../../../../common'; +import { ChatMessageTypeEnum, CreateLinkEvent, GetClubMemberLevel, GetConfiguration, GetRoomSession, GetSessionDataManager, LocalizeText, RoomWidgetUpdateChatInputContentEvent } from '../../../../api'; +import { Base, Text } from '../../../../common'; import { useChatInputWidget, useSessionInfo, useUiEvent } from '../../../../hooks'; import { ChatInputStyleSelectorView } from './ChatInputStyleSelectorView'; export const ChatInputView: FC<{}> = props => { const [ chatValue, setChatValue ] = useState(''); + const [ showInfoHabboPages, setShowInfohabboPages ] = useState(false); const { chatStyleId = 0, updateChatStyleId = null } = useSessionInfo(); const { selectedUsername = '', floodBlocked = false, floodBlockedSeconds = 0, setIsTyping = null, setIsIdle = null, sendChat = null } = useChatInputWidget(); const inputRef = useRef(); @@ -234,7 +236,7 @@ export const ChatInputView: FC<{}> = props => return ( createPortal( -
+
setShowInfohabboPages(true) } onMouseLeave={ () => setTimeout(() => setShowInfohabboPages(false), 100) }>
{ !floodBlocked && updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } /> } @@ -242,6 +244,12 @@ export const ChatInputView: FC<{}> = props => { LocalizeText('chat.input.alert.flood', [ 'time' ], [ floodBlockedSeconds.toString() ]) } }
-
, document.getElementById('toolbar-chat-input-container')) + { (showInfoHabboPages) && + CreateLinkEvent('habbopages/chat/chatting') }> + + + } +
+ , document.getElementById('toolbar-chat-input-container')) ); } diff --git a/src/hooks/catalog/useCatalog.ts b/src/hooks/catalog/useCatalog.ts index 9317cc3f7..6572baa6e 100644 --- a/src/hooks/catalog/useCatalog.ts +++ b/src/hooks/catalog/useCatalog.ts @@ -265,7 +265,7 @@ const useCatalogState = () => const loadCatalogPage = useCallback((pageId: number, offerId: number) => { if(pageId < 0) return; - + setIsBusy(true); setPageId(pageId); @@ -285,9 +285,9 @@ const useCatalogState = () => for(const offer of catalogPage.offers) { if(offer.offerId !== offerId) continue; - + setCurrentOffer(offer) - + break; } } @@ -351,7 +351,7 @@ const useCatalogState = () => return nodes; }); - + if(targetNode.pageId > -1) loadCatalogPage(targetNode.pageId, offerId); }, [ setActiveNodes, loadCatalogPage, cancelObjectMover ]); @@ -544,9 +544,9 @@ const useCatalogState = () => setPurchaseOptions(prevValue => { const newValue = { ...prevValue }; - + newValue.extraData =( offer.product.extraParam || null); - + return newValue; }); } @@ -576,7 +576,7 @@ const useCatalogState = () => break; } } - + petPalettes.push(petPalette); return { ...prevValue, petPalettes }; @@ -636,7 +636,7 @@ const useCatalogState = () => } const message = LocalizeText(`inventory.marketplace.result.${ parser.result }`); - + simpleAlert(message, NotificationAlertType.DEFAULT, null, null, title); }); @@ -674,11 +674,11 @@ const useCatalogState = () => { const parser = event.getParser(); - setFurniLimit(parser._Str_15864); - setMaxFurniLimit(parser._Str_24094); - setSecondsLeft(parser._Str_3709); + setFurniLimit(parser.furniLimit); + setMaxFurniLimit(parser.maxFurniLimit); + setSecondsLeft(parser.secondsLeft); setUpdateTime(GetTickerTime()); - setSecondsLeftWithGrace(parser._Str_24379); + setSecondsLeftWithGrace(parser.secondsLeftWithGrace); refreshBuilderStatus(); }); @@ -757,7 +757,7 @@ const useCatalogState = () => if(roomObject) roomObject.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 0.5); - if(catalogSkipPurchaseConfirmation) + if(catalogSkipPurchaseConfirmation) { SendMessageComposer(new PurchaseFromCatalogComposer(pageId, purchasableOffer.offerId, product.extraParam, 1)); @@ -832,7 +832,7 @@ const useCatalogState = () => { return () => setCurrentOffer(null); }, [ currentPage ]); - + useEffect(() => { if(!isVisible || !rootNode || !offersToNodes || !requestedPage.current) return; @@ -881,7 +881,7 @@ const useCatalogState = () => setPurchaseOptions({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null }); }, [ currentOffer ]); - + useEffect(() => { if(!isVisible || rootNode) return;