mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
Update profiles
This commit is contained in:
parent
10bb7c5aa7
commit
9ec5f9f0de
@ -35,8 +35,8 @@ $navigator-height: 420px;
|
||||
$chat-input-style-selector-widget-width: 210px;
|
||||
$chat-input-style-selector-widget-height: 200px;
|
||||
|
||||
$user-profile-width: 560px;
|
||||
$user-profile-height: 500px;
|
||||
$user-profile-width: 470px;
|
||||
$user-profile-height: 460px;
|
||||
|
||||
$nitro-widget-custom-stack-height-width: 275px;
|
||||
$nitro-widget-custom-stack-height-height: 220px;
|
||||
|
BIN
src/assets/images/groups/no-group-1.png
Normal file
BIN
src/assets/images/groups/no-group-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
src/assets/images/groups/no-group-2.png
Normal file
BIN
src/assets/images/groups/no-group-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/images/groups/no-group-3.png
Normal file
BIN
src/assets/images/groups/no-group-3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/images/groups/no-group-spritesheet.png
Normal file
BIN
src/assets/images/groups/no-group-spritesheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
@ -1,5 +1,5 @@
|
||||
.layout-grid-item {
|
||||
height: var(--nitro-grid-column-min-height, 45px);
|
||||
height: var(--nitro-grid-column-min-height, unset);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-color: $grid-bg-color;
|
||||
|
@ -1,106 +1,67 @@
|
||||
.user-profile {
|
||||
width: 560px;
|
||||
|
||||
.content-area {
|
||||
color: black;
|
||||
}
|
||||
width: $user-profile-width;
|
||||
height: $user-profile-height;
|
||||
|
||||
.user-container {
|
||||
border-right: 1px solid gray;
|
||||
|
||||
.avatar-image {
|
||||
left: -10px;
|
||||
.avatar-container {
|
||||
width: 75px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.add-friend {
|
||||
margin: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-container {
|
||||
min-height: 50px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
margin: 0px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.rooms-button-container {
|
||||
border-top: 1px solid gray;
|
||||
border-bottom: 1px solid gray;
|
||||
padding: 1px;
|
||||
|
||||
.rooms-button {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
text-decoration: underline;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.friends-container {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.user-relationship {
|
||||
height: 25px;
|
||||
|
||||
.profile-groups {
|
||||
height: 219px;
|
||||
|
||||
.profile-groups-item {
|
||||
.avatar-image-container {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: $border-radius;
|
||||
border-color: $grid-border-color !important;
|
||||
background-color: $grid-bg-color;
|
||||
border: nth(map-values($border-widths), 2) solid;
|
||||
|
||||
&.active {
|
||||
border-color: $grid-active-border-color !important;
|
||||
background-color: $grid-active-bg-color !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
z-index: 1;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.relationships-container {
|
||||
|
||||
.relationship-container {
|
||||
|
||||
.relationship
|
||||
{
|
||||
position: relative;
|
||||
|
||||
&.advanced {
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.relationship-text {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: -8pxpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-relationship-count {
|
||||
margin-top: 2px;
|
||||
margin-left: 5px;
|
||||
color: #939392 !important;
|
||||
}
|
||||
|
||||
.user-groups-container {
|
||||
|
||||
.layout-grid-item {
|
||||
width: 50px;
|
||||
height: 80px;
|
||||
right: 0;
|
||||
margin-top: -60px;
|
||||
}
|
||||
}
|
||||
|
||||
.others-text {
|
||||
margin-left: 20px;
|
||||
height: 21px;
|
||||
color: #939392;
|
||||
}
|
||||
.no-group-spritesheet {
|
||||
background: transparent url('../../assets/images/groups/no-group-spritesheet.png') no-repeat;
|
||||
|
||||
&.image-1 {
|
||||
width: 95px;
|
||||
height: 136px;
|
||||
background-position: -3px -3px;
|
||||
}
|
||||
|
||||
&.image-2 {
|
||||
width: 95px;
|
||||
height: 136px;
|
||||
background-position: -104px -3px;
|
||||
}
|
||||
|
||||
&.image-3 {
|
||||
width: 95px;
|
||||
height: 136px;
|
||||
background-position: -205px -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetSessionDataManager, GetUserProfile, LocalizeText, SendMessageComposer } from '../../api';
|
||||
import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
||||
import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../hooks';
|
||||
import { BadgesContainerView } from './views/BadgesContainerView';
|
||||
import { FriendsContainerView } from './views/FriendsContainerView';
|
||||
@ -26,10 +26,9 @@ export const UserProfileView: FC<{}> = props =>
|
||||
|
||||
const onLeaveGroup = useCallback(() =>
|
||||
{
|
||||
if(userProfile && userProfile.id === GetSessionDataManager().userId)
|
||||
{
|
||||
if(!userProfile || (userProfile.id !== GetSessionDataManager().userId)) return;
|
||||
|
||||
GetUserProfile(userProfile.id);
|
||||
}
|
||||
}, [ userProfile ]);
|
||||
|
||||
const onUserCurrentBadgesEvent = useCallback((event: UserCurrentBadgesEvent) =>
|
||||
@ -43,7 +42,7 @@ export const UserProfileView: FC<{}> = props =>
|
||||
|
||||
UseMessageEventHook(UserCurrentBadgesEvent, onUserCurrentBadgesEvent);
|
||||
|
||||
const OnUserRelationshipsEvent = useCallback((event: RelationshipStatusInfoEvent) =>
|
||||
const onUserRelationshipsEvent = useCallback((event: RelationshipStatusInfoEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
@ -52,27 +51,22 @@ export const UserProfileView: FC<{}> = props =>
|
||||
setUserRelationships(parser);
|
||||
}, [ userProfile ]);
|
||||
|
||||
UseMessageEventHook(RelationshipStatusInfoEvent, OnUserRelationshipsEvent);
|
||||
UseMessageEventHook(RelationshipStatusInfoEvent, onUserRelationshipsEvent);
|
||||
|
||||
const onUserProfileEvent = useCallback((event: UserProfileEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(userProfile)
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setUserProfile(null);
|
||||
setUserProfile(parser);
|
||||
setUserBadges([]);
|
||||
setUserRelationships(null);
|
||||
});
|
||||
}
|
||||
|
||||
setUserProfile(parser);
|
||||
|
||||
SendMessageComposer(new UserCurrentBadgesComposer(parser.id));
|
||||
SendMessageComposer(new UserRelationshipsComposer(parser.id));
|
||||
}, [ userProfile ]);
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(UserProfileEvent, onUserProfileEvent);
|
||||
|
||||
@ -81,22 +75,26 @@ export const UserProfileView: FC<{}> = props =>
|
||||
return (
|
||||
<NitroCardView className="user-profile" theme="primary-slim">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('extendedprofile.caption') } onCloseClick={ onClose } />
|
||||
<NitroCardContentView>
|
||||
<Grid>
|
||||
<Column size={ 7 } className="user-container">
|
||||
<NitroCardContentView overflow="hidden">
|
||||
<Grid fullHeight={ false } gap={ 2 }>
|
||||
<Column size={ 7 } gap={ 1 } className="user-container pe-2">
|
||||
<UserContainerView userProfile={ userProfile } />
|
||||
<BadgesContainerView badges={ userBadges } />
|
||||
<Grid columnCount={ 5 } fullHeight className="bg-muted rounded px-2 py-1">
|
||||
<BadgesContainerView fullWidth center badges={ userBadges } />
|
||||
</Grid>
|
||||
</Column>
|
||||
<Column size={ 5 }>
|
||||
{
|
||||
userRelationships && <FriendsContainerView relationships={userRelationships} friendsCount={userProfile.friendsCount} />
|
||||
}
|
||||
{ userRelationships &&
|
||||
<FriendsContainerView relationships={ userRelationships } friendsCount={ userProfile.friendsCount } /> }
|
||||
</Column>
|
||||
</Grid>
|
||||
<Flex alignItems="center" className="rooms-button-container">
|
||||
<i className="icon icon-rooms" /><span className="rooms-button">{LocalizeText('extendedprofile.rooms')}</span>
|
||||
<Flex alignItems="center" className="rooms-button-container px-2 py-1">
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<i className="icon icon-rooms" />
|
||||
<Text bold underline pointer>{ LocalizeText('extendedprofile.rooms') }</Text>
|
||||
</Flex>
|
||||
<GroupsContainerView itsMe={ userProfile.id === GetSessionDataManager().userId } groups={ userProfile.groups } onLeaveGroup={ onLeaveGroup } />
|
||||
</Flex>
|
||||
<GroupsContainerView fullWidth itsMe={ userProfile.id === GetSessionDataManager().userId } groups={ userProfile.groups } onLeaveGroup={ onLeaveGroup } />
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
)
|
||||
|
@ -1,27 +1,25 @@
|
||||
import { FC } from 'react';
|
||||
import { Grid, LayoutBadgeImageView, LayoutGridItem } from '../../../common';
|
||||
import { Column, FlexProps, LayoutBadgeImageView } from '../../../common';
|
||||
|
||||
interface BadgesContainerViewProps
|
||||
interface BadgesContainerViewProps extends FlexProps
|
||||
{
|
||||
badges: string[];
|
||||
}
|
||||
|
||||
export const BadgesContainerView: FC<BadgesContainerViewProps> = props =>
|
||||
{
|
||||
const { badges = null } = props;
|
||||
const { badges = null, gap = 1, justifyContent = 'between', ...rest } = props;
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<Grid>
|
||||
<>
|
||||
{ badges && (badges.length > 0) && badges.map((badge, index) =>
|
||||
{
|
||||
return (
|
||||
<LayoutGridItem key={ index }>
|
||||
<LayoutBadgeImageView badgeCode={ badge }/>
|
||||
</LayoutGridItem>
|
||||
)
|
||||
<Column key={ badge } center>
|
||||
<LayoutBadgeImageView key={ badge } badgeCode={ badge } />
|
||||
</Column>
|
||||
);
|
||||
}) }
|
||||
</Grid>
|
||||
</div>
|
||||
)
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { RelationshipStatusInfoMessageParser } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../api';
|
||||
import { Column, Text } from '../../../common';
|
||||
import { RelationshipsContainerView } from './RelationshipsContainerView';
|
||||
|
||||
interface FriendsContainerViewProps
|
||||
@ -14,12 +15,14 @@ export const FriendsContainerView: FC<FriendsContainerViewProps> = props =>
|
||||
const { relationships = null, friendsCount = null } = props;
|
||||
|
||||
return (
|
||||
<div className="friends-container h-100 d-flex flex-column">
|
||||
<div className="mb-1" dangerouslySetInnerHTML={{ __html: LocalizeText('extendedprofile.friends.count', ['count'], [friendsCount.toString()]) }} />
|
||||
<div className="mb-1"><b>{LocalizeText('extendedprofile.relstatus')}</b></div>
|
||||
<div className="h-100 d-flex flex-column justify-content-between">
|
||||
<Column gap={ 1 }>
|
||||
<Text small>
|
||||
<b>{ LocalizeText('extendedprofile.friends.count') }</b> { friendsCount }
|
||||
</Text>
|
||||
<Text bold small>{ LocalizeText('extendedprofile.relstatus') }</Text>
|
||||
<Column>
|
||||
<RelationshipsContainerView relationships={relationships} />
|
||||
</div>
|
||||
</div>
|
||||
</Column>
|
||||
</Column>
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { GroupFavoriteComposer, GroupInformationComposer, GroupInformationEvent, GroupInformationParser, HabboGroupEntryData } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { SendMessageComposer } from '../../../api';
|
||||
import { LayoutBadgeImageView } from '../../../common';
|
||||
import { UseMessageEventHook } from '../../../hooks';
|
||||
import { AutoGrid, Base, Column, Flex, Grid, GridProps, LayoutBadgeImageView, LayoutGridItem } from '../../../common';
|
||||
import { BatchUpdates, UseMessageEventHook } from '../../../hooks';
|
||||
import { GroupInformationView } from '../../groups/views/GroupInformationView';
|
||||
|
||||
interface GroupsContainerViewProps
|
||||
interface GroupsContainerViewProps extends GridProps
|
||||
{
|
||||
itsMe: boolean;
|
||||
groups: HabboGroupEntryData[];
|
||||
@ -15,16 +14,17 @@ interface GroupsContainerViewProps
|
||||
|
||||
export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
|
||||
{
|
||||
const { itsMe = null, groups = null, onLeaveGroup = null } = props;
|
||||
|
||||
const { itsMe = null, groups = null, onLeaveGroup = null, overflow = 'hidden', gap = 2, ...rest } = props;
|
||||
const [ selectedGroupId, setSelectedGroupId ] = useState<number>(null);
|
||||
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
|
||||
|
||||
const favoriteGroup = (groupId: number) => SendMessageComposer(new GroupFavoriteComposer(groupId));
|
||||
|
||||
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(!selectedGroupId || selectedGroupId !== parser.id || parser.flag) return;
|
||||
if(!selectedGroupId || (selectedGroupId !== parser.id) || parser.flag) return;
|
||||
|
||||
if(groupInformation) setGroupInformation(null);
|
||||
|
||||
@ -35,37 +35,54 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(groups.length > 0 && !selectedGroupId) setSelectedGroupId(groups[0].groupId);
|
||||
}, [ groups, selectedGroupId ]);
|
||||
if(!selectedGroupId) return;
|
||||
|
||||
SendMessageComposer(new GroupInformationComposer(selectedGroupId, false));
|
||||
}, [ selectedGroupId ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(selectedGroupId) SendMessageComposer(new GroupInformationComposer(selectedGroupId, false));
|
||||
}, [ selectedGroupId ]);
|
||||
|
||||
const favoriteGroup = useCallback((groupId: number) =>
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
SendMessageComposer(new GroupFavoriteComposer(groupId));
|
||||
}, []);
|
||||
setGroupInformation(null);
|
||||
|
||||
if(!groups) return null;
|
||||
if(groups.length > 0) setSelectedGroupId(groups[0].groupId);
|
||||
});
|
||||
}, [ groups ]);
|
||||
|
||||
if(!groups || !groups.length)
|
||||
{
|
||||
return (
|
||||
<Column center fullHeight>
|
||||
<Flex justifyContent="center" gap={ 2 }>
|
||||
<Base className="no-group-spritesheet image-1" />
|
||||
<Base className="no-group-spritesheet image-2" />
|
||||
<Base className="no-group-spritesheet image-3" />
|
||||
</Flex>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="d-flex">
|
||||
<div className="profile-groups p-2">
|
||||
<div className="h-100 overflow-auto d-flex flex-column gap-1">
|
||||
<Grid overflow={ overflow } gap={ 2 } { ...rest }>
|
||||
<Column alignItems="center" size={ 2 } overflow="auto">
|
||||
<AutoGrid overflow={ null } columnCount={ 1 } columnMinHeight={ 50 } className="user-groups-container">
|
||||
{ groups.map((group, index) =>
|
||||
{
|
||||
return <div key={ index } onClick={ () => setSelectedGroupId(group.groupId) } className={ 'profile-groups-item position-relative flex-shrink-0 d-flex align-items-center justify-content-center cursor-pointer' + classNames({ ' active': selectedGroupId === group.groupId }) }>
|
||||
{ itsMe && <i className={ 'position-absolute icon icon-group-' + (group.favourite ? 'favorite' : 'not-favorite') } onClick={ () => favoriteGroup(group.groupId) } /> }
|
||||
return (
|
||||
<LayoutGridItem key={ index } overflow="unset" itemActive={ (selectedGroupId === group.groupId) } onClick={ () => setSelectedGroupId(group.groupId) } className="p-1">
|
||||
{ itsMe &&
|
||||
<i className={ 'position-absolute end-0 top-0 z-index-1 icon icon-group-' + (group.favourite ? 'favorite' : 'not-favorite') } onClick={ () => favoriteGroup(group.groupId) } /> }
|
||||
<LayoutBadgeImageView badgeCode={ group.badgeCode } isGroup={ true } />
|
||||
</div>
|
||||
</LayoutGridItem>
|
||||
)
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-100">
|
||||
{ groupInformation && <GroupInformationView groupInformation={ groupInformation } onClose={ onLeaveGroup } /> }
|
||||
</div>
|
||||
</div>
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<Column size={ 10 }>
|
||||
{ groupInformation &&
|
||||
<GroupInformationView groupInformation={ groupInformation } onClose={ onLeaveGroup } /> }
|
||||
</Column>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
@ -1,75 +1,62 @@
|
||||
import { RelationshipStatusEnum, RelationshipStatusInfo, RelationshipStatusInfoMessageParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { RelationshipStatusEnum, RelationshipStatusInfoMessageParser } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { GetUserProfile, LocalizeText } from '../../../api';
|
||||
import { LayoutAvatarImageView } from '../../../common';
|
||||
import { Column, Flex, LayoutAvatarImageView, Text } from '../../../common';
|
||||
|
||||
interface RelationshipsContainerViewProps
|
||||
{
|
||||
relationships: RelationshipStatusInfoMessageParser;
|
||||
simple?: boolean;
|
||||
}
|
||||
|
||||
interface RelationshipsContainerRelationshipViewProps
|
||||
{
|
||||
type: number;
|
||||
}
|
||||
|
||||
export const RelationshipsContainerView: FC<RelationshipsContainerViewProps> = props =>
|
||||
{
|
||||
const { relationships = null, simple = false } = props;
|
||||
const { relationships = null } = props;
|
||||
|
||||
const OnUserClick = useCallback((user: RelationshipStatusInfo) =>
|
||||
{
|
||||
if(!user) return;
|
||||
|
||||
GetUserProfile(user.randomFriendId);
|
||||
}, []);
|
||||
|
||||
const RelationshipComponent = useCallback(({ type }) =>
|
||||
const RelationshipComponent = ({ type }: RelationshipsContainerRelationshipViewProps) =>
|
||||
{
|
||||
const relationshipInfo = (relationships && relationships.relationshipStatusMap.hasKey(type)) ? relationships.relationshipStatusMap.getValue(type) : null;
|
||||
|
||||
if(simple && !relationshipInfo) return null;
|
||||
|
||||
const relationshipName = RelationshipStatusEnum.RELATIONSHIP_NAMES[type].toLocaleLowerCase();
|
||||
|
||||
return (
|
||||
<div className="relationship-container d-flex flex-row align-items-center w-100">
|
||||
<i className={`nitro-friends-spritesheet icon-${relationshipName} flex-shrink-0 align-self-baseline mt-2`} />
|
||||
<div className="w-100 d-flex flex-column">
|
||||
<span className={'relationship mx-2' + (!simple ? ' advanced' : '')}>
|
||||
<span className="cursor-pointer relationship-text" onClick={ event => OnUserClick(relationshipInfo)}>
|
||||
{
|
||||
(relationshipInfo && relationshipInfo.friendCount > 0) ? relationshipInfo.randomFriendName : LocalizeText('extendedprofile.add.friends')
|
||||
}
|
||||
</span>
|
||||
{
|
||||
(simple && relationshipInfo && relationshipInfo.friendCount > 1) &&
|
||||
<span>
|
||||
{' ' + LocalizeText(`extendedprofile.relstatus.others.${relationshipName}`, ['count'], [(relationshipInfo.friendCount - 1).toString()])}
|
||||
</span>
|
||||
}
|
||||
{
|
||||
(!simple && relationshipInfo && relationshipInfo.friendCount > 0) &&
|
||||
<LayoutAvatarImageView figure={relationshipInfo.randomFriendFigure} headOnly={true} direction={4} />
|
||||
}
|
||||
</span>
|
||||
|
||||
{
|
||||
!simple && <div className="others-text">
|
||||
{
|
||||
(relationshipInfo && relationshipInfo.friendCount > 1) ? LocalizeText(`extendedprofile.relstatus.others.${relationshipName}`, ['count'], [(relationshipInfo.friendCount - 1).toString()]) : ''
|
||||
}
|
||||
{
|
||||
(relationshipInfo && relationshipInfo.friendCount < 1) ? LocalizeText('extendedprofile.no.friends.in.this.category') : ''
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Flex fullWidth gap={ 1 }>
|
||||
<Flex center className="user-relationship">
|
||||
<i className={ `nitro-friends-spritesheet icon-${ relationshipName }` } />
|
||||
</Flex>
|
||||
<Column grow gap={ 0 }>
|
||||
<Flex alignItems="center" justifyContent="between" className="bg-white rounded px-2 py-1 user-relationship">
|
||||
<Text small underline pointer onClick={ event => (relationshipInfo && (relationshipInfo.randomFriendId >= 1) && GetUserProfile(relationshipInfo.randomFriendId)) }>
|
||||
{ (!relationshipInfo || (relationshipInfo.friendCount === 0)) &&
|
||||
LocalizeText('extendedprofile.add.friends') }
|
||||
{ (relationshipInfo && (relationshipInfo.friendCount >= 1)) &&
|
||||
relationshipInfo.randomFriendName }
|
||||
</Text>
|
||||
{ (relationshipInfo && (relationshipInfo.friendCount >= 1)) &&
|
||||
<Flex center position="relative" className="avatar-image-container">
|
||||
<LayoutAvatarImageView figure={ relationshipInfo.randomFriendFigure } headOnly={ true } direction={ 4 } />
|
||||
</Flex> }
|
||||
</Flex>
|
||||
<Text small italics className="user-relationship-count">
|
||||
{ (!relationshipInfo || (relationshipInfo.friendCount === 0)) &&
|
||||
LocalizeText('extendedprofile.no.friends.in.this.category') }
|
||||
{ (relationshipInfo && (relationshipInfo.friendCount > 1)) &&
|
||||
LocalizeText(`extendedprofile.relstatus.others.${ relationshipName }`, [ 'count' ], [ (relationshipInfo.friendCount - 1).toString() ]) }
|
||||
|
||||
</Text>
|
||||
</Column>
|
||||
</Flex>
|
||||
);
|
||||
}, [OnUserClick, relationships, simple]);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="row justify-content-center relationships-container align-items-center flex-fill">
|
||||
<RelationshipComponent type={RelationshipStatusEnum.HEART} />
|
||||
<RelationshipComponent type={RelationshipStatusEnum.SMILE} />
|
||||
<RelationshipComponent type={RelationshipStatusEnum.BOBBA} />
|
||||
</div>
|
||||
<>
|
||||
<RelationshipComponent type={ RelationshipStatusEnum.HEART } />
|
||||
<RelationshipComponent type={ RelationshipStatusEnum.SMILE } />
|
||||
<RelationshipComponent type={ RelationshipStatusEnum.BOBBA } />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FriendlyTime, UserProfileParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { FC } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../../api';
|
||||
import { LayoutAvatarImageView } from '../../../common';
|
||||
import { Button, Column, Flex, LayoutAvatarImageView, Text } from '../../../common';
|
||||
|
||||
interface UserContainerViewProps
|
||||
{
|
||||
@ -11,42 +11,51 @@ interface UserContainerViewProps
|
||||
export const UserContainerView: FC<UserContainerViewProps> = props =>
|
||||
{
|
||||
const { userProfile = null } = props;
|
||||
|
||||
const OnlineIcon = useCallback(() =>
|
||||
{
|
||||
if(userProfile.isOnline) return (<i className="icon icon-pf-online" />);
|
||||
else return (<i className="icon icon-pf-offline" />);
|
||||
}, [ userProfile ]);
|
||||
|
||||
const FriendRequestComponent = useCallback(() =>
|
||||
{
|
||||
if(userProfile.id === GetSessionDataManager().userId) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.me')}</span> );
|
||||
|
||||
if(userProfile.isMyFriend) return (<span><i className="icon icon-pf-tick" />{LocalizeText('extendedprofile.friend')}</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>)
|
||||
}, [ userProfile ]);
|
||||
const isOwnProfile = (userProfile.id === GetSessionDataManager().userId);
|
||||
const canSendFriendRequest = (!isOwnProfile && !userProfile.isMyFriend && !userProfile.requestSent);
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-auto px-0 d-flex align-items-center">
|
||||
<LayoutAvatarImageView figure={userProfile.figure} direction={2} />
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="user-info-container">
|
||||
<div className="fw-bold">{userProfile.username}</div>
|
||||
<div className="fst-italic text-break small">{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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Flex gap={ 2 }>
|
||||
<Column center className="avatar-container">
|
||||
<LayoutAvatarImageView figure={ userProfile.figure } direction={ 2 } />
|
||||
</Column>
|
||||
<Column>
|
||||
<Column gap={ 0}>
|
||||
<Text bold>{ userProfile.username }</Text>
|
||||
<Text italics textBreak small>{ userProfile.motto } </Text>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text small>
|
||||
<b>{ LocalizeText('extendedprofile.created') }</b> { userProfile.registration }
|
||||
</Text>
|
||||
<Text small>
|
||||
<b>{ LocalizeText('extendedprofile.last.login') }</b> { FriendlyTime.format(userProfile.secondsSinceLastVisit, '.ago', 2) }
|
||||
</Text>
|
||||
<Text small>
|
||||
<b>{ LocalizeText('extendedprofile.achievementscore') }</b> { userProfile.achievementPoints }
|
||||
</Text>
|
||||
</Column>
|
||||
<Flex gap={ 1 }>
|
||||
{ userProfile.isOnline &&
|
||||
<i className="icon icon-pf-online" /> }
|
||||
{ !userProfile.isOnline &&
|
||||
<i className="icon icon-pf-offline" /> }
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
{ canSendFriendRequest &&
|
||||
<Button variant="success" className="add-friend">{ LocalizeText('extendedprofile.addasafriend') }</Button> }
|
||||
{ !canSendFriendRequest &&
|
||||
<>
|
||||
<i className="icon icon-pf-tick" />
|
||||
{ isOwnProfile &&
|
||||
<Text>{ LocalizeText('extendedprofile.me') }</Text> }
|
||||
{ userProfile.isMyFriend &&
|
||||
<Text>{ LocalizeText('extendedprofile.friend') }</Text> }
|
||||
{ userProfile.requestSent &&
|
||||
<Text>{ LocalizeText('extendedprofile.friendrequestsent') }</Text> }
|
||||
</> }
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Column>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user