feat(realtime): add voice/video recording activity events
Some checks are pending
CI / test (push) Has started running

This commit is contained in:
2026-03-08 19:53:48 +03:00
parent 1ef0cdf29d
commit ac82e25d16
8 changed files with 135 additions and 9 deletions

View File

@@ -16,6 +16,8 @@ export function useRealtime() {
const accessToken = useAuthStore((s) => s.accessToken);
const meId = useAuthStore((s) => s.me?.id ?? null);
const typingByChat = useRef<Record<number, Set<number>>>({});
const recordingVoiceByChat = useRef<Record<number, Set<number>>>({});
const recordingVideoByChat = useRef<Record<number, Set<number>>>({});
const wsRef = useRef<WebSocket | null>(null);
const reconnectTimeoutRef = useRef<number | null>(null);
const heartbeatIntervalRef = useRef<number | null>(null);
@@ -171,6 +173,48 @@ export function useRealtime() {
typingByChat.current[chatId]?.delete(userId);
chatStore.setTypingUsers(chatId, [...(typingByChat.current[chatId] ?? [])]);
}
if (event.event === "recording_voice_start") {
const chatId = Number(event.payload.chat_id);
const userId = Number(event.payload.user_id);
if (!Number.isFinite(chatId) || !Number.isFinite(userId) || userId === authStore.me?.id) {
return;
}
if (!recordingVoiceByChat.current[chatId]) {
recordingVoiceByChat.current[chatId] = new Set<number>();
}
recordingVoiceByChat.current[chatId].add(userId);
chatStore.setRecordingUsers(chatId, "voice", [...recordingVoiceByChat.current[chatId]]);
}
if (event.event === "recording_voice_stop") {
const chatId = Number(event.payload.chat_id);
const userId = Number(event.payload.user_id);
if (!Number.isFinite(chatId) || !Number.isFinite(userId)) {
return;
}
recordingVoiceByChat.current[chatId]?.delete(userId);
chatStore.setRecordingUsers(chatId, "voice", [...(recordingVoiceByChat.current[chatId] ?? [])]);
}
if (event.event === "recording_video_start") {
const chatId = Number(event.payload.chat_id);
const userId = Number(event.payload.user_id);
if (!Number.isFinite(chatId) || !Number.isFinite(userId) || userId === authStore.me?.id) {
return;
}
if (!recordingVideoByChat.current[chatId]) {
recordingVideoByChat.current[chatId] = new Set<number>();
}
recordingVideoByChat.current[chatId].add(userId);
chatStore.setRecordingUsers(chatId, "video", [...recordingVideoByChat.current[chatId]]);
}
if (event.event === "recording_video_stop") {
const chatId = Number(event.payload.chat_id);
const userId = Number(event.payload.user_id);
if (!Number.isFinite(chatId) || !Number.isFinite(userId)) {
return;
}
recordingVideoByChat.current[chatId]?.delete(userId);
chatStore.setRecordingUsers(chatId, "video", [...(recordingVideoByChat.current[chatId] ?? [])]);
}
if (event.event === "message_delivered") {
const chatId = Number(event.payload.chat_id);
const messageId = Number(event.payload.message_id);
@@ -280,7 +324,9 @@ export function useRealtime() {
wsRef.current?.close();
wsRef.current = null;
typingByChat.current = {};
useChatStore.setState({ typingByChat: {} });
recordingVoiceByChat.current = {};
recordingVideoByChat.current = {};
useChatStore.setState({ typingByChat: {}, recordingVoiceByChat: {}, recordingVideoByChat: {} });
window.removeEventListener("focus", onFocusOrVisible);
document.removeEventListener("visibilitychange", onFocusOrVisible);
};