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 { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useBetween } from 'use-between';
|
import { useBetween } from 'use-between';
|
||||||
import { CloneObject, LocalizeText, MessengerIconState, MessengerThread, MessengerThreadChat, NotificationAlertType, PlaySound, SendMessageComposer, SoundNames } from '../../api';
|
import { CloneObject, LocalizeText, MessengerIconState, MessengerThread, MessengerThreadChat, NotificationAlertType, PlaySound, SendMessageComposer, SoundNames } from '../../api';
|
||||||
@@ -17,6 +17,9 @@ const useMessengerState = () =>
|
|||||||
const { simpleAlert = null } = useNotification();
|
const { simpleAlert = null } = useNotification();
|
||||||
const { settings, translateIncoming } = useTranslation();
|
const { settings, translateIncoming } = useTranslation();
|
||||||
|
|
||||||
|
const [typingUserIds, setTypingUserIds] = useState<number[]>([]);
|
||||||
|
const typingTimersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());
|
||||||
|
|
||||||
const messageThreadsRef = useRef(messageThreads);
|
const messageThreadsRef = useRef(messageThreads);
|
||||||
messageThreadsRef.current = 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 =>
|
useMessageEvent<NewConsoleMessageEvent>(NewConsoleMessageEvent, event =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
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'));
|
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 =>
|
useMessageEvent<ConsoleReadReceiptEvent>(ConsoleReadReceiptEvent, event =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@@ -247,7 +289,7 @@ const useMessengerState = () =>
|
|||||||
});
|
});
|
||||||
}, [visibleThreads]);
|
}, [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);
|
export const useMessenger = () => useBetween(useMessengerState);
|
||||||
|
|||||||
Reference in New Issue
Block a user