From 820a147120d42c199d0665235d7a2a650958024c Mon Sep 17 00:00:00 2001 From: MyNameIsBatman Date: Tue, 31 Aug 2021 00:22:20 -0300 Subject: [PATCH] Groups updates --- src/api/groups/TryJoinGroup.ts | 7 +++ .../views/page/layout/GetCatalogLayout.tsx | 3 +- .../CatalogLayoutGuildCustomFurniView.tsx | 45 +++++++++++++- .../CatalogLayoutGuildFrontpageView.tsx | 28 +++++++++ .../CatalogLayoutGuildFrontpageView.types.ts | 4 ++ src/views/groups/GroupsMessageHandler.tsx | 27 ++++++++ src/views/groups/GroupsView.tsx | 49 +++++++++++++-- src/views/groups/context/GroupsContext.tsx | 14 +++++ .../groups/context/GroupsContext.types.ts | 61 +++++++++++++++++++ .../GroupInformationStandaloneView.tsx | 7 +-- .../information/GroupInformationView.tsx | 17 +++--- .../information/GroupInformationView.types.ts | 1 + .../GroupRoomInformationView.tsx | 8 +-- .../views/room-info/NavigatorRoomInfoView.tsx | 5 +- .../context-menu/FurnitureContextMenuView.tsx | 46 +++++++++++++- .../views/furni/InfoStandWidgetFurniView.tsx | 37 ++++++++--- 16 files changed, 318 insertions(+), 41 deletions(-) create mode 100644 src/api/groups/TryJoinGroup.ts create mode 100644 src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.tsx create mode 100644 src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.types.ts create mode 100644 src/views/groups/GroupsMessageHandler.tsx create mode 100644 src/views/groups/context/GroupsContext.tsx create mode 100644 src/views/groups/context/GroupsContext.types.ts diff --git a/src/api/groups/TryJoinGroup.ts b/src/api/groups/TryJoinGroup.ts new file mode 100644 index 00000000..607a8a27 --- /dev/null +++ b/src/api/groups/TryJoinGroup.ts @@ -0,0 +1,7 @@ +import { GroupJoinComposer } from '@nitrots/nitro-renderer'; +import { SendMessageHook } from '../../hooks'; + +export function TryJoinGroup(groupId: number): void +{ + SendMessageHook(new GroupJoinComposer(groupId)); +} diff --git a/src/views/catalog/views/page/layout/GetCatalogLayout.tsx b/src/views/catalog/views/page/layout/GetCatalogLayout.tsx index c7478d58..8fe64187 100644 --- a/src/views/catalog/views/page/layout/GetCatalogLayout.tsx +++ b/src/views/catalog/views/page/layout/GetCatalogLayout.tsx @@ -4,6 +4,7 @@ import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView'; import { CatalogLayoutFrontpage4View } from './frontpage4/CatalogLayoutFrontpage4View'; import { CatalogLayouGuildCustomFurniView } from './guild-custom-furni/CatalogLayoutGuildCustomFurniView'; import { CatalogLayouGuildForumView } from './guild-forum/CatalogLayoutGuildForumView'; +import { CatalogLayouGuildFrontpageView } from './guild-frontpage/CatalogLayoutGuildFrontpageView'; import { CatalogLayoutInfoLoyaltyView } from './info-loyalty/CatalogLayoutInfoLoyaltyView'; import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView'; import { CatalogLayoutPets2View } from './pets2/CatalogLayoutPets2View'; @@ -30,7 +31,7 @@ export const GetCatalogLayout = (pageParser: CatalogPageMessageParser, roomPrevi case 'vip_buy': return ; case 'guild_frontpage': - return null; + return ; case 'guild_forum': return ; case 'guild_custom_furni': diff --git a/src/views/catalog/views/page/layout/guild-custom-furni/CatalogLayoutGuildCustomFurniView.tsx b/src/views/catalog/views/page/layout/guild-custom-furni/CatalogLayoutGuildCustomFurniView.tsx index 10b69879..73b94416 100644 --- a/src/views/catalog/views/page/layout/guild-custom-furni/CatalogLayoutGuildCustomFurniView.tsx +++ b/src/views/catalog/views/page/layout/guild-custom-furni/CatalogLayoutGuildCustomFurniView.tsx @@ -1,7 +1,8 @@ -import { CatalogGroupsComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect } from 'react'; +import { CatalogGroupsComposer, StringDataType } from '@nitrots/nitro-renderer'; +import { FC, useEffect, useState } from 'react'; import { LocalizeText } from '../../../../../../api'; import { SendMessageHook } from '../../../../../../hooks/messages'; +import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView'; import { GetOfferName } from '../../../../common/CatalogUtilities'; import { useCatalogContext } from '../../../../context/CatalogContext'; import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView'; @@ -18,10 +19,31 @@ export const CatalogLayouGuildCustomFurniView: FC(0); + useEffect(() => { SendMessageHook(new CatalogGroupsComposer()); }, [ pageParser ]); + + useEffect(() => + { + if(!groups[selectedGroupIndex]) return; + + const productData = []; + productData.push('0'); + productData.push(groups[selectedGroupIndex].groupId); + productData.push(groups[selectedGroupIndex].badgeCode); + productData.push(groups[selectedGroupIndex].colorA); + productData.push(groups[selectedGroupIndex].colorB); + + const stringDataType = new StringDataType(); + stringDataType.setValue(productData); + + roomPreviewer.updateObjectStuffData(stringDataType); + }, [ selectedGroupIndex, activeOffer ]); + + if(!groups) return null; return (
@@ -30,13 +52,30 @@ export const CatalogLayouGuildCustomFurniView: FC { product &&
+ { groups[selectedGroupIndex] &&
+ +
}
{ GetOfferName(activeOffer) }
{ groups.length === 0 &&
{ LocalizeText('catalog.guild_selector.members_only') }
} - { groups.length > 0 && } + { groups.length > 0 && <> +
+
+
+
+
+ +
+ + }
}
); diff --git a/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.tsx b/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.tsx new file mode 100644 index 00000000..06dbb7f9 --- /dev/null +++ b/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.tsx @@ -0,0 +1,28 @@ +import { FC } from 'react'; +import { CreateLinkEvent, LocalizeText } from '../../../../../../api'; +import { GetCatalogPageImage, GetCatalogPageText } from '../../../../common/CatalogUtilities'; +import { useCatalogContext } from '../../../../context/CatalogContext'; +import { CatalogLayoutGuildFrontpageViewProps } from './CatalogLayoutGuildFrontpageView.types'; + +export const CatalogLayouGuildFrontpageView: FC = props => +{ + const { pageParser = null } = props; + + const { catalogState = null, dispatchCatalogState = null } = useCatalogContext(); + + return ( +
+
+
+
+
+
+ +
+
+
CreateLinkEvent('groups/create') }> + +
+
+ ); +} diff --git a/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.types.ts b/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.types.ts new file mode 100644 index 00000000..9ff88511 --- /dev/null +++ b/src/views/catalog/views/page/layout/guild-frontpage/CatalogLayoutGuildFrontpageView.types.ts @@ -0,0 +1,4 @@ +import { CatalogLayoutProps } from '../CatalogLayout.types'; + +export interface CatalogLayoutGuildFrontpageViewProps extends CatalogLayoutProps +{} diff --git a/src/views/groups/GroupsMessageHandler.tsx b/src/views/groups/GroupsMessageHandler.tsx new file mode 100644 index 00000000..54299d25 --- /dev/null +++ b/src/views/groups/GroupsMessageHandler.tsx @@ -0,0 +1,27 @@ +import { GroupBadgePartsEvent } from '@nitrots/nitro-renderer'; +import { FC, useCallback } from 'react'; +import { CreateMessageHook } from '../../hooks'; +import { useGroupsContext } from './context/GroupsContext'; +import { GroupsActions } from './context/GroupsContext.types'; + +export const GroupsMessageHandler: FC<{}> = props => +{ + const { groupsState = null, dispatchGroupsState = null } = useGroupsContext(); + + const onGroupBadgePartsEvent = useCallback((event: GroupBadgePartsEvent) => + { + const parser = event.getParser(); + + dispatchGroupsState({ + type: GroupsActions.SET_BADGE_PARTS, + payload: { + arrayMaps: [ parser.bases, parser.symbols ], + stringMaps: [ parser.partColors, parser.colorsA, parser.colorsB ] + } + }) + }, [ dispatchGroupsState ]); + + CreateMessageHook(GroupBadgePartsEvent, onGroupBadgePartsEvent); + + return null; +}; diff --git a/src/views/groups/GroupsView.tsx b/src/views/groups/GroupsView.tsx index c4e95a69..85cc0cb7 100644 --- a/src/views/groups/GroupsView.tsx +++ b/src/views/groups/GroupsView.tsx @@ -1,11 +1,50 @@ -import { FC } from 'react'; -import { GroupInformationBoxView } from './views/information-standalone/GroupInformationStandaloneView'; +import { GroupBadgePartsComposer, ILinkEventTracker } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useReducer } from 'react'; +import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api'; +import { SendMessageHook } from '../../hooks'; +import { GroupsContextProvider } from './context/GroupsContext'; +import { GroupsReducer, initialGroups } from './context/GroupsContext.types'; +import { GroupsMessageHandler } from './GroupsMessageHandler'; +import { GroupInformationStandaloneView } from './views/information-standalone/GroupInformationStandaloneView'; export const GroupsView: FC<{}> = props => { + const [ groupsState, dispatchGroupsState ] = useReducer(GroupsReducer, initialGroups); + + useEffect(() => + { + SendMessageHook(new GroupBadgePartsComposer()); + }, []); + + const linkReceived = useCallback((url: string) => + { + const parts = url.split('/'); + + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'create': + return; + } + }, []); + + useEffect(() => + { + const linkTracker: ILinkEventTracker = { + linkReceived, + eventUrlPrefix: 'groups/' + }; + + AddEventLinkTracker(linkTracker); + + return () => RemoveLinkEventTracker(linkTracker); + }, [ linkReceived ]); + return ( - <> - - + + + + ); }; diff --git a/src/views/groups/context/GroupsContext.tsx b/src/views/groups/context/GroupsContext.tsx new file mode 100644 index 00000000..27eb2078 --- /dev/null +++ b/src/views/groups/context/GroupsContext.tsx @@ -0,0 +1,14 @@ +import { createContext, FC, useContext } from 'react'; +import { GroupsContextProps, IGroupsContext } from './GroupsContext.types'; + +const GroupsContext = createContext({ + groupsState: null, + dispatchGroupsState: null +}); + +export const GroupsContextProvider: FC = props => +{ + return { props.children } +} + +export const useGroupsContext = () => useContext(GroupsContext); diff --git a/src/views/groups/context/GroupsContext.types.ts b/src/views/groups/context/GroupsContext.types.ts new file mode 100644 index 00000000..1bc4b089 --- /dev/null +++ b/src/views/groups/context/GroupsContext.types.ts @@ -0,0 +1,61 @@ +import { Dispatch, ProviderProps, Reducer } from 'react'; + +export interface IGroupsContext +{ + groupsState: IGroupsState; + dispatchGroupsState: Dispatch; +} + +export interface GroupsContextProps extends ProviderProps +{ + +} + +export interface IGroupsState +{ + badgeBases: Map; + badgeSymbols: Map; + badgePartColors: Map; + groupColorsA: Map; + groupColorsB: Map; +} + +export interface IGroupsAction +{ + type: string; + payload: { + arrayMaps?: Map[]; + stringMaps?: Map[]; + } +} + +export class GroupsActions +{ + public static SET_BADGE_PARTS: string = 'GA_SET_BADGE_PARTS'; +} + +export const initialGroups: IGroupsState = { + badgeBases: null, + badgeSymbols: null, + badgePartColors: null, + groupColorsA: null, + groupColorsB: null +}; + +export const GroupsReducer: Reducer = (state, action) => +{ + switch(action.type) + { + case GroupsActions.SET_BADGE_PARTS: { + const badgeBases = (action.payload.arrayMaps[0] || state.badgeBases || null); + const badgeSymbols = (action.payload.arrayMaps[1] || state.badgeSymbols || null); + const badgePartColors = (action.payload.stringMaps[0] || state.badgePartColors || null); + const groupColorsA = (action.payload.stringMaps[1] || state.groupColorsA || null); + const groupColorsB = (action.payload.stringMaps[2] || state.groupColorsB || null); + + return { ...state, badgeBases, badgeSymbols, badgePartColors, groupColorsA, groupColorsB }; + } + default: + return state; + } +} diff --git a/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx index 5d43f920..73666c57 100644 --- a/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx +++ b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx @@ -5,7 +5,7 @@ import { CreateMessageHook } from '../../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; import { GroupInformationView } from '../information/GroupInformationView'; -export const GroupInformationBoxView: FC<{}> = props => +export const GroupInformationStandaloneView: FC<{}> = props => { const [ groupInformation, setGroupInformation ] = useState(null); @@ -15,10 +15,9 @@ export const GroupInformationBoxView: FC<{}> = props => if(!parser.flag) return; - if(groupInformation) setGroupInformation(null); - + setGroupInformation(null); setGroupInformation(parser); - }, [ groupInformation ]); + }, []); CreateMessageHook(GroupInformationEvent, onGroupInformationEvent); diff --git a/src/views/groups/views/information/GroupInformationView.tsx b/src/views/groups/views/information/GroupInformationView.tsx index 8d4837d0..8f13cf28 100644 --- a/src/views/groups/views/information/GroupInformationView.tsx +++ b/src/views/groups/views/information/GroupInformationView.tsx @@ -1,6 +1,7 @@ -import { GroupDeleteComposer, GroupInformationComposer, GroupJoinComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; +import { GroupDeleteComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback } from 'react'; import { CreateLinkEvent, GetSessionDataManager, LocalizeText, TryVisitRoom } from '../../../../api'; +import { TryJoinGroup } from '../../../../api/groups/TryJoinGroup'; import { SendMessageHook } from '../../../../hooks'; import { CatalogPageName } from '../../../catalog/common/CatalogPageName'; import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; @@ -12,18 +13,16 @@ export const GroupInformationView: FC = props => { const { groupInformation = null, onClose = null } = props; - const tryJoinGroup = useCallback(() => + const joinGroup = useCallback(() => { if(!groupInformation) return; - SendMessageHook(new GroupJoinComposer(groupInformation.id)); - SendMessageHook(new GroupInformationComposer(groupInformation.id, false)); + TryJoinGroup(groupInformation.id); }, [ groupInformation ]); - const tryLeaveGroup = useCallback(() => + const leaveGroup = useCallback(() => { SendMessageHook(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId)); - SendMessageHook(new GroupInformationComposer(groupInformation.id, false)); if(onClose) onClose(); }, [ groupInformation, onClose ]); @@ -67,10 +66,10 @@ export const GroupInformationView: FC = props => { if(groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return; - if(groupInformation.membershipType === GroupMembershipType.MEMBER) return tryLeaveGroup(); + if(groupInformation.membershipType === GroupMembershipType.MEMBER) return leaveGroup(); - return tryJoinGroup(); - }, [ groupInformation, tryLeaveGroup, tryJoinGroup ]); + return joinGroup(); + }, [ groupInformation, leaveGroup, joinGroup ]); const handleAction = useCallback((action: string) => { diff --git a/src/views/groups/views/information/GroupInformationView.types.ts b/src/views/groups/views/information/GroupInformationView.types.ts index b8544e6f..1d4abad6 100644 --- a/src/views/groups/views/information/GroupInformationView.types.ts +++ b/src/views/groups/views/information/GroupInformationView.types.ts @@ -3,5 +3,6 @@ import { GroupInformationParser } from '@nitrots/nitro-renderer'; export interface GroupInformationViewProps { groupInformation: GroupInformationParser; + onJoin?: () => void; onClose?: () => void; } diff --git a/src/views/groups/views/room-information/GroupRoomInformationView.tsx b/src/views/groups/views/room-information/GroupRoomInformationView.tsx index 1daeb313..349f2500 100644 --- a/src/views/groups/views/room-information/GroupRoomInformationView.tsx +++ b/src/views/groups/views/room-information/GroupRoomInformationView.tsx @@ -70,9 +70,9 @@ export const GroupRoomInformationView: FC<{}> = props => const getButtonText = useCallback(() => { - if(groupInformation.type === GroupType.PRIVATE) return ''; + if(isRealOwner()) return 'group.manage'; - if(isRealOwner()) return 'group.youareowner'; + if(groupInformation.type === GroupType.PRIVATE) return ''; if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave'; @@ -112,8 +112,8 @@ export const GroupRoomInformationView: FC<{}> = props => { groupInformation.title }
- { groupInformation.type !== GroupType.PRIVATE && !isRealOwner() && - } diff --git a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx index f85de960..2c61e2d7 100644 --- a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx +++ b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx @@ -1,7 +1,7 @@ import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer'; import classNames from 'classnames'; import { FC, useCallback, useEffect, useState } from 'react'; -import { GetConfiguration, GetSessionDataManager, LocalizeText } from '../../../../api'; +import { GetConfiguration, GetGroupInformation, GetSessionDataManager, LocalizeText } from '../../../../api'; import { NavigatorEvent } from '../../../../events'; import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail'; import { dispatchUiEvent } from '../../../../hooks/events'; @@ -82,6 +82,7 @@ export const NavigatorRoomInfoView: FC = props => dispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL)); return; case 'open_group_info': + GetGroupInformation(roomInfoData.enteredGuestRoom.habboGroupId); return; case 'toggle_room_link': dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)); @@ -137,7 +138,7 @@ export const NavigatorRoomInfoView: FC = props =>
{ roomInfoData.enteredGuestRoom.description }
- processAction('open_room_thumbnail_camera') } /> + { hasPermission('settings') && processAction('open_room_thumbnail_camera') } /> } { roomThumbnail && }
{ roomInfoData.enteredGuestRoom.habboGroupId > 0 &&
processAction('open_group_info') }> diff --git a/src/views/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx b/src/views/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx index 8082e242..0189c308 100644 --- a/src/views/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx +++ b/src/views/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx @@ -1,6 +1,9 @@ -import { ContextMenuEnum, RoomEngineTriggerWidgetEvent, RoomObjectCategory } from '@nitrots/nitro-renderer'; +import { ContextMenuEnum, FurnitureGroupInfoComposer, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; +import { GroupFurniContextMenuInfoMessageEvent } from '@nitrots/nitro-renderer/src/nitro/communication/messages/incoming/room/furniture/GroupFurniContextMenuInfoMessageEvent'; import { FC, useCallback, useState } from 'react'; -import { GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage } from '../../../../../api'; +import { GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryVisitRoom } from '../../../../../api'; +import { TryJoinGroup } from '../../../../../api/groups/TryJoinGroup'; +import { CreateMessageHook, SendMessageHook } from '../../../../../hooks'; import { useRoomEngineEvent } from '../../../../../hooks/events'; import { useRoomContext } from '../../../context/RoomContext'; import { ContextMenuView } from '../../context-menu/ContextMenuView'; @@ -18,6 +21,9 @@ export const FurnitureContextMenuView: FC<{}> = props => const [ mode, setMode ] = useState(null); const [ confirmMode, setConfirmMode ] = useState(null); const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1); + const [ groupData, setGroupData ] = useState(null); + const [ isGroupMember, setIsGroupMember ] = useState(false); + const { roomSession = null, widgetHandler = null } = useRoomContext(); const close = useCallback(() => @@ -71,6 +77,9 @@ export const FurnitureContextMenuView: FC<{}> = props => case ContextMenuEnum.PURCHASABLE_CLOTHING: if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING); return; + case ContextMenuEnum.GROUP_FURNITURE: + SendMessageHook(new FurnitureGroupInfoComposer(object.id, object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID))); + return; } return; @@ -85,6 +94,18 @@ export const FurnitureContextMenuView: FC<{}> = props => useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent); useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent); + const onGroupFurniContextMenuInfoMessageEvent = useCallback((event: GroupFurniContextMenuInfoMessageEvent) => + { + const parser = event.getParser(); + + setGroupData(null); + setGroupData(parser); + setIsGroupMember(parser.userIsMember); + setMode(ContextMenuEnum.GROUP_FURNITURE); + }, []); + + CreateMessageHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent); + const processAction = useCallback((name: string) => { if(name) @@ -105,11 +126,18 @@ export const FurnitureContextMenuView: FC<{}> = props => setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION); setConfirmingObjectId(objectId); break; + case 'join_group': + TryJoinGroup(groupData.guildId); + setIsGroupMember(true); + return; + case 'go_to_group_homeroom': + if(groupData) TryVisitRoom(groupData.guildHomeRoomId); + break; } } close(); - }, [ roomSession, widgetHandler, objectId, close ]); + }, [ roomSession, widgetHandler, objectId, groupData, close ]); return ( <> @@ -153,6 +181,18 @@ export const FurnitureContextMenuView: FC<{}> = props => { LocalizeText('widget.generic_usable.button.use') } } + { (mode === ContextMenuEnum.GROUP_FURNITURE) && groupData && + <> + + { groupData.guildName } + + { !isGroupMember && processAction('join_group') }> + { LocalizeText('widget.furniture.button.join.group') } + } + processAction('go_to_group_homeroom') }> + { LocalizeText('widget.furniture.button.go.to.group.home.room') } + + } } ) diff --git a/src/views/room/widgets/infostand/views/furni/InfoStandWidgetFurniView.tsx b/src/views/room/widgets/infostand/views/furni/InfoStandWidgetFurniView.tsx index d68bd6a8..1c918dc6 100644 --- a/src/views/room/widgets/infostand/views/furni/InfoStandWidgetFurniView.tsx +++ b/src/views/room/widgets/infostand/views/furni/InfoStandWidgetFurniView.tsx @@ -1,7 +1,7 @@ -import { CrackableDataType, RoomControllerLevel, RoomObjectCategory, RoomObjectVariable, RoomWidgetEnumItemExtradataParameter, RoomWidgetFurniInfoUsagePolicyEnum, SetObjectDataMessageComposer, StringDataType, UserProfileComposer } from '@nitrots/nitro-renderer'; +import { CrackableDataType, GroupInformationComposer, GroupInformationEvent, RoomControllerLevel, RoomObjectCategory, RoomObjectVariable, RoomWidgetEnumItemExtradataParameter, RoomWidgetFurniInfoUsagePolicyEnum, SetObjectDataMessageComposer, StringDataType } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { CreateLinkEvent, GetRoomEngine, LocalizeText, RoomWidgetFurniActionMessage } from '../../../../../../api'; -import { SendMessageHook } from '../../../../../../hooks'; +import { CreateLinkEvent, GetGroupInformation, GetRoomEngine, LocalizeText, RoomWidgetFurniActionMessage } from '../../../../../../api'; +import { CreateMessageHook, SendMessageHook } from '../../../../../../hooks'; import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView'; import { LimitedEditionCompactPlateView } from '../../../../../shared/limited-edition/compact-plate/LimitedEditionCompactPlateView'; import { RarityLevelView } from '../../../../../shared/rarity-level/RarityLevelView'; @@ -31,6 +31,7 @@ export const InfoStandWidgetFurniView: FC = props const [ crackableHits, setCrackableHits ] = useState(0); const [ crackableTarget, setCrackableTarget ] = useState(0); const [ godMode, setGodMode ] = useState(false); + const [ groupName, setGroupName ] = useState(null); useEffect(() => { @@ -128,12 +129,23 @@ export const InfoStandWidgetFurniView: FC = props setCrackableHits(crackableHits); setCrackableTarget(crackableTarget); setGodMode(godMode); + setGroupName(null); + + if(furniData.groupId) SendMessageHook(new GroupInformationComposer(furniData.groupId, false)); }, [ roomSession, furniData ]); - const openFurniGroupInfo = useCallback(() => + const onGroupInformationEvent = useCallback((event: GroupInformationEvent) => { + const parser = event.getParser(); - }, []); + if(!furniData || furniData.groupId !== parser.id || parser.flag) return; + + if(groupName) setGroupName(null); + + setGroupName(parser.title); + }, [ furniData, groupName ]); + + CreateMessageHook(GroupInformationEvent, onGroupInformationEvent); const onFurniSettingChange = useCallback((index: number, value: string) => { @@ -223,9 +235,13 @@ export const InfoStandWidgetFurniView: FC = props widgetHandler.processWidgetMessage(new RoomWidgetFurniActionMessage(messageType, furniData.id, furniData.category, furniData.purchaseOfferId, objectData)); }, [ widgetHandler, furniData, pickupMode, customKeys, customValues, getFurniSettingsAsString ]); - const openProfile = useCallback(() => + const getGroupBadgeCode = useCallback(() => { - SendMessageHook(new UserProfileComposer(furniData.ownerId)); + const stringDataType = (furniData.stuffData as StringDataType); + + if(!stringDataType || !(stringDataType instanceof StringDataType)) return null; + + return stringDataType.getValue(2); }, [ furniData ]); if(!furniData) return null; @@ -258,11 +274,12 @@ export const InfoStandWidgetFurniView: FC = props
{ LocalizeText('infostand.crackable_furni.hits_remaining', [ 'hits', 'target' ], [ crackableHits.toString(), crackableTarget.toString() ]) }
} - { (furniData.groupId > 0) && + { furniData.groupId > 0 && <>
-
- +
GetGroupInformation(furniData.groupId) }> + +
{ groupName }
} { godMode &&