Первая версия вложенных файлов работает

This commit is contained in:
AidarKC
2026-09-11 02:38:02 +03:00
parent ea0098d705
commit f9ae811702
29 changed files with 1463 additions and 57 deletions
+50
View File
@@ -8,6 +8,7 @@ function defaultParsed(rawText = '') {
blocks: [],
replyRef: null,
callSummary: null,
fileAttachment: null,
};
}
@@ -87,6 +88,51 @@ export function buildDmReplyTechBlock({ baseKey = '' } = {}) {
return `<S:reply;v=1;id=${cleanBaseKey}>`;
}
function decodeFileField(value = '') {
try {
return decodeURIComponent(String(value || ''));
} catch {
return String(value || '');
}
}
function normalizeFileAttachment(fields = {}) {
const id = String(fields.id || '').trim();
const url = decodeFileField(fields.url || '').trim();
const keyB64Url = String(fields.key || '').trim();
const ivB64Url = String(fields.iv || '').trim();
const name = decodeFileField(fields.name || '').trim() || 'file';
const mime = decodeFileField(fields.mime || '').trim() || 'application/octet-stream';
const size = Number(fields.size || 0);
const encryptedSize = Number(fields.encsize || 0);
if (!id || !url || !keyB64Url || !ivB64Url || !Number.isFinite(size) || size < 0) return null;
return {
version: Number(fields.v || 0),
id,
url,
keyB64Url,
ivB64Url,
name,
mime,
size,
encryptedSize: Number.isFinite(encryptedSize) && encryptedSize > 0 ? encryptedSize : 0,
};
}
export function buildDmFileTechBlock(attachment = {}) {
const id = String(attachment?.id || '').trim();
const url = String(attachment?.url || '').trim();
const keyB64Url = String(attachment?.keyB64Url || '').trim();
const ivB64Url = String(attachment?.ivB64Url || '').trim();
const size = Math.max(0, Math.floor(Number(attachment?.size || 0)));
const encryptedSize = Math.max(0, Math.floor(Number(attachment?.encryptedSize || 0)));
if (!id || !url || !keyB64Url || !ivB64Url) throw new Error('Не хватает данных для технического блока файла');
const name = encodeURIComponent(String(attachment?.name || 'file'));
const mime = encodeURIComponent(String(attachment?.mime || 'application/octet-stream'));
const encodedUrl = encodeURIComponent(url);
return `<S:file;v=1;id=${id};url=${encodedUrl};key=${keyB64Url};iv=${ivB64Url};name=${name};mime=${mime};size=${size};encsize=${encryptedSize}>`;
}
export function parseDmTechBlocks(rawText = '') {
const text = String(rawText || '');
if (!hasTechPrefix(text)) return defaultParsed(text);
@@ -95,6 +141,7 @@ export function parseDmTechBlocks(rawText = '') {
let cursor = 0;
let replyRef = null;
let callSummary = null;
let fileAttachment = null;
while (hasTechPrefix(text, cursor)) {
const end = text.indexOf('>', cursor);
@@ -142,6 +189,8 @@ export function parseDmTechBlocks(rawText = '') {
reason: String(fields.reason || '').trim().toLowerCase(),
};
}
} else if (kind === 'file' && !fileAttachment) {
fileAttachment = normalizeFileAttachment(fields);
}
cursor = end + 1;
@@ -157,5 +206,6 @@ export function parseDmTechBlocks(rawText = '') {
blocks,
replyRef,
callSummary,
fileAttachment,
};
}