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
10 changes: 10 additions & 0 deletions apps/meteor/app/autotranslate/client/lib/autotranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ export const AutoTranslate = {
}
}

if (attachment.description && attachment.translations && attachment.translations[language]) {
attachment.translations.original = attachment.description;

if (autoTranslateShowInverse) {
attachment.description = attachment.translations.original;
} else {
attachment.description = attachment.translations[language];
}
}

if (attachment.attachments && attachment.attachments.length > 0) {
// @ts-expect-error - not sure what to do with this
attachment.attachments = this.translateAttachments(attachment.attachments, language);
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/autotranslate/server/autotranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export abstract class AutoTranslate {
if (message.attachments && message.attachments.length > 0) {
setImmediate(async () => {
for (const [index, attachment] of message.attachments?.entries() ?? []) {
if (attachment.text) {
if (attachment.description || attachment.text) {
// Removes the initial link `[ ](quoterl)` from quote message before translation
const translatedText = attachment?.text?.replace(/\[(.*?)\]\(.*?\)/g, '$1') || attachment?.text;
const attachmentMessage = { ...attachment, text: translatedText };
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/autotranslate/server/deeplTranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class DeeplAutoTranslate extends AutoTranslate {
params: {
auth_key: this.apiKey,
target_lang: language,
text: attachment.text || '',
text: attachment.description || attachment.text || '',
},
});
if (!result.ok) {
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/autotranslate/server/googleTranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class GoogleAutoTranslate extends AutoTranslate {
key: this.apiKey,
target: language,
format: 'text',
q: attachment.text || '',
q: attachment.description || attachment.text || '',
},
});
if (!result.ok) {
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/autotranslate/server/msTranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class MsAutoTranslate extends AutoTranslate {
return this._translate(
[
{
Text: attachment.text || '',
Text: attachment.description || attachment.text || '',
},
],
targetLanguages,
Expand Down
9 changes: 7 additions & 2 deletions apps/meteor/app/lib/server/functions/notifications/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,13 @@ export async function getEmailContent({ message, user, room }) {
}

if (hasFiles) {
const fileParts = files.map((file) => {
return escapeHTML(file.name);
const attachments = message.attachments || [];
const fileParts = files.map((file, index) => {
let part = escapeHTML(file.name);
if (attachments[index]?.description) {
part += `<br/><br/>${escapeHTML(attachments[index].description)}`;
}
return part;
});
Comment thread
MartinSchoeler marked this conversation as resolved.
contentParts.push(fileParts.join('<br/><br/>'));
}
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ export const sendNotification = async ({
const firstAttachment = message.attachments?.length && message.attachments.shift();

if (firstAttachment) {
firstAttachment.description =
typeof firstAttachment.description === 'string' ? emojione.shortnameToUnicode(firstAttachment.description) : undefined;
firstAttachment.text = typeof firstAttachment.text === 'string' ? emojione.shortnameToUnicode(firstAttachment.text) : undefined;
}

Expand Down
9 changes: 8 additions & 1 deletion apps/meteor/app/lib/server/methods/updateMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function executeUpdateMessage(
// IF the message has custom fields, always update
// Ideally, we'll compare the custom fields to check for change, but since we don't know the shape of
// custom fields, as it's user defined, we're gonna update
const msgText = originalMessage.msg;
const msgText = originalMessage?.attachments?.[0]?.description ?? originalMessage.msg;
if (msgText === message.msg && !previewUrls && !message.customFields) {
return;
}
Expand Down Expand Up @@ -86,6 +86,13 @@ export async function executeUpdateMessage(
}
await canSendMessageAsync(message.rid, { uid: user._id, username: user.username ?? undefined, ...user });

// It is possible to have an empty array as the attachments property, so ensure both things exist
if (originalMessage.attachments && originalMessage.attachments.length > 0 && originalMessage.attachments[0].description !== undefined) {
originalMessage.attachments[0].description = message.msg;
message.attachments = originalMessage.attachments;
message.msg = originalMessage.msg;
}

message.u = originalMessage.u;

return updateMessage(message, user, originalMessage, previewUrls);
Expand Down
5 changes: 4 additions & 1 deletion apps/meteor/app/livechat/server/lib/sendTranscript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,17 @@ export async function sendTranscript({

const messageType = MessageTypes.getType(message);

const messageContent = messageType?.system
let messageContent = messageType?.system
? DOMPurify.sanitize(`
<i>${messageType.text(i18n.cloneInstance({ interpolation: { escapeValue: false } }).t, message)}}</i>`)
: escapeHtml(message.msg);

let filesHTML = '';

if (message.attachments && message.attachments?.length > 0) {
messageContent = message.attachments[0].description || '';
escapeHtml(messageContent);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
MartinSchoeler marked this conversation as resolved.

for await (const attachment of message.attachments) {
if (!isFileAttachment(attachment)) {
continue;
Expand Down
5 changes: 4 additions & 1 deletion apps/meteor/app/slackbridge/server/RocketAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,14 @@ export default class RocketAdapter {

if (rocketMessage.file.name) {
let fileName = rocketMessage.file.name;
const text = rocketMessage.msg;
let text = rocketMessage.msg;

const attachment = this.getMessageAttachment(rocketMessage);
if (attachment) {
fileName = Meteor.absoluteUrl(attachment.title_link);
if (!text) {
text = attachment.description;
}
}

await slack.postMessage(slack.getSlackChannel(rocketMessage.rid), { ...rocketMessage, msg: `${text} ${fileName}` });
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/ui/client/lib/ChatMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class ChatMessages implements ChatAPI {
},
editMessage: async (message: IMessage, { cursorAtStart = false }: { cursorAtStart?: boolean } = {}) => {
this.composer?.uploads.clear();
const text = (await this.data.getDraft(message._id)) || message.msg;
const text = (await this.data.getDraft(message._id)) || message.attachments?.[0]?.description || message.msg;

await this.currentEditingMessage.stop();

Expand Down
Comment thread
MartinSchoeler marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import { useMediaUrl } from '@rocket.chat/ui-contexts';
import { useMemo } from 'react';

import { useReloadOnError } from './hooks/useReloadOnError';
import MarkdownText from '../../../../MarkdownText';
import MessageCollapsible from '../../../MessageCollapsible';
import MessageContentBody from '../../../MessageContentBody';

const AudioAttachment = ({
title,
audio_url: url,
audio_type: type,
audio_size: size,
description,
descriptionMd,
title_link: link,
title_link_download: hasDownload,
collapsed,
Expand All @@ -21,6 +25,7 @@ const AudioAttachment = ({

return (
<>
{descriptionMd ? <MessageContentBody md={descriptionMd} /> : <MarkdownText parseEmoji content={description} />}
<MessageCollapsible title={title} hasDownload={hasDownload} link={getURL(link || url)} size={size} isCollapsed={collapsed}>
<AudioPlayer src={src} type={type} ref={mediaRef} />
</MessageCollapsible>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { useTranslation } from 'react-i18next';

import { getFileExtension } from '../../../../../../lib/utils/getFileExtension';
import { forAttachmentDownload, registerDownloadForUid } from '../../../../../hooks/useDownloadFromServiceWorker';
import MarkdownText from '../../../../MarkdownText';
import MessageCollapsible from '../../../MessageCollapsible';
import MessageContentBody from '../../../MessageContentBody';
import AttachmentSize from '../structure/AttachmentSize';
import { useOpenEncryptedPdf } from './hooks/useOpenEncryptedPdf';

Expand All @@ -23,6 +25,8 @@ type GenericFileAttachmentProps = MessageAttachmentBase;

const GenericFileAttachment = ({
title,
description,
descriptionMd,
title_link: link,
title_link_download: hasDownload,
size,
Expand Down Expand Up @@ -81,6 +85,7 @@ const GenericFileAttachment = ({

return (
<>
{descriptionMd ? <MessageContentBody md={descriptionMd} /> : <MarkdownText parseEmoji content={description} />}
<MessageCollapsible title={title} hasDownload={hasDownload} link={link} isCollapsed={collapsed}>
<MessageGenericPreview style={{ maxWidth: 368, width: '100%' }}>
<MessageGenericPreviewContent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import type { ImageAttachmentProps } from '@rocket.chat/core-typings';
import { useMediaUrl } from '@rocket.chat/ui-contexts';

import { useLoadImage } from './hooks/useLoadImage';
import MarkdownText from '../../../../MarkdownText';
import MessageCollapsible from '../../../MessageCollapsible';
import MessageContentBody from '../../../MessageContentBody';
import AttachmentImage from '../structure/AttachmentImage';

const ImageAttachment = ({
Expand All @@ -16,6 +18,7 @@ const ImageAttachment = ({
height: 368,
},
description,
descriptionMd,
title_link: link,
title_link_download: hasDownload,
collapsed,
Expand All @@ -25,6 +28,7 @@ const ImageAttachment = ({

return (
<>
{descriptionMd ? <MessageContentBody md={descriptionMd} /> : <MarkdownText parseEmoji content={description} />}
<MessageCollapsible title={title} hasDownload={hasDownload} link={getURL(link || url)} size={size} isCollapsed={collapsed}>
<AttachmentImage
{...imageDimensions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { useMemo } from 'react';

import { useReloadOnError } from './hooks/useReloadOnError';
import { userAgentMIMETypeFallback } from '../../../../../lib/utils/userAgentMIMETypeFallback';
import MarkdownText from '../../../../MarkdownText';
import MessageCollapsible from '../../../MessageCollapsible';
import MessageContentBody from '../../../MessageContentBody';

const VideoAttachment = ({
title,
video_url: url,
video_type: type,
video_size: size,
description,
descriptionMd,
title_link: link,
title_link_download: hasDownload,
collapsed,
Expand All @@ -22,6 +26,7 @@ const VideoAttachment = ({

return (
<>
{descriptionMd ? <MessageContentBody md={descriptionMd} /> : <MarkdownText parseEmoji content={description} />}
<MessageCollapsible title={title} hasDownload={hasDownload} link={getURL(link || url)} size={size} isCollapsed={collapsed}>
<MessageGenericPreview style={{ maxWidth: 368, width: '100%' }}>
<Box is='video' controls preload='metadata' ref={mediaRef}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import type { MessageActionConfig } from '../../../../app/ui-utils/client/lib/Me

const getMainMessageText = (message: IMessage): IMessage => {
const newMessage = { ...message };
newMessage.msg = newMessage.msg || newMessage.attachments?.[0]?.title || '';
newMessage.md = newMessage.md || undefined;
newMessage.msg = newMessage.msg || newMessage.attachments?.[0]?.description || newMessage.attachments?.[0]?.title || '';
newMessage.md = newMessage.md || newMessage.attachments?.[0]?.descriptionMd || undefined;
return { ...newMessage };
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import ReportMessageModal from '../../../views/room/modals/ReportMessageModal';

const getMainMessageText = (message: IMessage): IMessage => {
const newMessage = { ...message };
newMessage.msg = newMessage.msg || newMessage.attachments?.[0]?.title || '';
newMessage.md = newMessage.md || undefined;
newMessage.msg = newMessage.msg || newMessage.attachments?.[0]?.description || newMessage.attachments?.[0]?.title || '';
newMessage.md = newMessage.md || newMessage.attachments?.[0]?.descriptionMd || undefined;
return { ...newMessage };
};

Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/client/hooks/useDecryptedMessage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('useDecryptedMessage', () => {
it('should handle E2EE messages with attachments', async () => {
(isE2EEMessage as jest.MockedFunction<typeof isE2EEMessage>).mockReturnValue(true);
(e2e.decryptMessage as jest.Mock).mockResolvedValue({
attachments: [{ title: 'Attachment title' }],
attachments: [{ description: 'Attachment description' }],
});
const message = { msg: 'Encrypted message with attachment' };

Expand All @@ -63,6 +63,7 @@ describe('useDecryptedMessage', () => {
expect(result.current).toBe('E2E_message_encrypted_placeholder');
});

expect(result.current).toBe('Attachment description');
expect(e2e.decryptMessage).toHaveBeenCalledWith(message);
});

Expand Down
9 changes: 6 additions & 3 deletions apps/meteor/client/hooks/useDecryptedMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ export const useDecryptedMessage = (message: IMessage): string => {
e2e.decryptMessage(message).then((decryptedMsg) => {
if (decryptedMsg.msg) {
setDecryptedMessage(decryptedMsg.msg);
return;
}

if (decryptedMsg.attachments && decryptedMsg.attachments.length > 0) {
setDecryptedMessage(t('Message_with_attachment'));
if (decryptedMsg.attachments && decryptedMsg.attachments?.length > 0) {
if (decryptedMsg.attachments[0].description) {
setDecryptedMessage(decryptedMsg.attachments[0].description);
} else {
setDecryptedMessage(t('Message_with_attachment'));
}
}
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}, [message, t, setDecryptedMessage]);
Expand Down
6 changes: 5 additions & 1 deletion apps/meteor/client/lib/normalizeThreadMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export function normalizeThreadMessage({ ...message }: Readonly<Pick<IMessage, '
}

if (message.attachments) {
const attachment = message.attachments.find((attachment) => attachment.title);
const attachment = message.attachments.find((attachment) => attachment.title || attachment.description);

if (attachment?.description) {
return <>{attachment.description}</>;
}

if (attachment?.title) {
return <>{attachment.title}</>;
Expand Down
Loading
Loading