mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-30 08:50:51 +01:00
Room invite + friend deletion
This commit is contained in:
parent
9666a4103a
commit
77819a7e2b
@ -92,5 +92,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nitro-friends-room-invite {
|
||||||
|
width: $friends-list-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-friends-remove-confirmation {
|
||||||
|
width: $friends-list-width;
|
||||||
|
}
|
||||||
|
|
||||||
@import "./views/friend-bar/FriendBarView";
|
@import "./views/friend-bar/FriendBarView";
|
||||||
@import "./views/messenger/FriendsMessengerView";
|
@import "./views/messenger/FriendsMessengerView";
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FollowFriendMessageComposer, SetRelationshipStatusComposer } from '@nitrots/nitro-renderer';
|
import { FollowFriendMessageComposer, SetRelationshipStatusComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import classNames from 'classnames';
|
||||||
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';
|
||||||
@ -9,7 +10,7 @@ import { FriendsGroupItemViewProps } from './FriendsGroupItemView.types';
|
|||||||
|
|
||||||
export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { friend = null, selected = false, children = null, ...rest } = props;
|
const { friend = null, selected = false, selectFriend = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
const [ isExpanded, setIsExpanded ] = useState<boolean>(false);
|
const [ isExpanded, setIsExpanded ] = useState<boolean>(false);
|
||||||
|
|
||||||
@ -20,8 +21,10 @@ export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
|||||||
SendMessageHook(new FollowFriendMessageComposer(friend.id));
|
SendMessageHook(new FollowFriendMessageComposer(friend.id));
|
||||||
}, [ friend ]);
|
}, [ friend ]);
|
||||||
|
|
||||||
const openMessengerChat = useCallback(() =>
|
const openMessengerChat = useCallback((e) =>
|
||||||
{
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
if(!friend) return;
|
if(!friend) return;
|
||||||
|
|
||||||
OpenMessengerChat(friend.id);
|
OpenMessengerChat(friend.id);
|
||||||
@ -40,8 +43,16 @@ export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ friend ]);
|
}, [ friend ]);
|
||||||
|
|
||||||
const updateRelationship = useCallback((type: number) =>
|
const initUpdateRelationship = useCallback((e) =>
|
||||||
{
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsExpanded(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const updateRelationship = useCallback((e, type: number) =>
|
||||||
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
if(type !== friend.relationshipStatus) SendMessageHook(new SetRelationshipStatusComposer(friend.id, type));
|
if(type !== friend.relationshipStatus) SendMessageHook(new SetRelationshipStatusComposer(friend.id, type));
|
||||||
|
|
||||||
setIsExpanded(false);
|
setIsExpanded(false);
|
||||||
@ -50,8 +61,10 @@ export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
|||||||
if(!friend) return null;
|
if(!friend) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroLayoutFlex className="px-2 py-1 align-items-center" gap={ 1 } { ...rest }>
|
<NitroLayoutFlex className={ 'px-2 py-1 align-items-center' + classNames({ ' bg-primary text-white': selected }) } gap={ 1 } { ...rest } onClick={ selectFriend }>
|
||||||
<UserProfileIconView userId={ friend.id } />
|
<div onClick={ (e) => e.stopPropagation() }>
|
||||||
|
<UserProfileIconView userId={ friend.id } />
|
||||||
|
</div>
|
||||||
<div>{ friend.name }</div>
|
<div>{ friend.name }</div>
|
||||||
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
<NitroLayoutFlex className="ms-auto align-items-center" gap={ 1 }>
|
||||||
{ !isExpanded &&
|
{ !isExpanded &&
|
||||||
@ -60,14 +73,14 @@ export const FriendsGroupItemView: FC<FriendsGroupItemViewProps> = props =>
|
|||||||
<NitroLayoutBase onClick={ followFriend } className="nitro-friends-spritesheet icon-follow cursor-pointer" title={ LocalizeText('friendlist.tip.follow') } /> }
|
<NitroLayoutBase onClick={ followFriend } className="nitro-friends-spritesheet icon-follow cursor-pointer" title={ LocalizeText('friendlist.tip.follow') } /> }
|
||||||
{ friend.online &&
|
{ friend.online &&
|
||||||
<NitroLayoutBase className="nitro-friends-spritesheet icon-chat cursor-pointer" onClick={ openMessengerChat } title={ LocalizeText('friendlist.tip.im') } /> }
|
<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') } />
|
<NitroLayoutBase className={ `nitro-friends-spritesheet icon-${ getCurrentRelationshipName() } cursor-pointer` } onClick={ initUpdateRelationship } title={ LocalizeText('infostand.link.relationship') } />
|
||||||
</> }
|
</> }
|
||||||
{ isExpanded &&
|
{ isExpanded &&
|
||||||
<>
|
<>
|
||||||
<NitroLayoutBase className="nitro-friends-spritesheet icon-heart cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_HEART) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-heart cursor-pointer" onClick={ (e) => updateRelationship(e, MessengerFriend.RELATIONSHIP_HEART) } />
|
||||||
<NitroLayoutBase className="nitro-friends-spritesheet icon-smile cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_SMILE) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-smile cursor-pointer" onClick={ (e) => updateRelationship(e, MessengerFriend.RELATIONSHIP_SMILE) } />
|
||||||
<NitroLayoutBase className="nitro-friends-spritesheet icon-bobba cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_BOBBA) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-bobba cursor-pointer" onClick={ (e) => updateRelationship(e, MessengerFriend.RELATIONSHIP_BOBBA) } />
|
||||||
<NitroLayoutBase className="nitro-friends-spritesheet icon-none cursor-pointer" onClick={ () => updateRelationship(MessengerFriend.RELATIONSHIP_NONE) } />
|
<NitroLayoutBase className="nitro-friends-spritesheet icon-none cursor-pointer" onClick={ (e) => updateRelationship(e, MessengerFriend.RELATIONSHIP_NONE) } />
|
||||||
</> }
|
</> }
|
||||||
</NitroLayoutFlex>
|
</NitroLayoutFlex>
|
||||||
{ children }
|
{ children }
|
||||||
|
@ -5,4 +5,5 @@ export interface FriendsGroupItemViewProps extends NitroLayoutFlexProps
|
|||||||
{
|
{
|
||||||
friend: MessengerFriend;
|
friend: MessengerFriend;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
|
selectFriend: () => void;
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,15 @@ import { FriendsGroupViewProps } from './FriendsGroupView.types';
|
|||||||
|
|
||||||
export const FriendsGroupView: FC<FriendsGroupViewProps> = props =>
|
export const FriendsGroupView: FC<FriendsGroupViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { list = null } = props;
|
const { list = null, selectedFriendsIds = null, selectFriend = null } = props;
|
||||||
|
|
||||||
if(!list) return null;
|
if(!list) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ list.map((item, index) =>
|
{ selectedFriendsIds && list && list.map((item, index) =>
|
||||||
{
|
{
|
||||||
return <FriendsGroupItemView key={ index } friend={ item } />;
|
return <FriendsGroupItemView key={ index } friend={ item } selected={ selectedFriendsIds.includes(item.id) } selectFriend={ () => selectFriend(item.id) } />;
|
||||||
}) }
|
}) }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -3,4 +3,6 @@ import { MessengerFriend } from '../../common/MessengerFriend';
|
|||||||
export interface FriendsGroupViewProps
|
export interface FriendsGroupViewProps
|
||||||
{
|
{
|
||||||
list: MessengerFriend[];
|
list: MessengerFriend[];
|
||||||
|
selectedFriendsIds: number[];
|
||||||
|
selectFriend: (userId: number) => void;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { FC, useEffect, useState } from 'react';
|
import { RemoveFriendComposer, SendRoomInviteComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useCallback, useMemo, useState } from 'react';
|
||||||
import { LocalizeText } from '../../../../api';
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { SendMessageHook } from '../../../../hooks';
|
||||||
import { NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
import { NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
||||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||||
import { FriendsGroupView } from '../friends-group/FriendsGroupView';
|
import { FriendsGroupView } from '../friends-group/FriendsGroupView';
|
||||||
|
import { FriendsRemoveConfirmationView } from '../friends-remove-confirmation/FriendsRemoveConfirmationView';
|
||||||
import { FriendsRequestView } from '../friends-request/FriendsRequestView';
|
import { FriendsRequestView } from '../friends-request/FriendsRequestView';
|
||||||
|
import { FriendsRoomInviteView } from '../friends-room-invite/FriendsRoomInviteView';
|
||||||
import { FriendsSearchView } from '../friends-search/FriendsSearchView';
|
import { FriendsSearchView } from '../friends-search/FriendsSearchView';
|
||||||
import { FriendsListViewProps } from './FriendsListView.types';
|
import { FriendsListViewProps } from './FriendsListView.types';
|
||||||
|
|
||||||
@ -13,39 +17,107 @@ const MODE_SEARCH: number = 1;
|
|||||||
export const FriendsListView: FC<FriendsListViewProps> = props =>
|
export const FriendsListView: FC<FriendsListViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { onlineFriends = [], offlineFriends = [], friendRequests = [], onCloseClick = null } = props;
|
const { onlineFriends = [], offlineFriends = [], friendRequests = [], onCloseClick = null } = props;
|
||||||
const [ selectedFriends, setSelectedFriends ] = useState<MessengerFriend[]>([]);
|
|
||||||
const [ mode, setMode ] = useState<number>(0);
|
|
||||||
|
|
||||||
useEffect(() =>
|
const [ selectedFriendsIds, setSelectedFriendsIds ] = useState<number[]>([]);
|
||||||
|
const [ mode, setMode ] = useState<number>(0);
|
||||||
|
|
||||||
|
const [ showRoomInvite, setShowRoomInvite ] = useState<boolean>(false);
|
||||||
|
const [ showRemoveFriendsConfirmation, setShowRemoveFriendsConfirmation ] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const removeFriendsText = useMemo(() =>
|
||||||
{
|
{
|
||||||
setSelectedFriends([]);
|
if(!selectedFriendsIds || !selectedFriendsIds.length) return '';
|
||||||
}, [ onlineFriends, offlineFriends ]);
|
|
||||||
|
const userNames: string[] = [];
|
||||||
|
|
||||||
|
for(const userId of selectedFriendsIds)
|
||||||
|
{
|
||||||
|
let existingFriend: MessengerFriend = onlineFriends.find(f => f.id === userId);
|
||||||
|
|
||||||
|
if(!existingFriend) existingFriend = offlineFriends.find(f => f.id === userId);
|
||||||
|
|
||||||
|
if(!existingFriend) continue;
|
||||||
|
|
||||||
|
userNames.push(existingFriend.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LocalizeText('friendlist.removefriendconfirm.userlist', ['user_names'], [userNames.join(', ')]);
|
||||||
|
}, [offlineFriends, onlineFriends, selectedFriendsIds]);
|
||||||
|
|
||||||
|
const selectFriend = useCallback((userId: number) =>
|
||||||
|
{
|
||||||
|
if(userId < 0) return;
|
||||||
|
|
||||||
|
const existingUserIdIndex: number = selectedFriendsIds.indexOf(userId);
|
||||||
|
|
||||||
|
if(existingUserIdIndex > -1)
|
||||||
|
{
|
||||||
|
const clonedFriend = [...selectedFriendsIds];
|
||||||
|
clonedFriend.splice(existingUserIdIndex, 1)
|
||||||
|
|
||||||
|
setSelectedFriendsIds([...clonedFriend]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setSelectedFriendsIds([...selectedFriendsIds, userId]);
|
||||||
|
}
|
||||||
|
}, [ selectedFriendsIds, setSelectedFriendsIds ]);
|
||||||
|
|
||||||
|
const sendRoomInvite = useCallback((message: string) =>
|
||||||
|
{
|
||||||
|
if(selectedFriendsIds.length === 0 || !message || message.length === 0) return;
|
||||||
|
|
||||||
|
SendMessageHook(new SendRoomInviteComposer(message, ...selectedFriendsIds));
|
||||||
|
setShowRoomInvite(false);
|
||||||
|
}, [ selectedFriendsIds, setShowRoomInvite ]);
|
||||||
|
|
||||||
|
const removeSelectedFriends = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(selectedFriendsIds.length === 0) return;
|
||||||
|
|
||||||
|
SendMessageHook(new RemoveFriendComposer(...selectedFriendsIds));
|
||||||
|
setSelectedFriendsIds([]);
|
||||||
|
setShowRemoveFriendsConfirmation(false);
|
||||||
|
}, [ selectedFriendsIds ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-friends" uniqueKey="nitro-friends">
|
<>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('friendlist.friends') } onCloseClick={ onCloseClick } />
|
<NitroCardView className="nitro-friends" uniqueKey="nitro-friends">
|
||||||
<NitroCardTabsView>
|
<NitroCardHeaderView headerText={ LocalizeText('friendlist.friends') } onCloseClick={ onCloseClick } />
|
||||||
<NitroCardTabsItemView isActive={ (mode === MODE_FRIENDS) } count={ friendRequests.length } onClick={ event => setMode(MODE_FRIENDS) }>
|
<NitroCardTabsView>
|
||||||
{ LocalizeText('friendlist.friends') }
|
<NitroCardTabsItemView isActive={ (mode === MODE_FRIENDS) } count={ friendRequests.length } onClick={ event => setMode(MODE_FRIENDS) }>
|
||||||
</NitroCardTabsItemView>
|
{ LocalizeText('friendlist.friends') }
|
||||||
<NitroCardTabsItemView isActive={ (mode === MODE_SEARCH) } onClick={ event => setMode(MODE_SEARCH) }>
|
</NitroCardTabsItemView>
|
||||||
{ LocalizeText('generic.search') }
|
<NitroCardTabsItemView isActive={ (mode === MODE_SEARCH) } onClick={ event => setMode(MODE_SEARCH) }>
|
||||||
</NitroCardTabsItemView>
|
{ LocalizeText('generic.search') }
|
||||||
</NitroCardTabsView>
|
</NitroCardTabsItemView>
|
||||||
<NitroCardContentView className="p-0 text-black">
|
</NitroCardTabsView>
|
||||||
{ (mode === MODE_FRIENDS) &&
|
<NitroCardContentView className="p-0 text-black">
|
||||||
<NitroCardAccordionView>
|
{ (mode === MODE_FRIENDS) &&
|
||||||
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends') + ` (${onlineFriends.length})` } isExpanded={ true }>
|
<>
|
||||||
<FriendsGroupView list={ onlineFriends } />
|
<NitroCardAccordionView className="overflow-y-auto">
|
||||||
</NitroCardAccordionSetView>
|
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends') + ` (${onlineFriends.length})` } isExpanded={ true }>
|
||||||
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends.offlinecaption') + ` (${offlineFriends.length})` }>
|
<FriendsGroupView list={ onlineFriends } selectedFriendsIds={ selectedFriendsIds } selectFriend={ selectFriend } />
|
||||||
<FriendsGroupView list={ offlineFriends } />
|
</NitroCardAccordionSetView>
|
||||||
</NitroCardAccordionSetView>
|
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.friends.offlinecaption') + ` (${offlineFriends.length})` }>
|
||||||
<FriendsRequestView requests={ friendRequests } />
|
<FriendsGroupView list={ offlineFriends } selectedFriendsIds={ selectedFriendsIds } selectFriend={ selectFriend } />
|
||||||
</NitroCardAccordionView> }
|
</NitroCardAccordionSetView>
|
||||||
{ (mode === MODE_SEARCH) &&
|
<FriendsRequestView requests={ friendRequests } />
|
||||||
<FriendsSearchView /> }
|
</NitroCardAccordionView>
|
||||||
</NitroCardContentView>
|
{ selectedFriendsIds && selectedFriendsIds.length > 0 && <div className="d-flex gap-2 p-2">
|
||||||
</NitroCardView>
|
<button className="btn btn-primary w-100" onClick={ () => setShowRoomInvite(true) }>Invite</button>
|
||||||
|
<button className="btn btn-danger w-100" onClick={ () => setShowRemoveFriendsConfirmation(true) }>Delete</button>
|
||||||
|
</div> }
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{ (mode === MODE_SEARCH) &&
|
||||||
|
<FriendsSearchView /> }
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
{ showRoomInvite &&
|
||||||
|
<FriendsRoomInviteView selectedFriendsIds={ selectedFriendsIds } onCloseClick={ () => setShowRoomInvite(false) } sendRoomInvite={ sendRoomInvite } /> }
|
||||||
|
{ showRemoveFriendsConfirmation &&
|
||||||
|
<FriendsRemoveConfirmationView selectedFriendsIds={ selectedFriendsIds } removeFriendsText={ removeFriendsText } onCloseClick={ () => setShowRemoveFriendsConfirmation(false) } removeSelectedFriends={ removeSelectedFriends } /> }
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { FriendsRemoveConfirmationViewProps } from './FriendsRemoveConfirmationView.types';
|
||||||
|
|
||||||
|
export const FriendsRemoveConfirmationView: FC<FriendsRemoveConfirmationViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { selectedFriendsIds = null, removeFriendsText = null, removeSelectedFriends = null, onCloseClick = null } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-friends-remove-confirmation" uniqueKey="nitro-friends-remove-confirmation" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('friendlist.removefriendconfirm.title') } onCloseClick={ onCloseClick } />
|
||||||
|
<NitroCardContentView className="text-black d-flex flex-column gap-3">
|
||||||
|
<div>{ removeFriendsText }</div>
|
||||||
|
<div className="d-flex gap-2">
|
||||||
|
<button className="btn btn-danger w-100" disabled={ selectedFriendsIds.length === 0 } onClick={ removeSelectedFriends }>{ LocalizeText('generic.ok') }</button>
|
||||||
|
<button className="btn btn-primary w-100" onClick={ onCloseClick }>{ LocalizeText('generic.cancel') }</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,7 @@
|
|||||||
|
export interface FriendsRemoveConfirmationViewProps
|
||||||
|
{
|
||||||
|
selectedFriendsIds: number[];
|
||||||
|
removeFriendsText: string;
|
||||||
|
removeSelectedFriends: () => void;
|
||||||
|
onCloseClick: () => void;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { FC, useState } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { FriendsRoomInviteViewProps } from './FriendsRoomInviteView.types';
|
||||||
|
|
||||||
|
export const FriendsRoomInviteView: FC<FriendsRoomInviteViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { selectedFriendsIds = null, onCloseClick = null, sendRoomInvite = null } = props;
|
||||||
|
|
||||||
|
const [ roomInviteMessage, setRoomInviteMessage ] = useState<string>('');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-friends-room-invite" uniqueKey="nitro-friends-room-invite" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('friendlist.invite.title') } onCloseClick={ onCloseClick } />
|
||||||
|
<NitroCardContentView className="text-black d-flex flex-column gap-2">
|
||||||
|
{ LocalizeText('friendlist.invite.summary', ['count'], [selectedFriendsIds.length.toString()]) }
|
||||||
|
<textarea className="form-control" value={roomInviteMessage} onChange={e => setRoomInviteMessage(e.target.value)}></textarea>
|
||||||
|
<div className="bg-muted rounded text-center p-2">{ LocalizeText('friendlist.invite.note') }</div>
|
||||||
|
<div className="d-flex gap-2">
|
||||||
|
<button className="btn btn-success w-100" disabled={ roomInviteMessage.length === 0 || selectedFriendsIds.length === 0 } onClick={ () => sendRoomInvite(roomInviteMessage) }>{ LocalizeText('friendlist.invite.send') }</button>
|
||||||
|
<button className="btn btn-primary w-100" onClick={ onCloseClick }>{ LocalizeText('generic.cancel') }</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,6 @@
|
|||||||
|
export interface FriendsRoomInviteViewProps
|
||||||
|
{
|
||||||
|
selectedFriendsIds: number[];
|
||||||
|
onCloseClick: () => void;
|
||||||
|
sendRoomInvite: (message: string) => void;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { FollowFriendMessageComposer, ILinkEventTracker, NewConsoleMessageEvent, SendMessageComposer } from '@nitrots/nitro-renderer';
|
import { FollowFriendMessageComposer, ILinkEventTracker, NewConsoleMessageEvent, RoomInviteEvent, SendMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { FC, KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { AddEventLinkTracker, GetSessionDataManager, GetUserProfile, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
import { AddEventLinkTracker, GetSessionDataManager, GetUserProfile, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
||||||
import { MESSENGER_MESSAGE_RECEIVED, MESSENGER_NEW_THREAD, PlaySound } from '../../../../api/utils/PlaySound';
|
import { MESSENGER_MESSAGE_RECEIVED, MESSENGER_NEW_THREAD, PlaySound } from '../../../../api/utils/PlaySound';
|
||||||
@ -105,6 +105,21 @@ export const FriendsMessengerView: FC<{}> = props =>
|
|||||||
|
|
||||||
CreateMessageHook(NewConsoleMessageEvent, onNewConsoleMessageEvent);
|
CreateMessageHook(NewConsoleMessageEvent, onNewConsoleMessageEvent);
|
||||||
|
|
||||||
|
const onRoomInviteEvent = useCallback((event: RoomInviteEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
const [threadIndex, thread] = getMessageThreadWithIndex(parser.senderId);
|
||||||
|
|
||||||
|
if((threadIndex === -1) || !thread) return;
|
||||||
|
|
||||||
|
thread.addMessage(parser.senderId, parser.messageText, 0, null, MessengerThreadChat.ROOM_INVITE);
|
||||||
|
|
||||||
|
setMessageThreads(prevValue => [...prevValue]);
|
||||||
|
}, [getMessageThreadWithIndex]);
|
||||||
|
|
||||||
|
CreateMessageHook(RoomInviteEvent, onRoomInviteEvent);
|
||||||
|
|
||||||
const sendMessage = useCallback(() =>
|
const sendMessage = useCallback(() =>
|
||||||
{
|
{
|
||||||
if(!messageText || !messageText.length) return;
|
if(!messageText || !messageText.length) return;
|
||||||
|
@ -119,7 +119,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
<div className="h4 text-muted m-0">{ roomOwner }</div>
|
<div className="h4 text-muted m-0">{ roomOwner }</div>
|
||||||
</div>
|
</div>
|
||||||
{ roomTags && roomTags.length > 0 && <div className="d-flex gap-2">
|
{ roomTags && roomTags.length > 0 && <div className="d-flex gap-2">
|
||||||
{ roomTags.map(tag =>
|
{ roomTags.map((tag: string) =>
|
||||||
{
|
{
|
||||||
return <div className="rounded bg-primary text-white p-1 text-sm">#{ tag }</div>
|
return <div className="rounded bg-primary text-white p-1 text-sm">#{ tag }</div>
|
||||||
}) }
|
}) }
|
||||||
|
Loading…
Reference in New Issue
Block a user