feat: add real media albums across backend, web, and android
Some checks failed
Android CI / android (push) Failing after 6m2s
Android Release / release (push) Has started running
CI / test (push) Has been cancelled

- add backend media-group endpoint with atomic message and attachment creation

- switch web composer to send multi-media albums through the new endpoint

- switch Android batch media sending to upload first and create one album message with caption
This commit is contained in:
2026-04-05 20:28:16 +03:00
parent 6bb3dfc712
commit 7d7996fb20
14 changed files with 507 additions and 47 deletions

View File

@@ -106,6 +106,42 @@ export async function sendMessageWithClientId(
return data;
}
export interface MediaGroupAttachmentInput {
file_url: string;
file_type: string;
file_size: number;
waveform_points?: number[] | null;
}
export interface MediaGroupSendResponse {
message: Message;
attachments: Array<{
id: number;
message_id: number;
file_url: string;
file_type: string;
file_size: number;
waveform_points?: number[] | null;
}>;
}
export async function sendMediaGroupWithClientId(
chatId: number,
attachments: MediaGroupAttachmentInput[],
text: string | null,
clientMessageId: string,
replyToMessageId?: number
): Promise<MediaGroupSendResponse> {
const { data } = await http.post<MediaGroupSendResponse>("/messages/media-group", {
chat_id: chatId,
attachments,
text,
client_message_id: clientMessageId,
reply_to_message_id: replyToMessageId
});
return data;
}
export interface UploadUrlResponse {
upload_url: string;
file_url: string;

View File

@@ -1,5 +1,5 @@
import { useEffect, useRef, useState, type KeyboardEvent, type PointerEvent } from "react";
import { attachFile, editMessage, requestUploadUrl, sendMessageWithClientId, uploadToPresignedUrl } from "../api/chats";
import { attachFile, editMessage, requestUploadUrl, sendMediaGroupWithClientId, sendMessageWithClientId, uploadToPresignedUrl } from "../api/chats";
import { useAuthStore } from "../store/authStore";
import { useChatStore } from "../store/chatStore";
import { buildWsUrl } from "../utils/ws";
@@ -937,17 +937,18 @@ export function MessageComposer() {
clientMessageId,
});
const replyToMessageId = replyToByChat[activeChatId]?.id ?? undefined;
const created = await sendMessageWithClientId(
const created = await sendMediaGroupWithClientId(
activeChatId,
uploaded.map((item) => ({
file_url: item.fileUrl,
file_type: item.fileType,
file_size: item.fileSize,
})),
caption,
messageType,
clientMessageId,
replyToMessageId
);
confirmMessageByClientId(activeChatId, clientMessageId, created);
for (const item of uploaded) {
await attachFile(created.id, item.fileUrl, item.fileType, item.fileSize);
}
confirmMessageByClientId(activeChatId, clientMessageId, created.message);
setReplyToMessage(activeChatId, null);
} catch {
setUploadError("Upload failed. Please try again.");