🆙 Added Avatar Direction to backgrounds

This commit is contained in:
DuckieTM 2025-05-24 19:23:51 +02:00
parent a4d59ca162
commit 917912b909
3 changed files with 627 additions and 341 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,13 @@ import { useRoom } from '../../hooks';
import { HabboClubLevelEnum } from '@nitrots/nitro-renderer'; import { HabboClubLevelEnum } from '@nitrots/nitro-renderer';
import { GetClubMemberLevel, GetConfiguration, GetSessionDataManager } from '../../api'; import { GetClubMemberLevel, GetConfiguration, GetSessionDataManager } from '../../api';
interface ItemData { interface ItemData {
id: number; id: number;
isHcOnly: boolean; isHcOnly: boolean;
minRank: number; minRank: number;
isAmbassadorOnly: boolean; isAmbassadorOnly: boolean;
selectable: boolean; selectable: boolean;
AvatarDirection: number;
} }
interface BackgroundsViewProps { interface BackgroundsViewProps {
@ -20,6 +21,9 @@ interface BackgroundsViewProps {
setSelectedStand: Dispatch<SetStateAction<number>>; setSelectedStand: Dispatch<SetStateAction<number>>;
selectedOverlay: number; selectedOverlay: number;
setSelectedOverlay: Dispatch<SetStateAction<number>>; setSelectedOverlay: Dispatch<SetStateAction<number>>;
setBackgroundDirection: Dispatch<SetStateAction<number>>;
setStandDirection: Dispatch<SetStateAction<number>>;
setOverlayDirection: Dispatch<SetStateAction<number>>;
} }
const TABS = ['backgrounds', 'stands', 'overlays'] as const; const TABS = ['backgrounds', 'stands', 'overlays'] as const;
@ -32,11 +36,14 @@ export const BackgroundsView: FC<BackgroundsViewProps> = ({
selectedStand, selectedStand,
setSelectedStand, setSelectedStand,
selectedOverlay, selectedOverlay,
setSelectedOverlay setSelectedOverlay,
setBackgroundDirection,
setStandDirection,
setOverlayDirection
}) => { }) => {
const [activeTab, setActiveTab] = useState<TabType>('backgrounds'); const [activeTab, setActiveTab] = useState<TabType>('backgrounds');
const { roomSession } = useRoom(); const { roomSession } = useRoom();
const userData = useMemo(() => ({ const userData = useMemo(() => ({
isHcMember: GetClubMemberLevel() >= HabboClubLevelEnum.CLUB, isHcMember: GetClubMemberLevel() >= HabboClubLevelEnum.CLUB,
securityLevel: GetSessionDataManager().canChangeName, securityLevel: GetSessionDataManager().canChangeName,
@ -45,14 +52,19 @@ export const BackgroundsView: FC<BackgroundsViewProps> = ({
const processData = useCallback((configData: any[], dataType: string): ItemData[] => { const processData = useCallback((configData: any[], dataType: string): ItemData[] => {
if (!configData?.length) return []; if (!configData?.length) return [];
return configData return configData
.filter(item => { .filter(item => {
const meetsRank = userData.securityLevel >= item.minRank; const meetsRank = userData.securityLevel >= item.minRank;
const ambassadorEligible = !item.isAmbassadorOnly || userData.isAmbassador; const ambassadorEligible = !item.isAmbassadorOnly || userData.isAmbassador;
return item.isHcOnly || (meetsRank && ambassadorEligible); return item.isHcOnly || (meetsRank && ambassadorEligible);
}) })
.map(item => ({ id: item[`${dataType}Id`], ...item, selectable: !item.isHcOnly || userData.isHcMember })); .map(item => ({
id: item[`${dataType}Id`],
...item,
selectable: !item.isHcOnly || userData.isHcMember,
AvatarDirection: item.AvatarDirection ?? 4
}));
}, [userData]); }, [userData]);
const allData = useMemo(() => ({ const allData = useMemo(() => ({
@ -64,14 +76,45 @@ export const BackgroundsView: FC<BackgroundsViewProps> = ({
const handleSelection = useCallback((id: number) => { const handleSelection = useCallback((id: number) => {
if (!roomSession) return; if (!roomSession) return;
const setters = { backgrounds: setSelectedBackground, stands: setSelectedStand, overlays: setSelectedOverlay }; const setters = {
backgrounds: setSelectedBackground,
const currentValues = { backgrounds: selectedBackground, stands: selectedStand, overlays: selectedOverlay }; stands: setSelectedStand,
overlays: setSelectedOverlay
};
const directionSetters = {
backgrounds: setBackgroundDirection,
stands: setStandDirection,
overlays: setOverlayDirection
};
setters[activeTab](id); const currentValues = {
const newValues = { ...currentValues, [activeTab]: id }; backgrounds: selectedBackground,
roomSession.sendBackgroundMessage( newValues.backgrounds, newValues.stands, newValues.overlays ); stands: selectedStand,
}, [activeTab, roomSession, selectedBackground, selectedStand, selectedOverlay, setSelectedBackground, setSelectedStand, setSelectedOverlay]); overlays: selectedOverlay
};
const selectedItem = allData[activeTab].find(item => item.id === id);
if (selectedItem) {
setters[activeTab](id);
directionSetters[activeTab](selectedItem.AvatarDirection);
const newValues = { ...currentValues, [activeTab]: id };
roomSession.sendBackgroundMessage(newValues.backgrounds, newValues.stands, newValues.overlays);
}
}, [
activeTab,
roomSession,
selectedBackground,
selectedStand,
selectedOverlay,
setSelectedBackground,
setSelectedStand,
setSelectedOverlay,
setBackgroundDirection,
setStandDirection,
setOverlayDirection,
allData
]);
const renderItem = useCallback((item: ItemData, type: string) => ( const renderItem = useCallback((item: ItemData, type: string) => (
<Flex <Flex

View File

@ -8,62 +8,62 @@ import { InfoStandWidgetUserRelationshipsView } from './InfoStandWidgetUserRelat
import { InfoStandWidgetUserTagsView } from './InfoStandWidgetUserTagsView'; import { InfoStandWidgetUserTagsView } from './InfoStandWidgetUserTagsView';
import { BackgroundsView } from '../../../../backgrounds/BackgroundsView'; import { BackgroundsView } from '../../../../backgrounds/BackgroundsView';
interface InfoStandWidgetUserViewProps interface InfoStandWidgetUserViewProps {
{
avatarInfo: AvatarInfoUser; avatarInfo: AvatarInfoUser;
setAvatarInfo: Dispatch<SetStateAction<AvatarInfoUser>>; setAvatarInfo: Dispatch<SetStateAction<AvatarInfoUser>>;
onClose: () => void; onClose: () => void;
} }
export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props => export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props => {
{
const { avatarInfo = null, setAvatarInfo = null, onClose = null } = props; const { avatarInfo = null, setAvatarInfo = null, onClose = null } = props;
const [ motto, setMotto ] = useState<string>(null); const [motto, setMotto] = useState<string>(null);
const [ isEditingMotto, setIsEditingMotto ] = useState(false); const [isEditingMotto, setIsEditingMotto] = useState(false);
const [ relationships, setRelationships ] = useState<RelationshipStatusInfoMessageParser>(null); const [relationships, setRelationships] = useState<RelationshipStatusInfoMessageParser>(null);
const { roomSession = null } = useRoom(); const { roomSession = null } = useRoom();
const [ backgroundId, setBackgroundId ] = useState<number>(null); const [backgroundId, setBackgroundId] = useState<number>(null);
const [ standId, setStandId ] = useState<number>(null); const [standId, setStandId] = useState<number>(null);
const [ overlayId, setOverlayId ] = useState<number>(null); const [overlayId, setOverlayId] = useState<number>(null);
const [ isVisible, setIsVisible ] = useState(false); const [backgroundDirection, setBackgroundDirection] = useState<number>(2);
const [standDirection, setStandDirection] = useState<number>(2);
const [overlayDirection, setOverlayDirection] = useState<number>(2);
const [isVisible, setIsVisible] = useState(false);
const infostandBackgroundClass = `background-${ backgroundId }`; const infostandBackgroundClass = `background-${backgroundId}`;
const infostandStandClass = `stand-${ standId }`; const infostandStandClass = `stand-${standId}`;
const infostandOverlayClass = `overlay-${ overlayId }`; const infostandOverlayClass = `overlay-${overlayId}`;
const saveMotto = (motto: string) => // Compute the avatar direction: Overlay > Stand > Background
{ const avatarDirection = overlayDirection !== null && overlayDirection !== undefined ? overlayDirection :
if(!isEditingMotto || (motto.length > GetConfiguration<number>('motto.max.length', 38))) return; (standDirection !== null && standDirection !== undefined ? standDirection : backgroundDirection);
const saveMotto = (motto: string) => {
if (!isEditingMotto || (motto.length > GetConfiguration<number>('motto.max.length', 38))) return;
roomSession.sendMottoMessage(motto); roomSession.sendMottoMessage(motto);
setIsEditingMotto(false); setIsEditingMotto(false);
} };
const onMottoBlur = (event: FocusEvent<HTMLInputElement>) => saveMotto(event.target.value); const onMottoBlur = (event: FocusEvent<HTMLInputElement>) => saveMotto(event.target.value);
const onMottoKeyDown = (event: KeyboardEvent<HTMLInputElement>) => const onMottoKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
{
event.stopPropagation(); event.stopPropagation();
switch(event.key) switch (event.key) {
{
case 'Enter': case 'Enter':
saveMotto((event.target as HTMLInputElement).value); saveMotto((event.target as HTMLInputElement).value);
return; return;
} }
} };
useRoomSessionManagerEvent<RoomSessionUserBadgesEvent>(RoomSessionUserBadgesEvent.RSUBE_BADGES, event => useRoomSessionManagerEvent<RoomSessionUserBadgesEvent>(RoomSessionUserBadgesEvent.RSUBE_BADGES, event => {
{ if (!avatarInfo || (avatarInfo.webID !== event.userId)) return;
if(!avatarInfo || (avatarInfo.webID !== event.userId)) return;
const oldBadges = avatarInfo.badges.join(''); const oldBadges = avatarInfo.badges.join('');
if(oldBadges === event.badges.join('')) return; if (oldBadges === event.badges.join('')) return;
setAvatarInfo(prevValue => setAvatarInfo(prevValue => {
{
const newValue = CloneObject(prevValue); const newValue = CloneObject(prevValue);
newValue.badges = event.badges; newValue.badges = event.badges;
@ -72,12 +72,10 @@ export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =
}); });
}); });
useRoomSessionManagerEvent<RoomSessionUserFigureUpdateEvent>(RoomSessionUserFigureUpdateEvent.USER_FIGURE, event => useRoomSessionManagerEvent<RoomSessionUserFigureUpdateEvent>(RoomSessionUserFigureUpdateEvent.USER_FIGURE, event => {
{ if (!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
if(!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
setAvatarInfo(prevValue => setAvatarInfo(prevValue => {
{
const newValue = CloneObject(prevValue); const newValue = CloneObject(prevValue);
newValue.figure = event.figure; newValue.figure = event.figure;
@ -89,163 +87,190 @@ export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =
return newValue; return newValue;
}); });
// Update directions based on the new IDs
const backgrounds = GetConfiguration('backgrounds.data') || [];
const stands = GetConfiguration('stands.data') || [];
const overlays = GetConfiguration('overlays.data') || [];
const background = backgrounds.find(bg => bg.backgroundId === event.backgroundId);
const stand = stands.find(st => st.standId === event.standId);
const overlay = overlays.find(ov => ov.overlayId === event.overlayId);
setBackgroundDirection(background ? background.AvatarDirection ?? 2 : 2);
setStandDirection(stand ? stand.AvatarDirection ?? 2 : 2);
setOverlayDirection(overlay ? overlay.AvatarDirection ?? 2 : 2);
}); });
useRoomSessionManagerEvent<RoomSessionFavoriteGroupUpdateEvent>(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, event => useRoomSessionManagerEvent<RoomSessionFavoriteGroupUpdateEvent>(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, event => {
{ if (!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
if(!avatarInfo || (avatarInfo.roomIndex !== event.roomIndex)) return;
setAvatarInfo(prevValue => setAvatarInfo(prevValue => {
{
const newValue = CloneObject(prevValue); const newValue = CloneObject(prevValue);
const clearGroup = ((event.status === -1) || (event.habboGroupId <= 0)); const clearGroup = ((event.status === -1) || (event.habboGroupId <= 0));
newValue.groupId = clearGroup ? -1 : event.habboGroupId; newValue.groupId = clearGroup ? -1 : event.habboGroupId;
newValue.groupName = clearGroup ? null : event.habboGroupName newValue.groupName = clearGroup ? null : event.habboGroupName;
newValue.groupBadgeId = clearGroup ? null : GetSessionDataManager().getGroupBadge(event.habboGroupId); newValue.groupBadgeId = clearGroup ? null : GetSessionDataManager().getGroupBadge(event.habboGroupId);
return newValue; return newValue;
}); });
}); });
useMessageEvent<RelationshipStatusInfoEvent>(RelationshipStatusInfoEvent, event => useMessageEvent<RelationshipStatusInfoEvent>(RelationshipStatusInfoEvent, event => {
{
const parser = event.getParser(); const parser = event.getParser();
if(!avatarInfo || (avatarInfo.webID !== parser.userId)) return; if (!avatarInfo || (avatarInfo.webID !== parser.userId)) return;
setRelationships(parser); setRelationships(parser);
}); });
useEffect(() => useEffect(() => {
{
setIsEditingMotto(false); setIsEditingMotto(false);
setMotto(avatarInfo.motto); setMotto(avatarInfo.motto);
setBackgroundId(avatarInfo.backgroundId); setBackgroundId(avatarInfo.backgroundId);
setStandId(avatarInfo.standId); setStandId(avatarInfo.standId);
setOverlayId(avatarInfo.overlayId); setOverlayId(avatarInfo.overlayId);
// Set initial directions based on avatarInfo
const backgrounds = GetConfiguration('backgrounds.data') || [];
const stands = GetConfiguration('stands.data') || [];
const overlays = GetConfiguration('overlays.data') || [];
const background = backgrounds.find(bg => bg.backgroundId === avatarInfo.backgroundId);
const stand = stands.find(st => st.standId === avatarInfo.standId);
const overlay = overlays.find(ov => ov.overlayId === avatarInfo.overlayId);
setBackgroundDirection(background ? background.AvatarDirection ?? 2 : 2);
setStandDirection(stand ? stand.AvatarDirection ?? 2 : 2);
setOverlayDirection(overlay ? overlay.AvatarDirection ?? 2 : 2);
SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID)); SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID));
return () => return () => {
{
setIsEditingMotto(false); setIsEditingMotto(false);
setMotto(null); setMotto(null);
setRelationships(null); setRelationships(null);
setBackgroundId(null); setBackgroundId(null);
setStandId(null); setStandId(null);
setOverlayId(null); setOverlayId(null);
} setBackgroundDirection(2);
}, [ avatarInfo ]); setStandDirection(2);
setOverlayDirection(2);
};
}, [avatarInfo]);
if(!avatarInfo) return null; if (!avatarInfo) return null;
return ( return (
<Column className="nitro-infostand rounded"> <Column className="nitro-infostand rounded">
<Column overflow="visible" className="container-fluid content-area" gap={ 1 }> <Column overflow="visible" className="container-fluid content-area" gap={1}>
<Column gap={ 1 }> <Column gap={1}>
<Flex alignItems="center" justifyContent="between"> <Flex alignItems="center" justifyContent="between">
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={1}>
<UserProfileIconView userId={ avatarInfo.webID } /> <UserProfileIconView userId={avatarInfo.webID} />
<Text variant="white" small wrap>{ avatarInfo.name }</Text> <Text variant="white" small wrap>{avatarInfo.name}</Text>
</Flex> </Flex>
<FaTimes className="cursor-pointer fa-icon" onClick={ onClose } /> <FaTimes className="cursor-pointer fa-icon" onClick={onClose} />
</Flex> </Flex>
<hr className="m-0" /> <hr className="m-0" />
</Column> </Column>
<Column gap={ 1 }> <Column gap={1}>
<Flex gap={ 1 }> <Flex gap={1}>
<Column position="relative" pointer fullWidth className={ `body-image profile-background ${ infostandBackgroundClass }` } onClick={ event => GetUserProfile(avatarInfo.webID) }> <Column position="relative" pointer fullWidth className={`body-image profile-background ${infostandBackgroundClass}`} onClick={event => GetUserProfile(avatarInfo.webID)}>
<Base position="absolute" className={ `body-image profile-stand ${ infostandStandClass }` }/> <Base position="absolute" className={`body-image profile-stand ${infostandStandClass}`} />
<LayoutAvatarImageView figure={ avatarInfo.figure } direction={ 4 } /> <LayoutAvatarImageView figure={avatarInfo.figure} direction={avatarDirection} style={{ position: 'relative', top: '-10px' }} />
<Base position="absolute" className={ `body-image profile-overlay ${ infostandOverlayClass }` }/> <Base position="absolute" className={`body-image profile-overlay ${infostandOverlayClass}`} />
{ avatarInfo.type === AvatarInfoUser.OWN_USER && {avatarInfo.type === AvatarInfoUser.OWN_USER &&
<Base position="absolute" className="icon edit-icon edit-icon-position" onClick={ event => <Base position="absolute" className="icon edit-icon edit-icon-position" onClick={event => {
{ event.stopPropagation(); setIsVisible(prevValue => !prevValue); } } event.stopPropagation();
/> setIsVisible(prevValue => !prevValue);
}} />
} }
</Column> </Column>
<Column grow alignItems="center" gap={ 0 }> <Column grow alignItems="center" gap={0}>
<Flex gap={ 1 }> <Flex gap={1}>
<Flex center className="badge-image"> <Flex center className="badge-image">
{ avatarInfo.badges[0] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[0] } showInfo={ true } /> } {avatarInfo.badges[0] && <LayoutBadgeImageView badgeCode={avatarInfo.badges[0]} showInfo={true} />}
</Flex> </Flex>
<Flex center pointer={ ( avatarInfo.groupId > 0) } className="badge-image" onClick={ event => GetGroupInformation(avatarInfo.groupId) }> <Flex center pointer={(avatarInfo.groupId > 0)} className="badge-image" onClick={event => GetGroupInformation(avatarInfo.groupId)}>
{ avatarInfo.groupId > 0 && {avatarInfo.groupId > 0 &&
<LayoutBadgeImageView badgeCode={ avatarInfo.groupBadgeId } isGroup={ true } showInfo={ true } customTitle={ avatarInfo.groupName } /> } <LayoutBadgeImageView badgeCode={avatarInfo.groupBadgeId} isGroup={true} showInfo={true} customTitle={avatarInfo.groupName} />}
</Flex> </Flex>
</Flex> </Flex>
<Flex center gap={ 1 }> <Flex center gap={1}>
<Flex center className="badge-image"> <Flex center className="badge-image">
{ avatarInfo.badges[1] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[1] } showInfo={ true } /> } {avatarInfo.badges[1] && <LayoutBadgeImageView badgeCode={avatarInfo.badges[1]} showInfo={true} />}
</Flex> </Flex>
<Flex center className="badge-image"> <Flex center className="badge-image">
{ avatarInfo.badges[2] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[2] } showInfo={ true } /> } {avatarInfo.badges[2] && <LayoutBadgeImageView badgeCode={avatarInfo.badges[2]} showInfo={true} />}
</Flex> </Flex>
</Flex> </Flex>
<Flex center gap={ 1 }> <Flex center gap={1}>
<Flex center className="badge-image"> <Flex center className="badge-image">
{ avatarInfo.badges[3] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[3] } showInfo={ true } /> } {avatarInfo.badges[3] && <LayoutBadgeImageView badgeCode={avatarInfo.badges[3]} showInfo={true} />}
</Flex> </Flex>
<Flex center className="badge-image"> <Flex center className="badge-image">
{ avatarInfo.badges[4] && <LayoutBadgeImageView badgeCode={ avatarInfo.badges[4] } showInfo={ true } /> } {avatarInfo.badges[4] && <LayoutBadgeImageView badgeCode={avatarInfo.badges[4]} showInfo={true} />}
</Flex> </Flex>
</Flex> </Flex>
</Column> </Column>
</Flex> </Flex>
<hr className="m-0" /> <hr className="m-0" />
</Column> </Column>
<Column gap={ 1 }> <Column gap={1}>
<Flex alignItems="center" className="bg-light-dark rounded py-1 px-2"> <Flex alignItems="center" className="bg-light-dark rounded py-1 px-2">
{ (avatarInfo.type !== AvatarInfoUser.OWN_USER) && {(avatarInfo.type !== AvatarInfoUser.OWN_USER) &&
<Flex grow alignItems="center" className="motto-content"> <Flex grow alignItems="center" className="motto-content">
<Text fullWidth pointer wrap textBreak small variant="white">{ motto }</Text> <Text fullWidth pointer wrap textBreak small variant="white">{motto}</Text>
</Flex> } </Flex>}
{ avatarInfo.type === AvatarInfoUser.OWN_USER && {avatarInfo.type === AvatarInfoUser.OWN_USER &&
<Flex grow alignItems="center" gap={ 2 }> <Flex grow alignItems="center" gap={2}>
<FaPencilAlt className="small fa-icon" /> <FaPencilAlt className="small fa-icon" />
<Flex grow alignItems="center" className="motto-content"> <Flex grow alignItems="center" className="motto-content">
{ !isEditingMotto && {!isEditingMotto &&
<Text fullWidth pointer wrap textBreak small variant="white" onClick={ event => setIsEditingMotto(true) }>{ motto }&nbsp;</Text> } <Text fullWidth pointer wrap textBreak small variant="white" onClick={event => setIsEditingMotto(true)}>{motto} </Text>}
{ isEditingMotto && {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 } /> } <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> } </Flex>}
</Flex> </Flex>
<hr className="m-0" /> <hr className="m-0" />
</Column> </Column>
<Column gap={ 1 }> <Column gap={1}>
<Text variant="white" small wrap> <Text variant="white" small wrap>
{ LocalizeText('infostand.text.achievement_score') + ' ' + avatarInfo.achievementScore } {LocalizeText('infostand.text.achievement_score') + ' ' + avatarInfo.achievementScore}
</Text> </Text>
{ (avatarInfo.carryItem > 0) && {(avatarInfo.carryItem > 0) &&
<> <>
<hr className="m-0" /> <hr className="m-0" />
<Text variant="white" small wrap> <Text variant="white" small wrap>
{ LocalizeText('infostand.text.handitem', [ 'item' ], [ LocalizeText('handitem' + avatarInfo.carryItem) ]) } {LocalizeText('infostand.text.handitem', ['item'], [LocalizeText('handitem' + avatarInfo.carryItem)])}
</Text> </Text>
</> } </>}
</Column> </Column>
<Column gap={ 1 }> <Column gap={1}>
<InfoStandWidgetUserRelationshipsView relationships={ relationships } /> <InfoStandWidgetUserRelationshipsView relationships={relationships} />
</Column> </Column>
{ GetConfiguration('user.tags.enabled') && {GetConfiguration('user.tags.enabled') &&
<Column gap={ 1 } className="mt-1"> <Column gap={1} className="mt-1">
<InfoStandWidgetUserTagsView tags={ GetSessionDataManager().tags } /> <InfoStandWidgetUserTagsView tags={GetSessionDataManager().tags} />
</Column> </Column>
} }
</Column> </Column>
{ (isVisible && avatarInfo.type === AvatarInfoUser.OWN_USER) && {(isVisible && avatarInfo.type === AvatarInfoUser.OWN_USER) &&
<BackgroundsView <BackgroundsView
setIsVisible={ setIsVisible } setIsVisible={setIsVisible}
selectedBackground={ backgroundId } selectedBackground={backgroundId}
setSelectedBackground={ setBackgroundId } setSelectedBackground={setBackgroundId}
selectedStand={ standId } selectedStand={standId}
setSelectedStand={ setStandId } setSelectedStand={setStandId}
selectedOverlay={ overlayId } selectedOverlay={overlayId}
setSelectedOverlay={ setOverlayId } setSelectedOverlay={setOverlayId} // Fixed: Use setOverlayId
/> setBackgroundDirection={setBackgroundDirection}
} setStandDirection={setStandDirection}
setOverlayDirection={setOverlayDirection}
/>}
</Column> </Column>
); );
} };