mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
feat(messenger): incoming typing state + outgoing typing action
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ConsoleReadReceiptEvent, GetSessionDataManager, MarkConsoleReadComposer, NewConsoleMessageEvent, RoomInviteErrorEvent, RoomInviteEvent, SendMessageComposer as SendMessageComposerPacket } from '@nitrots/nitro-renderer';
|
||||
import { ConsoleReadReceiptEvent, ConsoleTypingComposer, FriendIsTypingEvent, GetSessionDataManager, MarkConsoleReadComposer, NewConsoleMessageEvent, RoomInviteErrorEvent, RoomInviteEvent, SendMessageComposer as SendMessageComposerPacket } from '@nitrots/nitro-renderer';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useBetween } from 'use-between';
|
||||
import { CloneObject, LocalizeText, MessengerIconState, MessengerThread, MessengerThreadChat, NotificationAlertType, PlaySound, SendMessageComposer, SoundNames } from '../../api';
|
||||
@@ -17,6 +17,9 @@ const useMessengerState = () =>
|
||||
const { simpleAlert = null } = useNotification();
|
||||
const { settings, translateIncoming } = useTranslation();
|
||||
|
||||
const [typingUserIds, setTypingUserIds] = useState<number[]>([]);
|
||||
const typingTimersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());
|
||||
|
||||
const messageThreadsRef = useRef(messageThreads);
|
||||
messageThreadsRef.current = messageThreads;
|
||||
|
||||
@@ -151,6 +154,13 @@ const useMessengerState = () =>
|
||||
});
|
||||
};
|
||||
|
||||
const sendTypingStatus = (peerId: number, isTyping: boolean) =>
|
||||
{
|
||||
if (!peerId || (peerId <= 0)) return;
|
||||
|
||||
SendMessageComposer(new ConsoleTypingComposer(peerId, isTyping));
|
||||
};
|
||||
|
||||
useMessageEvent<NewConsoleMessageEvent>(NewConsoleMessageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@@ -179,6 +189,38 @@ const useMessengerState = () =>
|
||||
simpleAlert(`Received room invite error: ${ parser.errorCode },recipients: ${ parser.failedRecipients.join(',') }`, NotificationAlertType.DEFAULT, null, null, LocalizeText('friendlist.alert.title'));
|
||||
});
|
||||
|
||||
useMessageEvent<FriendIsTypingEvent>(FriendIsTypingEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
const senderId = parser.senderId;
|
||||
|
||||
if (senderId <= 0) return;
|
||||
|
||||
const timers = typingTimersRef.current;
|
||||
const existing = timers.get(senderId);
|
||||
|
||||
if (existing)
|
||||
{
|
||||
clearTimeout(existing);
|
||||
timers.delete(senderId);
|
||||
}
|
||||
|
||||
if (parser.isTyping)
|
||||
{
|
||||
setTypingUserIds(prev => (prev.indexOf(senderId) >= 0) ? prev : [...prev, senderId]);
|
||||
|
||||
timers.set(senderId, setTimeout(() =>
|
||||
{
|
||||
typingTimersRef.current.delete(senderId);
|
||||
setTypingUserIds(prev => prev.filter(id => (id !== senderId)));
|
||||
}, 6000));
|
||||
}
|
||||
else
|
||||
{
|
||||
setTypingUserIds(prev => prev.filter(id => (id !== senderId)));
|
||||
}
|
||||
});
|
||||
|
||||
useMessageEvent<ConsoleReadReceiptEvent>(ConsoleReadReceiptEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@@ -247,7 +289,7 @@ const useMessengerState = () =>
|
||||
});
|
||||
}, [visibleThreads]);
|
||||
|
||||
return { messageThreads, activeThread, iconState, visibleThreads, getMessageThread, setActiveThreadId, closeThread, sendMessage };
|
||||
return { messageThreads, activeThread, iconState, visibleThreads, getMessageThread, setActiveThreadId, closeThread, sendMessage, typingUserIds, sendTypingStatus };
|
||||
};
|
||||
|
||||
export const useMessenger = () => useBetween(useMessengerState);
|
||||
|
||||
Reference in New Issue
Block a user