GroupRoomInformationView.tsx 7.4 Ko
Télécharger le fichier
import {
DesktopViewEvent,
GetGuestRoomResultEvent,
GetSessionDataManager,
GroupInformationComposer,
GroupInformationEvent,
GroupInformationParser,
HabboGroupDeactivatedMessageEvent,
RoomEntryInfoMessageEvent
} from '@octane/renderer';
import { FC, useEffect, useRef, useState } from 'react';
import { GetGroupInformation, GetGroupManager, GroupMembershipType, GroupType, LocalizeText, SendMessageComposer, TryJoinGroup } from '../../../api';
import groupBaseIcon from '../../../assets/images/groups/swf/group_base_icon.png';
import { Button, Flex, LayoutBadgeImageView, Text } from '../../../common';
import { useGroupLeave, useMessageEvent } from '../../../hooks';
import { BaseButton } from '../../../common/BaseButton';
import { NativeTextTree } from '../../../common/native-text/NativeTextTree';
export const GroupRoomInformationView: FC<{}> = (props) => {
const expectedGroupIdRef = useRef<number>(0);
const requestRetryCountRef = useRef<number>(0);
const requestRetryTimeoutRef = useRef<ReturnType<typeof setTimeout>>(null);
const [groupInformation, setGroupInformation] = useState<GroupInformationParser>(null);
const [isOpen, setIsOpen] = useState<boolean>(true);
const clearRequestRetryTimeout = () => {
if (!requestRetryTimeoutRef.current) return;
clearTimeout(requestRetryTimeoutRef.current);
requestRetryTimeoutRef.current = null;
};
const scheduleGroupInfoRetry = (groupId: number) => {
if (requestRetryCountRef.current >= 2) return;
clearRequestRetryTimeout();
requestRetryTimeoutRef.current = setTimeout(() => {
requestRetryTimeoutRef.current = null;
if (expectedGroupIdRef.current !== groupId) return;
if (groupInformation && groupInformation.id === groupId) return;
requestRetryCountRef.current++;
SendMessageComposer(new GroupInformationComposer(groupId, false));
scheduleGroupInfoRetry(groupId);
}, 700);
};
const requestGroupInformation = (groupId: number) => {
if (groupId <= 0) return;
requestRetryCountRef.current = 0;
clearRequestRetryTimeout();
SendMessageComposer(new GroupInformationComposer(groupId, false));
scheduleGroupInfoRetry(groupId);
};
const resetGroupState = () => {
expectedGroupIdRef.current = 0;
requestRetryCountRef.current = 0;
clearRequestRetryTimeout();
setGroupInformation(null);
};
const setRequestedGroupId = (groupId: number) => {
expectedGroupIdRef.current = groupId;
};
useMessageEvent<DesktopViewEvent>(DesktopViewEvent, (event) => {
resetGroupState();
});
useMessageEvent<RoomEntryInfoMessageEvent>(RoomEntryInfoMessageEvent, (event) => {
resetGroupState();
});
useMessageEvent<GetGuestRoomResultEvent>(GetGuestRoomResultEvent, (event) => {
const parser = event.getParser();
if (!parser.roomEnter) return;
if (parser.data.habboGroupId > 0) {
setRequestedGroupId(parser.data.habboGroupId);
requestGroupInformation(parser.data.habboGroupId);
} else {
resetGroupState();
}
});
useMessageEvent<HabboGroupDeactivatedMessageEvent>(HabboGroupDeactivatedMessageEvent, (event) => {
const parser = event.getParser();
if (!groupInformation || (parser.groupId !== groupInformation.id && parser.groupId !== expectedGroupIdRef.current)) return;
resetGroupState();
});
useMessageEvent<GroupInformationEvent>(GroupInformationEvent, (event) => {
const parser = event.getParser();
if (parser.id !== expectedGroupIdRef.current) return;
clearRequestRetryTimeout();
setGroupInformation(parser);
});
useEffect(() => () => clearRequestRetryTimeout(), []);
// The official leave: ask the server what leaving costs, then confirm (shared with the group windows).
const leaveGroup = useGroupLeave(groupInformation?.id ?? 0);
const isRealOwner = groupInformation && groupInformation.ownerName === GetSessionDataManager().userName;
const getButtonText = () => {
if (isRealOwner) return 'group.manage';
if (groupInformation.type === GroupType.PRIVATE) return '';
if (groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave';
if (groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && groupInformation.type === GroupType.REGULAR) return 'group.join';
if (groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending';
if (groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && groupInformation.type === GroupType.EXCLUSIVE)
return 'group.requestmembership';
};
const handleButtonClick = () => {
if (isRealOwner) return GetGroupManager(groupInformation.id);
if (groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return;
if (groupInformation.membershipType === GroupMembershipType.MEMBER) {
leaveGroup();
return;
}
TryJoinGroup(groupInformation.id);
};
if (!groupInformation) return null;
return (
<NativeTextTree>
<div className={`octane-group-room-info pointer-events-auto ml-auto mt-[6px] overflow-hidden ${isOpen ? 'is-open' : 'is-closed'}`}>
<BaseButton type="button" className="octane-group-room-info__contracted" onClick={() => setIsOpen((value) => !value)}>
<img src={groupBaseIcon} alt="" className="octane-group-room-info__base-icon" draggable={false} />
<Text variant="white" className="octane-group-room-info__title">
{LocalizeText('group.homeroominfo.title')}
</Text>
<span className="octane-group-room-info__toggle" />
</BaseButton>
<div className="octane-group-room-info__content">
<Flex component={BaseButton} type="button" pointer alignItems="center" className="octane-group-room-info__main" onClick={() => GetGroupInformation(groupInformation.id)}>
<div className="octane-group-room-info__badge">
<LayoutBadgeImageView badgeCode={groupInformation.badge} isGroup={true} />
</div>
<Text wrap variant="white" className="octane-group-room-info__group-name">
{groupInformation.title}
</Text>
</Flex>
{(groupInformation.type !== GroupType.PRIVATE || isRealOwner) && (
<div className="octane-group-room-info__button-wrap">
<Button
fullWidth
disabled={groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING}
className="octane-groups-button octane-group-room-info__button"
onClick={handleButtonClick}
>
{LocalizeText(getButtonText())}
</Button>
</div>
)}
</div>
</div>
</NativeTextTree>
);
};
