1.0.7-1.5.0 #14
@@ -466,6 +466,87 @@ export function DialogProvider(props: DialogProviderProps) {
|
|||||||
setMessages((prev) => ([...prev, newMessage]));
|
setMessages((prev) => ([...prev, newMessage]));
|
||||||
}, [privatePlain]);
|
}, [privatePlain]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обработчик сообщений для синхронизации своих же сообщений в группе
|
||||||
|
*/
|
||||||
|
usePacket(0x06, async (packet: PacketMessage) => {
|
||||||
|
const fromPublicKey = packet.getFromPublicKey();
|
||||||
|
const toPublicKey = packet.getToPublicKey();
|
||||||
|
|
||||||
|
if(fromPublicKey != publicKey){
|
||||||
|
/**
|
||||||
|
* Это не синхронизация, игнорируем ее в этом обработчике
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(toPublicKey != props.dialog){
|
||||||
|
/**
|
||||||
|
* Исправление кросс диалогового сообщения
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!hasGroup(props.dialog)){
|
||||||
|
/**
|
||||||
|
* Если это не групповое сообщение, то для него есть
|
||||||
|
* другой обработчик выше
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const content = packet.getContent();
|
||||||
|
const timestamp = packet.getTimestamp();
|
||||||
|
/**
|
||||||
|
* Генерация рандомного ID сообщения по SEED нужна для того,
|
||||||
|
* чтобы сообщение записанное здесь в стек сообщений совпадало
|
||||||
|
* с тем что записывается в БД в файле useDialogFiber.ts
|
||||||
|
*/
|
||||||
|
const messageId = packet.getMessageId();
|
||||||
|
|
||||||
|
const groupKey = await getGroupKey(toPublicKey);
|
||||||
|
if(!groupKey){
|
||||||
|
log("Group key not found for group " + toPublicKey);
|
||||||
|
error("Message dropped because group key not found for group " + toPublicKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info("New group message packet received from " + fromPublicKey);
|
||||||
|
|
||||||
|
let decryptedContent = '';
|
||||||
|
|
||||||
|
try{
|
||||||
|
decryptedContent = await decodeWithPassword(groupKey, content);
|
||||||
|
}catch(e) {
|
||||||
|
decryptedContent = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let attachments: Attachment[] = [];
|
||||||
|
for(let i = 0; i < packet.getAttachments().length; i++) {
|
||||||
|
const attachment = packet.getAttachments()[i];
|
||||||
|
attachments.push({
|
||||||
|
id: attachment.id,
|
||||||
|
preview: attachment.preview,
|
||||||
|
type: attachment.type,
|
||||||
|
blob: attachment.type == AttachmentType.MESSAGES ? await decodeWithPassword(groupKey, attachment.blob) : ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const newMessage : Message = {
|
||||||
|
from_public_key: fromPublicKey,
|
||||||
|
to_public_key: toPublicKey,
|
||||||
|
content: content,
|
||||||
|
timestamp: timestamp,
|
||||||
|
readed: 0,
|
||||||
|
chacha_key: groupKey,
|
||||||
|
from_me: 1,
|
||||||
|
plain_message: decryptedContent,
|
||||||
|
delivered: DeliveredMessageState.DELIVERED,
|
||||||
|
message_id: messageId,
|
||||||
|
attachments: attachments
|
||||||
|
};
|
||||||
|
|
||||||
|
setMessages((prev) => ([...prev, newMessage]));
|
||||||
|
}, [messages, idle, props.dialog]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обработчик для личных сообщений
|
* Обработчик для личных сообщений
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -391,15 +391,22 @@ export function useDialogFiber() {
|
|||||||
*/
|
*/
|
||||||
usePacket(0x07, async (packet: PacketRead) => {
|
usePacket(0x07, async (packet: PacketRead) => {
|
||||||
runTaskInQueue(async () => {
|
runTaskInQueue(async () => {
|
||||||
if (!hasGroup(packet.getToPublicKey())) {
|
const fromPublicKey = packet.getFromPublicKey();
|
||||||
|
const toPublicKey = packet.getToPublicKey();
|
||||||
|
if (!hasGroup(toPublicKey)) {
|
||||||
/**
|
/**
|
||||||
* Если это не относится к группам, то игнорируем здесь,
|
* Если это не относится к группам, то игнорируем здесь,
|
||||||
* для этого есть отдельный слушатель usePacket выше
|
* для этого есть отдельный слушатель usePacket выше
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const fromPublicKey = packet.getFromPublicKey();
|
if(fromPublicKey == publicKey){
|
||||||
const toPublicKey = packet.getToPublicKey();
|
/**
|
||||||
|
* Игнорируем если это наше прочтение
|
||||||
|
* которое получается при синхронизации
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
await runQuery(`UPDATE messages SET read = 1 WHERE to_public_key = ? AND from_public_key = ? AND account = ?`, [toPublicKey, publicKey, publicKey]);
|
await runQuery(`UPDATE messages SET read = 1 WHERE to_public_key = ? AND from_public_key = ? AND account = ?`, [toPublicKey, publicKey, publicKey]);
|
||||||
await updateSyncTime(Date.now());
|
await updateSyncTime(Date.now());
|
||||||
updateDialog(toPublicKey);
|
updateDialog(toPublicKey);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { useDialogsCache } from "./useDialogsCache";
|
|||||||
import { PacketRead } from "../ProtocolProvider/protocol/packets/packet.read";
|
import { PacketRead } from "../ProtocolProvider/protocol/packets/packet.read";
|
||||||
import { useLogger } from "@/app/hooks/useLogger";
|
import { useLogger } from "@/app/hooks/useLogger";
|
||||||
import { useIdle } from "@mantine/hooks";
|
import { useIdle } from "@mantine/hooks";
|
||||||
import { useViewPanelsState, ViewPanelsState } from "@/app/hooks/useViewPanelsState";
|
import { useViewPanelsState } from "@/app/hooks/useViewPanelsState";
|
||||||
import { useWindowFocus } from "@/app/hooks/useWindowFocus";
|
import { useWindowFocus } from "@/app/hooks/useWindowFocus";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,6 +145,13 @@ export function useSynchronize() {
|
|||||||
const content = packet.getContent();
|
const content = packet.getContent();
|
||||||
const timestamp = packet.getTimestamp();
|
const timestamp = packet.getTimestamp();
|
||||||
const messageId = packet.getMessageId();
|
const messageId = packet.getMessageId();
|
||||||
|
if(hasGroup(toPublicKey)){
|
||||||
|
/**
|
||||||
|
* Игнорируем если это сообщение для группы, для них есть отдельный слушатель usePacket ниже
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fromPublicKey != publicKey) {
|
if (fromPublicKey != publicKey) {
|
||||||
/**
|
/**
|
||||||
* Игнорируем если это не сообщение от нас
|
* Игнорируем если это не сообщение от нас
|
||||||
@@ -262,6 +269,43 @@ export function useSynchronize() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}, [updateDialog, publicKey]);
|
}, [updateDialog, publicKey]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обработчик синхронизации прочтения групповых сообщений
|
||||||
|
*/
|
||||||
|
usePacket(0x07, async (packet: PacketRead) => {
|
||||||
|
runTaskInQueue(async () => {
|
||||||
|
const fromPublicKey = packet.getFromPublicKey();
|
||||||
|
const toPublicKey = packet.getToPublicKey();
|
||||||
|
if (!hasGroup(toPublicKey)) {
|
||||||
|
/**
|
||||||
|
* Если это не относится к группам, то игнорируем здесь,
|
||||||
|
* для этого есть отдельный слушатель usePacket выше
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(fromPublicKey != publicKey){
|
||||||
|
/**
|
||||||
|
* Игнорируем если это наше прочтение
|
||||||
|
* которое получается при синхронизации
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await runQuery(`UPDATE messages SET read = 1 WHERE to_public_key = ? AND from_public_key != ? AND account = ?`,
|
||||||
|
[toPublicKey, publicKey, publicKey]);
|
||||||
|
await updateSyncTime(Date.now());
|
||||||
|
updateDialog(toPublicKey);
|
||||||
|
addOrUpdateDialogCache(toPublicKey, getDialogCache(toPublicKey).map((message) => {
|
||||||
|
if (!message.readed && message.from_public_key != publicKey) {
|
||||||
|
return {
|
||||||
|
...message,
|
||||||
|
readed: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}, [updateDialog]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обработчик сообщений для синхронизации своих же сообщений в группе
|
* Обработчик сообщений для синхронизации своих же сообщений в группе
|
||||||
@@ -337,9 +381,9 @@ export function useSynchronize() {
|
|||||||
to_public_key: toPublicKey,
|
to_public_key: toPublicKey,
|
||||||
content: content,
|
content: content,
|
||||||
timestamp: timestamp,
|
timestamp: timestamp,
|
||||||
readed: idle ? 0 : 1,
|
readed: 0,
|
||||||
chacha_key: groupKey,
|
chacha_key: groupKey,
|
||||||
from_me: fromPublicKey == publicKey ? 1 : 0,
|
from_me: 1,
|
||||||
plain_message: decryptedContent,
|
plain_message: decryptedContent,
|
||||||
delivered: DeliveredMessageState.DELIVERED,
|
delivered: DeliveredMessageState.DELIVERED,
|
||||||
message_id: messageId,
|
message_id: messageId,
|
||||||
@@ -353,10 +397,9 @@ export function useSynchronize() {
|
|||||||
toPublicKey,
|
toPublicKey,
|
||||||
content,
|
content,
|
||||||
timestamp,
|
timestamp,
|
||||||
/**если текущий открытый диалог == беседе (которая приходит в toPublicKey) */
|
0, //по умолчанию не прочитаны
|
||||||
(currentDialogPublicKeyView == toPublicKey && !idle && viewState != ViewPanelsState.DIALOGS_PANEL_ONLY) ? 1 : 0,
|
"",
|
||||||
'',
|
1, //Свои же сообщения всегда от нас
|
||||||
0,
|
|
||||||
await encodeWithPassword(privatePlain, decryptedContent),
|
await encodeWithPassword(privatePlain, decryptedContent),
|
||||||
publicKey,
|
publicKey,
|
||||||
messageId,
|
messageId,
|
||||||
|
|||||||
Reference in New Issue
Block a user