216 lines
10 KiB
TypeScript
216 lines
10 KiB
TypeScript
import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomSessionFavoriteGroupUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, UserRelationshipsComposer } from '@nitrots/nitro-renderer';
|
|
import { Dispatch, FC, FocusEvent, KeyboardEvent, SetStateAction, useEffect, useState } from 'react';
|
|
import { FaPencilAlt, FaTimes } from 'react-icons/fa';
|
|
import { AvatarInfoUser, CloneObject, GetConfiguration, GetGroupInformation, GetSessionDataManager, GetUserProfile, LocalizeText, SendMessageComposer } from '../../../../../api';
|
|
import { Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, Text, UserProfileIconView } from '../../../../../common';
|
|
import { useMessageEvent, useRoom, useRoomSessionManagerEvent } from '../../../../../hooks';
|
|
import { InfoStandWidgetUserRelationshipsView } from './InfoStandWidgetUserRelationshipsView';
|
|
import { InfoStandWidgetUserTagsView } from './InfoStandWidgetUserTagsView';
|
|
|
|
interface InfoStandWidgetUserViewProps
|
|
{
|
|
avatarInfo: AvatarInfoUser;
|
|
setAvatarInfo: Dispatch<SetStateAction<AvatarInfoUser>>;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =>
|
|
{
|
|
const { avatarInfo = null, setAvatarInfo = null, onClose = null } = props;
|
|
const [ motto, setMotto ] = useState<string>(null);
|
|
const [ isEditingMotto, setIsEditingMotto ] = useState(false);
|
|
const [ relationships, setRelationships ] = useState<RelationshipStatusInfoMessageParser>(null);
|
|
const { roomSession = null } = useRoom();
|
|
|
|
const saveMotto = (motto: string) =>
|
|
{
|
|
if(!isEditingMotto || (motto.length > GetConfiguration<number>('motto.max.length', 38))) return;
|
|
|
|
roomSession.sendMottoMessage(motto);
|
|
|
|
setIsEditingMotto(false);
|
|
}
|
|
|
|
const onMottoBlur = (event: FocusEvent<HTMLInputElement>) => saveMotto(event.target.value);
|
|
|
|
const onMottoKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
|
{
|
|
event.stopPropagation();
|
|
|
|
switch(event.key)
|
|
{
|
|
case 'Enter':
|
|
saveMotto((event.target as HTMLInputElement).value);
|
|
return;
|
|
}
|
|
}
|
|
|
|
useRoomSessionManagerEvent<RoomSessionUserBadgesEvent>(RoomSessionUserBadgesEvent.RSUBE_BADGES, event =>
|
|
{
|
|
if(!avatarInfo || (avatarInfo.webID !== event.userId)) return;
|
|
|
|
const oldBadges = avatarInfo.badges.join('');
|
|
|
|
if(oldBadges === event.badges.join('')) return;
|
|
|
|
setAvatarInfo(prevValue =>
|
|
{
|
|
const newValue = CloneObject(prevValue);
|
|
|
|
newValue.badges = event.badges;
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useRoomSessionManagerEvent<RoomSessionUserFigureUpdateEvent>(RoomSessionUserFigureUpdateEvent.USER_FIGURE, event =>
|
|
{
|
|
if(!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
|
|
|
|
setAvatarInfo(prevValue =>
|
|
{
|
|
const newValue = CloneObject(prevValue);
|
|
|
|
newValue.figure = event.figure;
|
|
newValue.motto = event.customInfo;
|
|
newValue.achievementScore = event.activityPoints;
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useRoomSessionManagerEvent<RoomSessionFavoriteGroupUpdateEvent>(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, event =>
|
|
{
|
|
if(!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
|
|
|
|
setAvatarInfo(prevValue =>
|
|
{
|
|
const newValue = CloneObject(prevValue);
|
|
const clearGroup = ((event.status === -1) || (event.habboGroupId <= 0));
|
|
|
|
newValue.groupId = clearGroup ? -1 : event.habboGroupId;
|
|
newValue.groupName = clearGroup ? null : event.habboGroupName
|
|
newValue.groupBadgeId = clearGroup ? null : GetSessionDataManager().getGroupBadge(event.habboGroupId);
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useMessageEvent<RelationshipStatusInfoEvent>(RelationshipStatusInfoEvent, event =>
|
|
{
|
|
const parser = event.getParser();
|
|
|
|
if(!avatarInfo || (avatarInfo.webID !== parser.userId)) return;
|
|
|
|
setRelationships(parser);
|
|
});
|
|
|
|
useEffect(() =>
|
|
{
|
|
setIsEditingMotto(false);
|
|
setMotto(avatarInfo.motto);
|
|
|
|
SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID));
|
|
|
|
return () =>
|
|
{
|
|
setIsEditingMotto(false);
|
|
setMotto(null);
|
|
setRelationships(null);
|
|
}
|
|
}, [ avatarInfo ]);
|
|
|
|
if(!avatarInfo) return null;
|
|
|
|
return (
|
|
<Column className="nitro-infostand rounded">
|
|
<Column overflow="visible" className="container-fluid content-area" gap={ 1 }>
|
|
<Column gap={ 1 }>
|
|
<Flex alignItems="center" justifyContent="between">
|
|
<Flex alignItems="center" gap={ 1 }>
|
|
<UserProfileIconView userId={ avatarInfo.webID } />
|
|
<Text variant="white" small wrap>{ avatarInfo.name }</Text>
|
|
</Flex>
|
|
<FaTimes className="cursor-pointer fa-icon" onClick={ onClose } />
|
|
</Flex>
|
|
<hr className="m-0" />
|
|
</Column>
|
|
<Column gap={ 1 }>
|
|
<Flex gap={ 1 }>
|
|
<Column fullWidth className="body-image" onClick={ event => GetUserProfile(avatarInfo.webID) }>
|
|
<LayoutAvatarImageView figure={ avatarInfo.figure } direction={ 4 } />
|
|
</Column>
|
|
<Column grow alignItems="center" gap={ 0 }>
|
|
<Flex gap={ 1 }>
|
|
<Flex center className="badge-image">
|
|
{ avatarInfo.badges[0] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[0] } showInfo={ true } /> }
|
|
</Flex>
|
|
<Flex center pointer={ ( avatarInfo.groupId > 0) } className="badge-image" onClick={ event => GetGroupInformation(avatarInfo.groupId) }>
|
|
{ avatarInfo.groupId > 0 &&
|
|
<LayoutBadgeImageView badgeCode={ avatarInfo.groupBadgeId } isGroup={ true } showInfo={ true } customTitle={ avatarInfo.groupName } /> }
|
|
</Flex>
|
|
</Flex>
|
|
<Flex center gap={ 1 }>
|
|
<Flex center className="badge-image">
|
|
{ avatarInfo.badges[1] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[1] } showInfo={ true } /> }
|
|
</Flex>
|
|
<Flex center className="badge-image">
|
|
{ avatarInfo.badges[2] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[2] } showInfo={ true } /> }
|
|
</Flex>
|
|
</Flex>
|
|
<Flex center gap={ 1 }>
|
|
<Flex center className="badge-image">
|
|
{ avatarInfo.badges[3] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[3] } showInfo={ true } /> }
|
|
</Flex>
|
|
<Flex center className="badge-image">
|
|
{ avatarInfo.badges[4] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[4] } showInfo={ true } /> }
|
|
</Flex>
|
|
</Flex>
|
|
</Column>
|
|
</Flex>
|
|
<hr className="m-0" />
|
|
</Column>
|
|
<Column gap={ 1 }>
|
|
<Flex alignItems="center" className="bg-light-dark rounded py-1 px-2">
|
|
{ (avatarInfo.type !== AvatarInfoUser.OWN_USER) &&
|
|
<Flex grow alignItems="center" className="motto-content">
|
|
<Text fullWidth pointer wrap textBreak small variant="white">{ motto }</Text>
|
|
</Flex> }
|
|
{ avatarInfo.type === AvatarInfoUser.OWN_USER &&
|
|
<Flex grow alignItems="center" gap={ 2 }>
|
|
<FaPencilAlt className="small fa-icon" />
|
|
<Flex grow alignItems="center" className="motto-content">
|
|
{ !isEditingMotto &&
|
|
<Text fullWidth pointer wrap textBreak small variant="white" onClick={ event => setIsEditingMotto(true) }>{ motto } </Text> }
|
|
{ isEditingMotto &&
|
|
<input type="text" className="motto-input" maxLength={ GetConfiguration<number>('motto.max.length', 38) } value={ motto } onChange={ event => setMotto(event.target.value) } onBlur={ onMottoBlur } onKeyDown={ onMottoKeyDown } autoFocus={ true } /> }
|
|
</Flex>
|
|
</Flex> }
|
|
</Flex>
|
|
<hr className="m-0" />
|
|
</Column>
|
|
<Column gap={ 1 }>
|
|
<Text variant="white" small wrap>
|
|
{ LocalizeText('infostand.text.achievement_score') + ' ' + avatarInfo.achievementScore }
|
|
</Text>
|
|
{ (avatarInfo.carryItem > 0) &&
|
|
<>
|
|
<hr className="m-0" />
|
|
<Text variant="white" small wrap>
|
|
{ LocalizeText('infostand.text.handitem', [ 'item' ], [ LocalizeText('handitem' + avatarInfo.carryItem) ]) }
|
|
</Text>
|
|
</> }
|
|
</Column>
|
|
<Column gap={ 1 }>
|
|
<InfoStandWidgetUserRelationshipsView relationships={ relationships } />
|
|
</Column>
|
|
{ GetConfiguration('user.tags.enabled') &&
|
|
<Column gap={ 1 } className="mt-1">
|
|
<InfoStandWidgetUserTagsView tags={ GetSessionDataManager().tags } />
|
|
</Column>
|
|
}
|
|
</Column>
|
|
</Column>
|
|
);
|
|
}
|