mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Groups update
This commit is contained in:
parent
e83ddc7aec
commit
7a6d290c2c
@ -521,7 +521,7 @@
|
||||
|
||||
&.icon-pf-offline {
|
||||
background: url('../images/profile/icons/offline.png');
|
||||
width: 40px;
|
||||
width: 39px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
@import './views/GroupinformationView';
|
||||
@import './views/information/GroupInformationView';
|
||||
|
@ -1,90 +0,0 @@
|
||||
import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../api';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../../hooks';
|
||||
import { BadgeImageView } from '../../shared/badge-image/BadgeImageView';
|
||||
import { GroupMembershipType } from '../common/GroupMembershipType';
|
||||
import { GroupType } from '../common/GroupType';
|
||||
import { GroupInformationViewProps } from './GroupInformationView.types';
|
||||
|
||||
export const GroupInformationView: FC<GroupInformationViewProps> = props =>
|
||||
{
|
||||
const { group = null } = props;
|
||||
|
||||
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setGroupInformation(null);
|
||||
if(group) SendMessageHook(new GroupInformationComposer(group.id, true));
|
||||
}, [ group ]);
|
||||
|
||||
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
setGroupInformation(parser);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
|
||||
|
||||
if(!groupInformation) return null;
|
||||
|
||||
return (
|
||||
<div className="group-information p-2">
|
||||
<div>
|
||||
<div className="group-badge text-center">
|
||||
<BadgeImageView badgeCode={ group.badge } isGroup={ true } />
|
||||
<div className="mt-3">
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()]) }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
{ groupInformation.pendingRequestsCount > 0 && <a href="#" className="small text-black">
|
||||
{ LocalizeText('group.pendingmembercount', ['totalMembers'], [groupInformation.pendingRequestsCount.toString()]) }
|
||||
</a> }
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
{ groupInformation.membershipType === GroupMembershipType.MEMBER && !groupInformation.isAdmin && <i className="icon icon-group-member" title={ LocalizeText('group.youaremember') } /> }
|
||||
{ groupInformation.isAdmin && !groupInformation.isOwner && <i className="icon icon-group-admin" title={ LocalizeText('group.youareadmin') } /> }
|
||||
{ groupInformation.isOwner && <i className="icon icon-group-owner" title={ LocalizeText('group.youareowner') } /> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ms-2 w-100">
|
||||
<div className="fw-bold d-flex align-items-center">
|
||||
<i className={ 'icon icon-group-type-' + groupInformation.type } />
|
||||
{ groupInformation.canMembersDecorate && <i className="icon icon-group-decorate ms-1" /> }
|
||||
<div className="ms-1">{ group.title }</div>
|
||||
</div>
|
||||
<div>{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }</div>
|
||||
<div className="group-description small overflow-auto">{ groupInformation.description }</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.linktobase') }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.buyfurni') }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.showgroups') }
|
||||
</a>
|
||||
</div>
|
||||
{ groupInformation.type !== GroupType.PRIVATE &&
|
||||
<button className="btn btn-primary w-100 mt-2" disabled={ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING }>
|
||||
{ groupInformation.membershipType === GroupMembershipType.MEMBER && LocalizeText('group.leave') }
|
||||
{ groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && groupInformation.type === GroupType.REGULAR && LocalizeText('group.join') }
|
||||
{ groupInformation.type === GroupType.EXCLUSIVE && <>
|
||||
{ groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && LocalizeText('group.requestmembership') }
|
||||
{ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING && LocalizeText('group.membershippending') }
|
||||
</> }
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
146
src/views/groups/views/information/GroupInformationView.tsx
Normal file
146
src/views/groups/views/information/GroupInformationView.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser, GroupJoinComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../../../hooks';
|
||||
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
|
||||
import { GroupMembershipType } from '../../common/GroupMembershipType';
|
||||
import { GroupType } from '../../common/GroupType';
|
||||
import { GroupInformationViewProps } from './GroupInformationView.types';
|
||||
|
||||
export const GroupInformationView: FC<GroupInformationViewProps> = props =>
|
||||
{
|
||||
const { group = null, onLeaveGroup = null } = props;
|
||||
|
||||
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setGroupInformation(null);
|
||||
if(group) SendMessageHook(new GroupInformationComposer(group.id, false));
|
||||
}, [ group ]);
|
||||
|
||||
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(groupInformation) setGroupInformation(null);
|
||||
|
||||
setGroupInformation(parser);
|
||||
}, [ groupInformation ]);
|
||||
|
||||
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
|
||||
|
||||
const tryJoinGroup = useCallback(() =>
|
||||
{
|
||||
if(!groupInformation) return;
|
||||
|
||||
SendMessageHook(new GroupJoinComposer(groupInformation.id));
|
||||
SendMessageHook(new GroupInformationComposer(groupInformation.id, false));
|
||||
}, [ groupInformation ]);
|
||||
|
||||
const tryLeaveGroup = useCallback(() =>
|
||||
{
|
||||
SendMessageHook(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId));
|
||||
SendMessageHook(new GroupInformationComposer(groupInformation.id, false));
|
||||
if(onLeaveGroup) onLeaveGroup();
|
||||
}, [ groupInformation, onLeaveGroup ]);
|
||||
|
||||
const isOwner = useCallback(() =>
|
||||
{
|
||||
if(!group) return false;
|
||||
|
||||
return (group.ownerId === GetSessionDataManager().userId);
|
||||
}, [ group, groupInformation ]);
|
||||
|
||||
const getRoleIcon = useCallback(() =>
|
||||
{
|
||||
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER || groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return null;
|
||||
|
||||
if(isOwner()) return <i className="icon icon-group-owner" title={ LocalizeText('group.youareowner') } />;
|
||||
|
||||
if(groupInformation.isAdmin) return <i className="icon icon-group-admin" title={ LocalizeText('group.youareadmin') } />;
|
||||
|
||||
return <i className="icon icon-group-member" title={ LocalizeText('group.youaremember') } />;
|
||||
}, [ groupInformation, isOwner ]);
|
||||
|
||||
const getButtonText = useCallback(() =>
|
||||
{
|
||||
if(groupInformation.type === GroupType.PRIVATE) return '';
|
||||
|
||||
if(isOwner()) return 'group.youareowner';
|
||||
|
||||
if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave';
|
||||
|
||||
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && groupInformation.type === GroupType.REGULAR) return 'group.join';
|
||||
|
||||
if(groupInformation.type === GroupType.EXCLUSIVE)
|
||||
{
|
||||
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return 'group.requestmembership';
|
||||
|
||||
if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending';
|
||||
}
|
||||
}, [ groupInformation, isOwner ]);
|
||||
|
||||
const handleButtonClick = useCallback(() =>
|
||||
{
|
||||
if(groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return;
|
||||
|
||||
if(groupInformation.membershipType === GroupMembershipType.MEMBER) return tryLeaveGroup();
|
||||
|
||||
return tryJoinGroup();
|
||||
}, [ groupInformation, tryLeaveGroup, tryJoinGroup ]);
|
||||
|
||||
if(!group || !groupInformation) return null;
|
||||
|
||||
return (
|
||||
<div className="group-information p-2">
|
||||
<div>
|
||||
<div className="group-badge text-center">
|
||||
<BadgeImageView badgeCode={ group.badge } isGroup={ true } />
|
||||
<div className="mt-3">
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()]) }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
{ groupInformation.pendingRequestsCount > 0 && <a href="#" className="small text-black">
|
||||
{ LocalizeText('group.pendingmembercount', ['totalMembers'], [groupInformation.pendingRequestsCount.toString()]) }
|
||||
</a> }
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
{ getRoleIcon() }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ms-2 w-100">
|
||||
<div className="fw-bold d-flex align-items-center">
|
||||
<i className={ 'icon icon-group-type-' + groupInformation.type } />
|
||||
{ groupInformation.canMembersDecorate && <i className="icon icon-group-decorate ms-1" /> }
|
||||
<div className="ms-1">{ group.title }</div>
|
||||
</div>
|
||||
<div>{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }</div>
|
||||
<div className="group-description small overflow-auto">{ groupInformation.description }</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.linktobase') }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.buyfurni') }
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" className="small text-black">
|
||||
{ LocalizeText('group.showgroups') }
|
||||
</a>
|
||||
</div>
|
||||
{ groupInformation.type !== GroupType.PRIVATE &&
|
||||
<button className="btn btn-primary w-100 mt-2" disabled={ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING || isOwner() } onClick={ handleButtonClick }>
|
||||
{ LocalizeText(getButtonText()) }
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -3,4 +3,5 @@ import { GroupDataParser } from '@nitrots/nitro-renderer';
|
||||
export interface GroupInformationViewProps
|
||||
{
|
||||
group: GroupDataParser;
|
||||
onLeaveGroup?: () => void;
|
||||
}
|
@ -17,4 +17,9 @@
|
||||
background-color: rgba($black, .125);
|
||||
border-color: $black !important;
|
||||
}
|
||||
|
||||
.group-badge {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
@ -131,10 +131,10 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{ roomThumbnail && <img alt="" src={ roomThumbnail } /> }
|
||||
</div>
|
||||
{ roomInfoData.enteredGuestRoom.habboGroupId > 0 && <div className="d-flex align-items-center mb-2 cursor-pointer" onClick={ () => processAction('open_group_info') }>
|
||||
<div className="me-2">
|
||||
<div className="group-badge flex-shrink-0 me-2">
|
||||
<BadgeImageView badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||
</div>
|
||||
<div className="text-decoration-underline">
|
||||
<div className="text-decoration-underline small">
|
||||
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
|
||||
</div>
|
||||
</div> }
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer';
|
||||
import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileComposer, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../api';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../api';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../hooks';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout';
|
||||
import { BadgesContainerView } from './views/badges-container/BadgesContainerView';
|
||||
@ -21,6 +21,11 @@ export const UserProfileView: FC = props =>
|
||||
setUserRelationships(null);
|
||||
}, []);
|
||||
|
||||
const onLeaveGroup = useCallback(() =>
|
||||
{
|
||||
if(userProfile && userProfile.id === GetSessionDataManager().userId) SendMessageHook(new UserProfileComposer(userProfile.id));
|
||||
}, [ userProfile ]);
|
||||
|
||||
const OnUserCurrentBadgesEvent = useCallback((event: UserCurrentBadgesEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -45,14 +50,14 @@ export const UserProfileView: FC = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(userProfile && userProfile.id !== parser.id)
|
||||
if(userProfile)
|
||||
{
|
||||
setUserProfile(null);
|
||||
setUserBadges([]);
|
||||
setUserRelationships(null);
|
||||
}
|
||||
|
||||
setUserProfile(parser);
|
||||
console.log(parser);
|
||||
SendMessageHook(new UserCurrentBadgesComposer(parser.id));
|
||||
SendMessageHook(new UserRelationshipsComposer(parser.id));
|
||||
}, [userProfile]);
|
||||
@ -67,8 +72,8 @@ export const UserProfileView: FC = props =>
|
||||
<NitroCardContentView>
|
||||
<div className="row">
|
||||
<div className="col-sm-7 user-container">
|
||||
<UserContainerView id={userProfile.id} username={userProfile.username} motto={userProfile.motto} figure={userProfile.figure} secondsSinceLastLogin={userProfile.secondsSinceLastVisit} creation={userProfile.registration} achievementScore={userProfile.achievementPoints} isFriend={userProfile.isMyFriend} isOnline={userProfile.isOnline} requestSent={userProfile.requestSent} />
|
||||
<BadgesContainerView badges={userBadges} />
|
||||
<UserContainerView userProfile={ userProfile } />
|
||||
<BadgesContainerView badges={ userBadges } />
|
||||
</div>
|
||||
<div className="col-sm-5">
|
||||
{
|
||||
@ -81,7 +86,7 @@ export const UserProfileView: FC = props =>
|
||||
<i className="icon icon-rooms" /><span className="rooms-button">{LocalizeText('extendedprofile.rooms')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<GroupsContainerView groups={ userProfile.groups } />
|
||||
<GroupsContainerView groups={ userProfile.groups } onLeaveGroup={ onLeaveGroup } />
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ export const BadgesContainerView: FC<BadgesContainerViewProps> = props =>
|
||||
const { badges = null } = props;
|
||||
|
||||
return (
|
||||
<div className="row badge-container d-flex">
|
||||
<div className="row badge-container d-flex mt-1">
|
||||
<div className="nitro-card-grid theme-default">
|
||||
<div className="row row-cols-5 align-content-start">
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
import classNames from 'classnames';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { GroupInformationView } from '../../../groups/views/GroupInformationView';
|
||||
import { GroupInformationView } from '../../../groups/views/information/GroupInformationView';
|
||||
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
|
||||
import { GroupsContainerViewProps } from './GroupsContainerView.types';
|
||||
|
||||
export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
|
||||
{
|
||||
const { groups = null } = props;
|
||||
const { groups = null, onLeaveGroup = null } = props;
|
||||
|
||||
const [ selectedIndex, setSelectedIndex ] = useState<number>(null);
|
||||
|
||||
@ -30,7 +30,7 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-100">
|
||||
{ selectedIndex > -1 && <GroupInformationView group={ groups[selectedIndex] } /> }
|
||||
{ selectedIndex > -1 && <GroupInformationView group={ groups[selectedIndex] } onLeaveGroup={ onLeaveGroup } /> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -3,4 +3,5 @@ import { GroupDataParser } from '@nitrots/nitro-renderer';
|
||||
export interface GroupsContainerViewProps
|
||||
{
|
||||
groups: GroupDataParser[];
|
||||
onLeaveGroup: () => void;
|
||||
}
|
||||
|
@ -6,38 +6,38 @@ import { UserContainerViewProps } from './UserContainerView.types';
|
||||
|
||||
export const UserContainerView: FC<UserContainerViewProps> = props =>
|
||||
{
|
||||
const { figure = null, username = null, motto = null, creation = null, secondsSinceLastLogin = null, achievementScore, isFriend = null, isOnline = null, id = null, requestSent = null } = props;
|
||||
const { userProfile = null } = props;
|
||||
|
||||
const OnlineIcon = useCallback(() =>
|
||||
{
|
||||
if(isOnline) return (<i className="icon icon-pf-online" />);
|
||||
if(userProfile.isOnline) return (<i className="icon icon-pf-online" />);
|
||||
else return (<i className="icon icon-pf-offline" />);
|
||||
}, [isOnline]);
|
||||
}, [ userProfile ]);
|
||||
|
||||
const FriendRequestComponent = useCallback(() =>
|
||||
{
|
||||
if(id === GetSessionDataManager().userId) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.me')}</span> );
|
||||
if(userProfile.id === GetSessionDataManager().userId) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.me')}</span> );
|
||||
|
||||
if(isFriend) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.friend')}</span>);
|
||||
if(userProfile.isMyFriend) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.friend')}</span>);
|
||||
|
||||
if(requestSent) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.friendrequestsent')}</span>);
|
||||
if(userProfile.requestSent) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.friendrequestsent')}</span>);
|
||||
|
||||
return (<button className="btn btn-success btn-sm add-friend">{LocalizeText('extendedprofile.addasafriend')}</button>)
|
||||
}, [id, isFriend, requestSent]);
|
||||
}, [ userProfile ]);
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-sm-3 px-0 d-flex align-items-center">
|
||||
<AvatarImageView figure={figure} direction={2} />
|
||||
<AvatarImageView figure={userProfile.figure} direction={2} />
|
||||
</div>
|
||||
<div className="col-sm-8">
|
||||
<div className="user-info-container">
|
||||
<div className="fw-bold">{username}</div>
|
||||
<div className="mb-1 fst-italic">{motto}</div>
|
||||
<div className="mb-1" dangerouslySetInnerHTML={{ __html: LocalizeText('extendedprofile.created', ['created'], [creation]) }} />
|
||||
<div className="mb-1" dangerouslySetInnerHTML={{ __html: LocalizeText('extendedprofile.last.login', ['lastlogin'], [FriendlyTime.format(secondsSinceLastLogin, '.ago', 2)]) }} />
|
||||
<div className="mb-1"><b>{LocalizeText('extendedprofile.achievementscore')}</b> {achievementScore}</div>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div className="fw-bold">{userProfile.username}</div>
|
||||
<div className="fst-italic">{userProfile.motto}</div>
|
||||
<div dangerouslySetInnerHTML={{ __html: LocalizeText('extendedprofile.created', ['created'], [userProfile.registration]) }} />
|
||||
<div dangerouslySetInnerHTML={{ __html: LocalizeText('extendedprofile.last.login', ['lastlogin'], [FriendlyTime.format(userProfile.secondsSinceLastVisit, '.ago', 2)]) }} />
|
||||
<div><b>{LocalizeText('extendedprofile.achievementscore')}</b> {userProfile.achievementPoints}</div>
|
||||
<div className="d-flex flex-row align-items-center gap-2">
|
||||
<OnlineIcon />
|
||||
<FriendRequestComponent />
|
||||
</div>
|
||||
|
@ -1,12 +1,6 @@
|
||||
export interface UserContainerViewProps {
|
||||
id: number;
|
||||
username: string;
|
||||
figure: string;
|
||||
motto: string;
|
||||
creation: string;
|
||||
secondsSinceLastLogin: number;
|
||||
achievementScore: number;
|
||||
isFriend: boolean;
|
||||
requestSent: boolean;
|
||||
isOnline: boolean;
|
||||
import { UserProfileParser } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface UserContainerViewProps
|
||||
{
|
||||
userProfile: UserProfileParser;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user