This commit is contained in:
lendry
2026-07-10 10:37:22 +03:00
parent caf12e64f7
commit a4b4577c55
13 changed files with 669 additions and 48 deletions

View File

@@ -104,15 +104,57 @@ export function formatFileSize(bytes?: number) {
return `${(bytes / (1024 * 1024)).toFixed(1)} МБ`;
}
export interface ChatLocationMetadata {
latitude?: number;
longitude?: number;
address?: string;
label?: string;
}
export function parseMessageMetadata(metadataJson?: string) {
if (!metadataJson) return {} as { fileName?: string; fileSize?: number; durationMs?: number; videoNote?: boolean };
if (!metadataJson) {
return {} as { fileName?: string; fileSize?: number; durationMs?: number; videoNote?: boolean } & ChatLocationMetadata;
}
try {
return JSON.parse(metadataJson) as { fileName?: string; fileSize?: number; durationMs?: number; videoNote?: boolean };
return JSON.parse(metadataJson) as {
fileName?: string;
fileSize?: number;
durationMs?: number;
videoNote?: boolean;
} & ChatLocationMetadata;
} catch {
return {};
}
}
export function parseLocationMetadata(
metadataJson?: string,
e2ePayload?: { kind?: string; latitude?: number; longitude?: number; address?: string; label?: string; text?: string } | null
): ChatLocationMetadata | null {
if (e2ePayload?.kind === 'location') {
const { latitude, longitude } = e2ePayload;
if (typeof latitude === 'number' && typeof longitude === 'number') {
return {
latitude,
longitude,
address: e2ePayload.address,
label: e2ePayload.label ?? e2ePayload.text
};
}
return null;
}
const meta = parseMessageMetadata(metadataJson);
if (typeof meta.latitude === 'number' && typeof meta.longitude === 'number') {
return {
latitude: meta.latitude,
longitude: meta.longitude,
address: meta.address,
label: meta.label
};
}
return null;
}
export function fileIconLabel(fileName?: string, mimeType?: string) {
const extension = extractFileExtension(fileName);
if (extension === 'pdf' || mimeType === 'application/pdf') return 'PDF';

View File

@@ -58,6 +58,7 @@ export function getMessagePreviewText(message: ChatMessage, visibleText?: string
if (message.type === 'IMAGE') return '📷 Фото';
if (message.type === 'VIDEO') return '🎬 Видео';
if (message.type === 'VIDEO_NOTE') return '⭕ Кружок';
if (message.type === 'LOCATION') return '📍 Геопозиция';
if (message.type === 'VOICE') return '🎤 Голосовое';
if (message.type === 'AUDIO') return '🎵 Аудио';
if (message.type === 'FILE') return '📄 Файл';

View File

@@ -1,6 +1,6 @@
import { decryptBinary, decryptDirectMessage, encryptBinary, encryptDirectMessage } from '@/lib/e2e-crypto';
export type E2EMessageKind = 'text' | 'emoji' | 'image' | 'voice' | 'audio' | 'video' | 'video_note' | 'file';
export type E2EMessageKind = 'text' | 'emoji' | 'image' | 'voice' | 'audio' | 'video' | 'video_note' | 'file' | 'location';
export interface E2EMessagePayload {
kind: E2EMessageKind;
@@ -10,6 +10,10 @@ export interface E2EMessagePayload {
mimeType?: string;
fileSize?: number;
durationMs?: number;
latitude?: number;
longitude?: number;
address?: string;
label?: string;
}
export async function encryptE2EPayload(userId: string, peerPublicKey: string, payload: E2EMessagePayload) {
@@ -50,6 +54,8 @@ export function e2eKindFromMessageType(type: string): E2EMessageKind {
return 'video_note';
case 'FILE':
return 'file';
case 'LOCATION':
return 'location';
default:
return 'text';
}
@@ -74,6 +80,8 @@ export function readableE2EPayload(payload: E2EMessagePayload | null) {
return 'Кружок';
case 'file':
return payload.fileName ?? 'Файл';
case 'location':
return payload.label?.trim() || payload.address?.trim() || payload.text?.trim() || 'Геопозиция';
default:
return '🔒 Зашифрованное сообщение';
}