mirror of
https://github.com/duckietm/Nitro-Cool-UI.git
synced 2025-06-21 22:36:58 +00:00
172 lines
7.8 KiB
TypeScript
172 lines
7.8 KiB
TypeScript
import { AddLinkEventTracker, FollowFriendMessageComposer, GetSessionDataManager, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer';
|
|
import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react';
|
|
import { FaTimes } from 'react-icons/fa';
|
|
import { GetUserProfile, LocalizeText, ReportType, SendMessageComposer } from '../../../../api';
|
|
import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
|
import { useHelp, useMessenger } from '../../../../hooks';
|
|
import { FriendsMessengerThreadView } from './messenger-thread/FriendsMessengerThreadView';
|
|
|
|
export const FriendsMessengerView: FC<{}> = props =>
|
|
{
|
|
const [ isVisible, setIsVisible ] = useState(false);
|
|
const [ lastThreadId, setLastThreadId ] = useState(-1);
|
|
const [ messageText, setMessageText ] = useState('');
|
|
const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThreadId = null, closeThread = null } = useMessenger();
|
|
const { report = null } = useHelp();
|
|
const messagesBox = useRef<HTMLDivElement>();
|
|
|
|
const followFriend = () => (activeThread && activeThread.participant && SendMessageComposer(new FollowFriendMessageComposer(activeThread.participant.id)));
|
|
const openProfile = () => (activeThread && activeThread.participant && GetUserProfile(activeThread.participant.id));
|
|
|
|
const send = () =>
|
|
{
|
|
if(!activeThread || !messageText.length) return;
|
|
|
|
sendMessage(activeThread, GetSessionDataManager().userId, messageText);
|
|
|
|
setMessageText('');
|
|
}
|
|
|
|
const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
|
{
|
|
if(event.key !== 'Enter') return;
|
|
|
|
send();
|
|
}
|
|
|
|
useEffect(() =>
|
|
{
|
|
const linkTracker: ILinkEventTracker = {
|
|
linkReceived: (url: string) =>
|
|
{
|
|
const parts = url.split('/');
|
|
|
|
if(parts.length === 2)
|
|
{
|
|
if(parts[1] === 'open')
|
|
{
|
|
setIsVisible(true);
|
|
|
|
return;
|
|
}
|
|
|
|
if(parts[1] === 'toggle')
|
|
{
|
|
setIsVisible(prevValue => !prevValue);
|
|
|
|
return;
|
|
}
|
|
|
|
const thread = getMessageThread(parseInt(parts[1]));
|
|
|
|
if(!thread) return;
|
|
|
|
setActiveThreadId(thread.threadId);
|
|
setIsVisible(true);
|
|
}
|
|
},
|
|
eventUrlPrefix: 'friends-messenger/'
|
|
};
|
|
|
|
AddLinkEventTracker(linkTracker);
|
|
|
|
return () => RemoveLinkEventTracker(linkTracker);
|
|
}, [ getMessageThread, setActiveThreadId ]);
|
|
|
|
useEffect(() =>
|
|
{
|
|
if(!isVisible || !activeThread) return;
|
|
|
|
messagesBox.current.scrollTop = messagesBox.current.scrollHeight;
|
|
}, [ isVisible, activeThread ]);
|
|
|
|
useEffect(() =>
|
|
{
|
|
if(isVisible && !activeThread)
|
|
{
|
|
if(lastThreadId > 0)
|
|
{
|
|
setActiveThreadId(lastThreadId);
|
|
}
|
|
else
|
|
{
|
|
if(visibleThreads.length > 0) setActiveThreadId(visibleThreads[0].threadId);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if(!isVisible && activeThread)
|
|
{
|
|
setLastThreadId(activeThread.threadId);
|
|
setActiveThreadId(-1);
|
|
}
|
|
}, [ isVisible, activeThread, lastThreadId, visibleThreads, setActiveThreadId ]);
|
|
|
|
if(!isVisible) return null;
|
|
|
|
return (
|
|
<NitroCardView className="nitro-friends-messenger" uniqueKey="nitro-friends-messenger" theme="primary-slim">
|
|
<NitroCardHeaderView headerText={ LocalizeText('messenger.window.title', [ 'OPEN_CHAT_COUNT' ], [ visibleThreads.length.toString() ]) } onCloseClick={ event => setIsVisible(false) } />
|
|
<NitroCardContentView>
|
|
<Grid overflow="hidden">
|
|
<Column size={ 4 } overflow="hidden">
|
|
<Text bold>{ LocalizeText('toolbar.icon.label.messenger') }</Text>
|
|
<Column fit overflow="auto">
|
|
<Column>
|
|
{ visibleThreads && (visibleThreads.length > 0) && visibleThreads.map(thread => {
|
|
return (
|
|
<LayoutGridItem key={ thread.threadId } itemActive={ (activeThread === thread) } onClick={ event => setActiveThreadId(thread.threadId) }>
|
|
{ thread.unread && <LayoutItemCountView count={ thread.unreadCount } /> }
|
|
<Flex fullWidth alignItems="center" gap={ 1 }>
|
|
<Flex alignItems="center" className="friend-head px-2">
|
|
<LayoutAvatarImageView figure={
|
|
thread.participant.id > 0 ? thread.participant.figure : thread.participant.id <= 0 && thread.participant.figure === 'ADM' ? 'ha-3409-1413-70.lg-285-89.ch-3032-1334-109.sh-3016-110.hd-185-1359.ca-3225-110-62.wa-3264-62-62.fa-1206-90.hr-3322-1403' : thread.participant.figure
|
|
} headOnly={true} direction={thread.participant.id > 0 ? 2 : 3} />
|
|
</Flex>
|
|
<Text truncate grow>{ thread.participant.name }</Text>
|
|
</Flex>
|
|
</LayoutGridItem>
|
|
);
|
|
}) }
|
|
</Column>
|
|
</Column>
|
|
</Column>
|
|
<Column size={ 8 } overflow="hidden">
|
|
{ activeThread &&
|
|
<>
|
|
<Text bold center>{ LocalizeText('messenger.window.separator', [ 'FRIEND_NAME' ], [ activeThread.participant.name ]) }</Text>
|
|
<Flex alignItems="center" justifyContent="between" gap={ 1 }>
|
|
{activeThread && activeThread.participant.id > 0 && (
|
|
<Flex gap={1}>
|
|
<ButtonGroup>
|
|
<Button onClick={followFriend}><Base className="nitro-friends-spritesheet icon-follow" /></Button>
|
|
<Button onClick={openProfile}><Base className="nitro-friends-spritesheet icon-profile-sm" /></Button>
|
|
</ButtonGroup>
|
|
<Button variant="danger" onClick={() => report(ReportType.IM, { reportedUserId: activeThread.participant.id })}>
|
|
{LocalizeText('messenger.window.button.report')}
|
|
</Button>
|
|
</Flex>
|
|
)}
|
|
<Button onClick={ event => closeThread(activeThread.threadId) }>
|
|
<FaTimes className="fa-icon" />
|
|
</Button>
|
|
</Flex>
|
|
<Column fit className="bg-muted p-2 rounded chat-messages">
|
|
<Column innerRef={ messagesBox } overflow="auto">
|
|
<FriendsMessengerThreadView thread={ activeThread } />
|
|
</Column>
|
|
</Column>
|
|
<Flex gap={ 1 }>
|
|
<input type="text" className="form-control form-control-sm" maxLength={ 255 } placeholder={ LocalizeText('messenger.window.input.default', [ 'FRIEND_NAME' ], [ activeThread.participant.name ]) } value={ messageText } onChange={ event => setMessageText(event.target.value) } onKeyDown={ onKeyDown } />
|
|
<Button variant="success" onClick={ send }>
|
|
{ LocalizeText('widgets.chatinput.say') }
|
|
</Button>
|
|
</Flex>
|
|
</> }
|
|
</Column>
|
|
</Grid>
|
|
</NitroCardContentView>
|
|
</NitroCardView>
|
|
);
|
|
} |