Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions src/components/chat/messages/MessageFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,35 @@ interface MessageFileProps {
const MessageFile: React.FC<MessageFileProps> = ({ attachments }) => {
const { t } = useLanguage('chat');

const downloadFile = (attachment: Attachment) => {
const result = openAttachmentInNewTab({
url: attachment.data_url,
filename: attachment.fallback_title || t('messages.messageFile.fileFallback'),
});
const downloadFile = async (attachment: Attachment) => {
const url = attachment.data_url?.trim();
if (!url) return;

if (result === 'download-fallback') {
toast.info(t('messages.messageImage.downloadStarted'), {
description: attachment.fallback_title || t('messages.messageFile.fileFallbackTitle'),
const filename = attachment.fallback_title || t('messages.messageFile.fileFallback');

try {
const response = await fetch(url, { mode: 'cors' });
if (!response.ok) {
console.warn('[MessageFile] non-ok response:', response.status, url);
toast.warning(t('messages.messageFile.downloadFallbackOpenedInNewTab'), {
description: t('messages.messageFile.downloadFallbackReason.serverError', { status: response.status }),
});
openAttachmentInNewTab({ url, filename });
return;
}
const blob = await response.blob();
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobUrl;
link.download = filename;
link.click();
setTimeout(() => URL.revokeObjectURL(blobUrl), 0);
} catch (err) {
console.warn('[MessageFile] download fallback after fetch error:', err);
toast.warning(t('messages.messageFile.downloadFallbackOpenedInNewTab'), {
description: t('messages.messageFile.downloadFallbackReason.network'),
});
openAttachmentInNewTab({ url, filename });
}
};

Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/en/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@
"messageFile": {
"fileFallback": "file",
"unknownSize": "Unknown size",
"fileFallbackTitle": "File"
"fileFallbackTitle": "File",
"downloadFallbackOpenedInNewTab": "File opened in new tab",
"downloadFallbackReason": {
"serverError": "Server returned {{status}} — could not download directly.",
"network": "Network error or CORS block — could not download directly."
}
},
"messageImage": {
"downloadStarted": "Download started",
Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/es/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@
"messageFile": {
"fileFallback": "archivo",
"unknownSize": "Tamaño desconocido",
"fileFallbackTitle": "Archivo"
"fileFallbackTitle": "Archivo",
"downloadFallbackOpenedInNewTab": "Archivo abierto en nueva pestaña",
"downloadFallbackReason": {
"serverError": "El servidor devolvió {{status}} — no se pudo descargar directamente.",
"network": "Error de red o bloqueo de CORS — no se pudo descargar directamente."
}
},
"messageImage": {
"downloadStarted": "Descarga iniciada",
Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/fr/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@
"messageFile": {
"fileFallback": "fichier",
"unknownSize": "Taille inconnue",
"fileFallbackTitle": "Fichier"
"fileFallbackTitle": "Fichier",
"downloadFallbackOpenedInNewTab": "Fichier ouvert dans un nouvel onglet",
"downloadFallbackReason": {
"serverError": "Le serveur a renvoyé {{status}} — impossible de télécharger directement.",
"network": "Erreur réseau ou blocage CORS — impossible de télécharger directement."
}
},
"messageImage": {
"downloadStarted": "Téléchargement démarré",
Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/it/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@
"messageFile": {
"fileFallback": "file",
"unknownSize": "Dimensione sconosciuta",
"fileFallbackTitle": "File"
"fileFallbackTitle": "File",
"downloadFallbackOpenedInNewTab": "File aperto in una nuova scheda",
"downloadFallbackReason": {
"serverError": "Il server ha restituito {{status}} — impossibile scaricare direttamente.",
"network": "Errore di rete o blocco CORS — impossibile scaricare direttamente."
}
},
"messageImage": {
"downloadStarted": "Download avviato",
Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/pt-BR/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@
"messageFile": {
"fileFallback": "arquivo",
"unknownSize": "Tamanho desconhecido",
"fileFallbackTitle": "Arquivo"
"fileFallbackTitle": "Arquivo",
"downloadFallbackOpenedInNewTab": "Arquivo aberto em nova aba",
"downloadFallbackReason": {
"serverError": "Servidor retornou {{status}} — não foi possível baixar diretamente.",
"network": "Falha de rede ou bloqueio de CORS — não foi possível baixar diretamente."
}
},
"messageImage": {
"downloadStarted": "Download iniciado",
Expand Down
7 changes: 6 additions & 1 deletion src/i18n/locales/pt/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@
"messageFile": {
"fileFallback": "arquivo",
"unknownSize": "Tamanho desconhecido",
"fileFallbackTitle": "Arquivo"
"fileFallbackTitle": "Arquivo",
"downloadFallbackOpenedInNewTab": "Ficheiro aberto em nova aba",
"downloadFallbackReason": {
"serverError": "O servidor retornou {{status}} — não foi possível descarregar diretamente.",
"network": "Falha de rede ou bloqueio de CORS — não foi possível descarregar diretamente."
}
},
"messageImage": {
"downloadStarted": "Download iniciado",
Expand Down