mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
Update friends
This commit is contained in:
parent
91ff5d4c66
commit
2c04e7e075
@ -1,6 +1,95 @@
|
|||||||
|
.nitro-friends-spritesheet {
|
||||||
|
background: url('../../assets/images/friends/friends-spritesheet.png') transparent no-repeat;
|
||||||
|
|
||||||
|
&.icon-friendbar-visit {
|
||||||
|
width: 21px; height: 21px;
|
||||||
|
background-position: -38px -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-heart {
|
||||||
|
width: 16px; height: 14px;
|
||||||
|
background-position: -5px -67px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-new-message {
|
||||||
|
width: 14px; height: 14px;
|
||||||
|
background-position: -96px -53px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-none {
|
||||||
|
width: 16px; height: 14px;
|
||||||
|
background-position: -31px -67px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-profile {
|
||||||
|
width: 21px; height: 21px;
|
||||||
|
background-position: -5px -36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-profile-sm {
|
||||||
|
width: 13px; height: 11px;
|
||||||
|
background-position: -51px -91px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
width: 13px; height: 11px;
|
||||||
|
background-position: -74px -91px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-smile {
|
||||||
|
width: 16px; height: 14px;
|
||||||
|
background-position: -57px -67px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-warning {
|
||||||
|
width: 23px; height: 21px;
|
||||||
|
background-position: -5px -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-accept {
|
||||||
|
width: 13px; height: 14px;
|
||||||
|
background-position: -5px -91px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-add {
|
||||||
|
width: 16px; height: 15px;
|
||||||
|
background-position: -69px -31px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-bobba {
|
||||||
|
width: 16px; height: 14px;
|
||||||
|
background-position: -96px -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-chat {
|
||||||
|
width: 17px; height: 16px;
|
||||||
|
background-position: -69px -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-deny {
|
||||||
|
width: 13px; height: 14px;
|
||||||
|
background-position: -28px -91px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-follow {
|
||||||
|
width: 16px; height: 14px;
|
||||||
|
background-position: -96px -29px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-friendbar-chat {
|
||||||
|
width: 20px; height: 21px;
|
||||||
|
background-position: -36px -36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.nitro-friends {
|
.nitro-friends {
|
||||||
width: $friends-list-width;
|
width: $friends-list-width;
|
||||||
height: $friends-list-height;
|
height: $friends-list-height;
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid rgba($black, 0.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "./views/friend-bar/FriendBarView";
|
@import "./views/friend-bar/FriendBarView";
|
||||||
|
@ -344,7 +344,7 @@ export const FriendsView: FC<{}> = props =>
|
|||||||
}, [ requests ]);
|
}, [ requests ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FriendsContextProvider value={ { friends, requests, settings, acceptFriend, declineFriend } }>
|
<FriendsContextProvider value={ { friends, requests, settings, canRequestFriend, requestFriend, acceptFriend, declineFriend } }>
|
||||||
{ isReady &&
|
{ isReady &&
|
||||||
createPortal(<FriendBarView onlineFriends={ onlineFriends } />, document.getElementById('toolbar-friend-bar-container')) }
|
createPortal(<FriendBarView onlineFriends={ onlineFriends } />, document.getElementById('toolbar-friend-bar-container')) }
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
|
@ -5,6 +5,8 @@ const FriendsContext = createContext<IFriendsContext>({
|
|||||||
friends: null,
|
friends: null,
|
||||||
requests: null,
|
requests: null,
|
||||||
settings: null,
|
settings: null,
|
||||||
|
canRequestFriend: null,
|
||||||
|
requestFriend: null,
|
||||||
acceptFriend: null,
|
acceptFriend: null,
|
||||||
declineFriend: null
|
declineFriend: null
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,8 @@ export interface IFriendsContext
|
|||||||
friends: MessengerFriend[];
|
friends: MessengerFriend[];
|
||||||
requests: MessengerRequest[];
|
requests: MessengerRequest[];
|
||||||
settings: MessengerSettings;
|
settings: MessengerSettings;
|
||||||
|
canRequestFriend: (userId: number) => boolean;
|
||||||
|
requestFriend: (userId: number, userName: string) => void;
|
||||||
acceptFriend: (userId: number) => void;
|
acceptFriend: (userId: number) => void;
|
||||||
declineFriend: (userId: number, declineAll?: boolean) => void;
|
declineFriend: (userId: number, declineAll?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { FollowFriendMessageComposer, MouseEventType } from '@nitrots/nitro-rend
|
|||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { GetUserProfile, LocalizeText, OpenMessengerChat } from '../../../../api';
|
import { GetUserProfile, LocalizeText, OpenMessengerChat } from '../../../../api';
|
||||||
import { SendMessageHook } from '../../../../hooks/messages';
|
import { SendMessageHook } from '../../../../hooks/messages';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
||||||
import { FriendBarItemViewProps } from './FriendBarItemView.types';
|
import { FriendBarItemViewProps } from './FriendBarItemView.types';
|
||||||
|
|
||||||
@ -63,9 +64,10 @@ export const FriendBarItemView: FC<FriendBarItemViewProps> = props =>
|
|||||||
<div className="text-truncate">{ friend.name }</div>
|
<div className="text-truncate">{ friend.name }</div>
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
<div className="d-flex justify-content-between">
|
<div className="d-flex justify-content-between">
|
||||||
<i onClick={ openMessengerChat } className="icon icon-fb-chat cursor-pointer" />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-friendbar-chat cursor-pointer" onClick={ openMessengerChat } />
|
||||||
{ friend.followingAllowed && <i onClick={ followFriend } className="icon icon-fb-visit cursor-pointer" /> }
|
{ friend.followingAllowed &&
|
||||||
<i onClick={ event => GetUserProfile(friend.id) } className="icon icon-fb-profile cursor-pointer" />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-friendbar-visit cursor-pointer" onClick={ followFriend } /> }
|
||||||
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-profile cursor-pointer" onClick={ event => GetUserProfile(friend.id) } />
|
||||||
</div> }
|
</div> }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { FC, useMemo, useState } from 'react';
|
import { FC, useMemo, useState } from 'react';
|
||||||
|
import { NitroLayoutButton, NitroLayoutFlex } from '../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { FriendBarItemView } from '../friend-bar-item/FriendBarItemView';
|
import { FriendBarItemView } from '../friend-bar-item/FriendBarItemView';
|
||||||
import { FriendBarViewProps } from './FriendBarView.types';
|
import { FriendBarViewProps } from './FriendBarView.types';
|
||||||
|
|
||||||
@ -24,10 +26,10 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
|||||||
}, [ maxDisplayCount, indexOffset, onlineFriends ]);
|
}, [ maxDisplayCount, indexOffset, onlineFriends ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="d-flex friend-bar align-items-center">
|
<NitroLayoutFlex className="friend-bar align-items-center">
|
||||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canDecreaseIndex } onClick={ event => setIndexOffset(indexOffset - 1) }>
|
<NitroLayoutButton className="friend-bar-button" variant="black" size="sm" disabled={ !canDecreaseIndex } onClick={ event => setIndexOffset(indexOffset - 1) }>
|
||||||
<i className="fas fa-chevron-left" />
|
<NitroLayoutBase className="fas fa-chevron-left" />
|
||||||
</button>
|
</NitroLayoutButton>
|
||||||
{ Array.from(Array(maxDisplayCount), (e, i) =>
|
{ Array.from(Array(maxDisplayCount), (e, i) =>
|
||||||
{
|
{
|
||||||
return <FriendBarItemView key={ i } friend={ (onlineFriends[ indexOffset + i ] || null) } />;
|
return <FriendBarItemView key={ i } friend={ (onlineFriends[ indexOffset + i ] || null) } />;
|
||||||
@ -35,6 +37,6 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
|||||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>
|
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>
|
||||||
<i className="fas fa-chevron-right" />
|
<i className="fas fa-chevron-right" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</NitroLayoutFlex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ import { FollowFriendMessageComposer, SetRelationshipStatusComposer } from '@nit
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, OpenMessengerChat } from '../../../../api';
|
import { LocalizeText, OpenMessengerChat } from '../../../../api';
|
||||||
import { SendMessageHook } from '../../../../hooks';
|
import { SendMessageHook } from '../../../../hooks';
|
||||||
import { UserProfileIconView } from '../../../shared/user-profile-icon/UserProfileIconView';
|
import { NitroLayoutFlex, UserProfileIconView } from '../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||||
import { FriendsGroupItemViewProps } from './FriendsGroupItemView.types';
|
import { FriendsGroupItemViewProps } from './FriendsGroupItemView.types';
|
||||||
|
|
||||||
@ -52,19 +53,23 @@ export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
|||||||
<div className="px-2 py-1 d-flex gap-1 align-items-center">
|
<div className="px-2 py-1 d-flex gap-1 align-items-center">
|
||||||
<UserProfileIconView userId={ friend.id } />
|
<UserProfileIconView userId={ friend.id } />
|
||||||
<div>{ friend.name }</div>
|
<div>{ friend.name }</div>
|
||||||
<div className="ms-auto d-flex align-items-center gap-1">
|
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
||||||
{ !isExpanded && <>
|
{ !isExpanded &&
|
||||||
{ friend.followingAllowed && <i onClick={ followFriend } className="icon icon-friendlist-follow cursor-pointer" title={ LocalizeText('friendlist.tip.follow') } /> }
|
<>
|
||||||
{ friend.online && <i className="icon icon-friendlist-chat cursor-pointer" onClick={ openMessengerChat } title={ LocalizeText('friendlist.tip.im') } /> }
|
{ friend.followingAllowed &&
|
||||||
<i className={ 'icon cursor-pointer icon-relationship-' + getCurrentRelationshipName() } onClick={ () => setIsExpanded(true) } title={ LocalizeText('infostand.link.relationship') } />
|
<NitroLayoutBase onClick={ followFriend } className="nitro-friends-spritesheet icon-follow cursor-pointer" title={ LocalizeText('friendlist.tip.follow') } /> }
|
||||||
|
{ friend.online &&
|
||||||
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-chat cursor-pointer" onClick={ openMessengerChat } title={ LocalizeText('friendlist.tip.im') } /> }
|
||||||
|
<NitroLayoutBase className={ `nitro-friends-spritesheet icon-${ getCurrentRelationshipName() } cursor-pointer` }onClick={ event => setIsExpanded(true) } title={ LocalizeText('infostand.link.relationship') } />
|
||||||
</> }
|
</> }
|
||||||
{ isExpanded && <>
|
{ isExpanded &&
|
||||||
<i className="icon icon-relationship-heart cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_HEART) } />
|
<>
|
||||||
<i className="icon icon-relationship-smile cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_SMILE) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-heart cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_HEART) } />
|
||||||
<i className="icon icon-relationship-bobba cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_BOBBA) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-smile cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_SMILE) } />
|
||||||
<i className="icon icon-relationship-none cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_NONE) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-bobba cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_BOBBA) } />
|
||||||
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-none cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_NONE) } />
|
||||||
</> }
|
</> }
|
||||||
</div>
|
</NitroLayoutFlex>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { LocalizeText } from '../../../../api';
|
|||||||
import { NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
import { NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
||||||
import { FriendsGroupView } from '../friends-group/FriendsGroupView';
|
import { FriendsGroupView } from '../friends-group/FriendsGroupView';
|
||||||
import { FriendsRequestView } from '../friends-request/FriendsRequestView';
|
import { FriendsRequestView } from '../friends-request/FriendsRequestView';
|
||||||
|
import { FriendsSearchView } from '../friends-search/FriendsSearchView';
|
||||||
import { FriendsListViewProps } from './FriendsListView.types';
|
import { FriendsListViewProps } from './FriendsListView.types';
|
||||||
|
|
||||||
const MODE_FRIENDS: number = 0;
|
const MODE_FRIENDS: number = 0;
|
||||||
@ -15,7 +16,7 @@ export const FriendsListView: FC<FriendsListViewProps> = props =>
|
|||||||
const [ mode, setMode ] = useState<number>(0);
|
const [ mode, setMode ] = useState<number>(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-friends">
|
<NitroCardView className="nitro-friends" uniqueKey="nitro-friends">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('friendlist.friends') } onCloseClick={ onCloseClick } />
|
<NitroCardHeaderView headerText={ LocalizeText('friendlist.friends') } onCloseClick={ onCloseClick } />
|
||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
<NitroCardTabsItemView isActive={ (mode === MODE_FRIENDS) } count={ friendRequests.length } onClick={ event => setMode(MODE_FRIENDS) }>
|
<NitroCardTabsItemView isActive={ (mode === MODE_FRIENDS) } count={ friendRequests.length } onClick={ event => setMode(MODE_FRIENDS) }>
|
||||||
@ -34,13 +35,10 @@ export const FriendsListView: FC<FriendsListViewProps> = props =>
|
|||||||
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends.offlinecaption') + ` (${offlineFriends.length})` }>
|
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends.offlinecaption') + ` (${offlineFriends.length})` }>
|
||||||
<FriendsGroupView list={ offlineFriends } />
|
<FriendsGroupView list={ offlineFriends } />
|
||||||
</NitroCardAccordionSetView>
|
</NitroCardAccordionSetView>
|
||||||
|
|
||||||
|
|
||||||
<FriendsRequestView requests={ friendRequests } />
|
<FriendsRequestView requests={ friendRequests } />
|
||||||
</NitroCardAccordionView> }
|
</NitroCardAccordionView> }
|
||||||
{ (mode === MODE_SEARCH) &&
|
{ (mode === MODE_SEARCH) &&
|
||||||
<>
|
<FriendsSearchView /> }
|
||||||
</> }
|
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { NitroCardAccordionItemView } from '../../../../layout';
|
import { NitroCardAccordionItemView, NitroLayoutFlex, UserProfileIconView } from '../../../../layout';
|
||||||
import { UserProfileIconView } from '../../../shared/user-profile-icon/UserProfileIconView';
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { useFriendsContext } from '../../context/FriendsContext';
|
import { useFriendsContext } from '../../context/FriendsContext';
|
||||||
import { FriendsRequestItemViewProps } from './FriendsRequestItemView.types';
|
import { FriendsRequestItemViewProps } from './FriendsRequestItemView.types';
|
||||||
|
|
||||||
@ -14,11 +14,11 @@ export const FriendsRequestItemView: FC<FriendsRequestItemViewProps> = props =>
|
|||||||
return (
|
return (
|
||||||
<NitroCardAccordionItemView>
|
<NitroCardAccordionItemView>
|
||||||
<UserProfileIconView userId={ request.id } />
|
<UserProfileIconView userId={ request.id } />
|
||||||
<div>{ request.name }</div>
|
<NitroLayoutBase>{ request.name }</NitroLayoutBase>
|
||||||
<div className="ms-auto d-flex align-items-center gap-1">
|
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
||||||
<i className="icon icon-accept cursor-pointer" onClick={ event => acceptFriend(request.requesterUserId) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-accept cursor-pointer" onClick={ event => acceptFriend(request.requesterUserId) } />
|
||||||
<i className="icon icon-deny cursor-pointer" onClick={ event => declineFriend(request.requesterUserId) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-deny cursor-pointer" onClick={ event => declineFriend(request.requesterUserId) } />
|
||||||
</div>
|
</NitroLayoutFlex>
|
||||||
</NitroCardAccordionItemView>
|
</NitroCardAccordionItemView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
80
src/views/friends/views/friends-search/FriendsSearchView.tsx
Normal file
80
src/views/friends/views/friends-search/FriendsSearchView.tsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { LocalizeText, OpenMessengerChat } from '../../../../api';
|
||||||
|
import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../hooks';
|
||||||
|
import { NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionView, NitroLayoutFlex, UserProfileIconView } from '../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
|
import { useFriendsContext } from '../../context/FriendsContext';
|
||||||
|
|
||||||
|
export const FriendsSearchView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const [ searchValue, setSearchValue ] = useState('');
|
||||||
|
const [ friendResults, setFriendResults ] = useState<HabboSearchResultData[]>([]);
|
||||||
|
const [ otherResults, setOtherResults ] = useState<HabboSearchResultData[]>([]);
|
||||||
|
const { canRequestFriend = null, requestFriend = null } = useFriendsContext();
|
||||||
|
|
||||||
|
const onHabboSearchResultEvent = useCallback((event: HabboSearchResultEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setFriendResults(parser.friends);
|
||||||
|
setOtherResults(parser.others);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(HabboSearchResultEvent, onHabboSearchResultEvent);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!searchValue || !searchValue.length) return;
|
||||||
|
|
||||||
|
const timeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
if(!searchValue || !searchValue.length) return;
|
||||||
|
|
||||||
|
SendMessageHook(new HabboSearchComposer(searchValue));
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}, [ searchValue ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<input type="text" className="search-input form-control form-control-sm w-100 rounded-0" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
||||||
|
<NitroCardAccordionView>
|
||||||
|
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.search.friendscaption', [ 'cnt' ], [ friendResults.length.toString() ]) } isExpanded={ true }>
|
||||||
|
{ (friendResults.length > 0) && friendResults.map(result =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<NitroCardAccordionItemView key={ result.avatarId }>
|
||||||
|
<UserProfileIconView userId={ result.avatarId } />
|
||||||
|
<NitroLayoutBase>{ result.avatarName }</NitroLayoutBase>
|
||||||
|
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
||||||
|
{ result.isAvatarOnline &&
|
||||||
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-chat cursor-pointer" onClick={ event => OpenMessengerChat(result.avatarId) } title={ LocalizeText('friendlist.tip.im') } /> }
|
||||||
|
</NitroLayoutFlex>
|
||||||
|
</NitroCardAccordionItemView>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
</NitroCardAccordionSetView>
|
||||||
|
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.search.otherscaption', [ 'cnt' ], [ otherResults.length.toString() ]) } isExpanded={ true }>
|
||||||
|
{ (otherResults.length > 0) && otherResults.map(result =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<NitroCardAccordionItemView key={ result.avatarId }>
|
||||||
|
<UserProfileIconView userId={ result.avatarId } />
|
||||||
|
<NitroLayoutBase>{ result.avatarName }</NitroLayoutBase>
|
||||||
|
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
||||||
|
{ canRequestFriend(result.avatarId) &&
|
||||||
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-add cursor-pointer" onClick={ event => requestFriend(result.avatarId, result.avatarName) } title={ LocalizeText('friendlist.tip.addfriend') } /> }
|
||||||
|
</NitroLayoutFlex>
|
||||||
|
</NitroCardAccordionItemView>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
</NitroCardAccordionSetView>
|
||||||
|
</NitroCardAccordionView>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { GetSessionDataManager } from '../../../../api';
|
import { GetSessionDataManager } from '../../../../api';
|
||||||
|
import { NitroLayoutFlex } from '../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
||||||
import { MessengerThreadChat } from '../../common/MessengerThreadChat';
|
import { MessengerThreadChat } from '../../common/MessengerThreadChat';
|
||||||
import { FriendsMessengerThreadGroupProps } from './FriendsMessengerThreadGroup.types';
|
import { FriendsMessengerThreadGroupProps } from './FriendsMessengerThreadGroup.types';
|
||||||
@ -17,13 +19,13 @@ export const FriendsMessengerThreadGroup: FC<FriendsMessengerThreadGroupProps> =
|
|||||||
{ group.chats.map((chat, index) =>
|
{ group.chats.map((chat, index) =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div key={ index } className="text-break">
|
<NitroLayoutBase key={ index } className="text-break">
|
||||||
{ chat.type === MessengerThreadChat.SECURITY_NOTIFICATION &&
|
{ chat.type === MessengerThreadChat.SECURITY_NOTIFICATION &&
|
||||||
<div className="bg-light rounded mb-2 d-flex gap-2 px-2 py-1 small text-muted align-items-center">
|
<NitroLayoutBase className="bg-light rounded mb-2 d-flex gap-2 px-2 py-1 small text-muted align-items-center">
|
||||||
<i className="icon icon-friendlist-warning flex-shrink-0" />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-warning flex-shrink-0" />
|
||||||
<div>{ chat.message }</div>
|
<NitroLayoutBase>{ chat.message }</NitroLayoutBase>
|
||||||
</div> }
|
</NitroLayoutBase> }
|
||||||
</div>
|
</NitroLayoutBase>
|
||||||
);
|
);
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
@ -31,18 +33,18 @@ export const FriendsMessengerThreadGroup: FC<FriendsMessengerThreadGroupProps> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ 'd-flex gap-2 w-100 justify-content-' + (group.userId === 0 ? 'end' : 'start') }>
|
<NitroLayoutFlex className={ 'w-100 justify-content-' + (group.userId === 0 ? 'end' : 'start') } gap={ 2 }>
|
||||||
{ (group.userId > 0) &&
|
{ (group.userId > 0) &&
|
||||||
<div className="message-avatar flex-shrink-0">
|
<NitroLayoutBase className="message-avatar flex-shrink-0">
|
||||||
<AvatarImageView figure={ thread.participant.figure } direction={ 2 } />
|
<AvatarImageView figure={ thread.participant.figure } direction={ 2 } />
|
||||||
</div> }
|
</NitroLayoutBase> }
|
||||||
<div className={ 'bg-light text-black border-radius mb-2 rounded py-1 px-2 messages-group-' + (group.userId === 0 ? 'right' : 'left') }>
|
<NitroLayoutBase className={ 'bg-light text-black border-radius mb-2 rounded py-1 px-2 messages-group-' + (group.userId === 0 ? 'right' : 'left') }>
|
||||||
{ group.chats.map((chat, index) => <div key={ index } className="text-break">{ chat.message }</div>) }
|
{ group.chats.map((chat, index) => <NitroLayoutBase key={ index } className="text-break">{ chat.message }</NitroLayoutBase>) }
|
||||||
</div>
|
</NitroLayoutBase>
|
||||||
{ (group.userId === 0) &&
|
{ (group.userId === 0) &&
|
||||||
<div className="message-avatar flex-shrink-0">
|
<NitroLayoutBase className="message-avatar flex-shrink-0">
|
||||||
<AvatarImageView figure={ GetSessionDataManager().figure } direction={ 4 } />
|
<AvatarImageView figure={ GetSessionDataManager().figure } direction={ 4 } />
|
||||||
</div> }
|
</NitroLayoutBase> }
|
||||||
</div>
|
</NitroLayoutFlex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ import { FC, KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState }
|
|||||||
import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
||||||
import { FriendsMessengerIconEvent } from '../../../../events';
|
import { FriendsMessengerIconEvent } from '../../../../events';
|
||||||
import { BatchUpdates, CreateMessageHook, dispatchUiEvent, SendMessageHook } from '../../../../hooks';
|
import { BatchUpdates, CreateMessageHook, dispatchUiEvent, SendMessageHook } from '../../../../hooks';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex } from '../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutButtonGroup, NitroLayoutFlex, NitroLayoutFlexColumn } from '../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../layout/base';
|
||||||
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
||||||
import { MessengerThread } from '../../common/MessengerThread';
|
import { MessengerThread } from '../../common/MessengerThread';
|
||||||
import { MessengerThreadChat } from '../../common/MessengerThreadChat';
|
import { MessengerThreadChat } from '../../common/MessengerThreadChat';
|
||||||
@ -232,7 +233,7 @@ export const FriendsMessengerView: FC<{}> = props =>
|
|||||||
if(!isVisible) return null;
|
if(!isVisible) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-friends-messenger" simple={ true }>
|
<NitroCardView className="nitro-friends-messenger" uniqueKey="nitro-friends-messenger" simple={ true }>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('messenger.window.title', [ 'OPEN_CHAT_COUNT' ], [ visibleThreads.length.toString() ]) } onCloseClick={ event => setIsVisible(false) } />
|
<NitroCardHeaderView headerText={ LocalizeText('messenger.window.title', [ 'OPEN_CHAT_COUNT' ], [ visibleThreads.length.toString() ]) } onCloseClick={ event => setIsVisible(false) } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
<NitroLayoutFlex gap={ 2 } overflow="auto">
|
<NitroLayoutFlex gap={ 2 } overflow="auto">
|
||||||
@ -241,8 +242,9 @@ export const FriendsMessengerView: FC<{}> = props =>
|
|||||||
const messageThreadIndex = messageThreads.indexOf(thread);
|
const messageThreadIndex = messageThreads.indexOf(thread);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={ index } className="friend-head rounded flex-shrink-0 cursor-pointer bg-muted" onClick={ event => setActiveThreadIndex(messageThreadIndex) }>
|
<div key={ index } className="position-relative friend-head rounded flex-shrink-0 cursor-pointer bg-muted" onClick={ event => setActiveThreadIndex(messageThreadIndex) }>
|
||||||
{ thread.unread && <i className="icon icon-friendlist-new-message" /> }
|
{ thread.unread &&
|
||||||
|
<NitroLayoutBase className="position-absolute nitro-friends-spritesheet icon-new-message top-1 end-1 z-index-1" /> }
|
||||||
<AvatarImageView figure={ thread.participant.figure } headOnly={ true } direction={ 3 } />
|
<AvatarImageView figure={ thread.participant.figure } headOnly={ true } direction={ 3 } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -250,32 +252,38 @@ export const FriendsMessengerView: FC<{}> = props =>
|
|||||||
</NitroLayoutFlex>
|
</NitroLayoutFlex>
|
||||||
<NitroLayoutFlex className="align-items-center my-1" position="relative">
|
<NitroLayoutFlex className="align-items-center my-1" position="relative">
|
||||||
{ (activeThreadIndex >= 0) &&
|
{ (activeThreadIndex >= 0) &&
|
||||||
<div className="text-black bg-light pe-2 flex-none">
|
<NitroLayoutBase className="text-black bg-light pe-2 flex-none">
|
||||||
{ LocalizeText('messenger.window.separator', [ 'FRIEND_NAME' ], [ messageThreads[activeThreadIndex].participant.name ]) }
|
{ LocalizeText('messenger.window.separator', [ 'FRIEND_NAME' ], [ messageThreads[activeThreadIndex].participant.name ]) }
|
||||||
</div> }
|
</NitroLayoutBase> }
|
||||||
<hr className="bg-dark m-0 w-100" />
|
<hr className="bg-dark m-0 w-100" />
|
||||||
</NitroLayoutFlex>
|
</NitroLayoutFlex>
|
||||||
{ (activeThreadIndex >= 0) &&
|
{ (activeThreadIndex >= 0) &&
|
||||||
<>
|
<>
|
||||||
<div className="d-flex gap-2 mb-2">
|
<NitroLayoutFlex className="mb-2" gap={ 2 }>
|
||||||
<div className="btn-group">
|
<NitroLayoutButtonGroup>
|
||||||
<button className="d-flex justify-content-center align-items-center btn btn-sm btn-primary" onClick={ followFriend }>
|
<NitroLayoutButton variant="primary" size="sm" onClick={ followFriend }>
|
||||||
<i className="icon icon-friendlist-follow" />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-follow" />
|
||||||
</button>
|
</NitroLayoutButton>
|
||||||
<button className="d-flex justify-content-center align-items-center btn btn-sm btn-primary" onClick={ openProfile }>
|
<NitroLayoutButton variant="primary" size="sm" onClick={ openProfile }>
|
||||||
<i className="icon icon-user-profile" />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-profile-sm" />
|
||||||
</button>
|
</NitroLayoutButton>
|
||||||
</div>
|
</NitroLayoutButtonGroup>
|
||||||
<button className="btn btn-sm btn-danger">{ LocalizeText('messenger.window.button.report') }</button>
|
<NitroLayoutButton variant="danger" size="sm" onClick={ openProfile }>
|
||||||
<button className="btn btn-sm btn-primary ms-auto" onClick={ event => closeThread(activeThreadIndex) }><i className="fas fa-times" /></button>
|
{ LocalizeText('messenger.window.button.report') }
|
||||||
</div>
|
</NitroLayoutButton>
|
||||||
<div ref={ messagesBox } className="bg-muted p-2 rounded chat-messages mb-2 d-flex flex-column">
|
<NitroLayoutButton className="ms-auto" variant="primary" size="sm" onClick={ event => closeThread(activeThreadIndex) }>
|
||||||
|
<NitroLayoutBase className="fas fa-times" />
|
||||||
|
</NitroLayoutButton>
|
||||||
|
</NitroLayoutFlex>
|
||||||
|
<NitroLayoutFlexColumn innerRef={ messagesBox } className="bg-muted p-2 rounded chat-messages mb-2">
|
||||||
<FriendsMessengerThreadView thread={ messageThreads[activeThreadIndex] } />
|
<FriendsMessengerThreadView thread={ messageThreads[activeThreadIndex] } />
|
||||||
</div>
|
</NitroLayoutFlexColumn>
|
||||||
<div className="d-flex gap-2">
|
<NitroLayoutFlex gap={ 2 }>
|
||||||
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('messenger.window.input.default', [ 'FRIEND_NAME' ], [ messageThreads[activeThreadIndex].participant.name ]) } value={ messageText } onChange={ event => setMessageText(event.target.value) } onKeyDown={ onKeyDown } />
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('messenger.window.input.default', [ 'FRIEND_NAME' ], [ messageThreads[activeThreadIndex].participant.name ]) } value={ messageText } onChange={ event => setMessageText(event.target.value) } onKeyDown={ onKeyDown } />
|
||||||
<button className="btn btn-sm btn-success" onClick={ sendMessage }>{ LocalizeText('widgets.chatinput.say') }</button>
|
<NitroLayoutButton variant="success" size="sm" onClick={ sendMessage }>
|
||||||
</div>
|
{ LocalizeText('widgets.chatinput.say') }
|
||||||
|
</NitroLayoutButton>
|
||||||
|
</NitroLayoutFlex>
|
||||||
</> }
|
</> }
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AcceptFriendMessageComposer, DeclineFriendMessageComposer } from '@nitrots/nitro-renderer';
|
import { AcceptFriendMessageComposer, DeclineFriendMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { SendMessageHook } from '../../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../../hooks';
|
||||||
import { UserProfileIconView } from '../../../shared/user-profile-icon/UserProfileIconView';
|
import { UserProfileIconView } from '../../../../layout';
|
||||||
import { FriendsRequestItemViewProps } from './FriendsRequestItemView.types';
|
import { FriendsRequestItemViewProps } from './FriendsRequestItemView.types';
|
||||||
|
|
||||||
export const FriendsRequestItemView: FC<FriendsRequestItemViewProps> = props =>
|
export const FriendsRequestItemView: FC<FriendsRequestItemViewProps> = props =>
|
||||||
|
Loading…
Reference in New Issue
Block a user