Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Multiple file sharing in one message #32703

Draft
wants to merge 144 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 125 commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
4ee6d2f
POC
rodrigok Apr 25, 2024
a1c0569
Initial service worker implementation
rodrigok Apr 26, 2024
640ed9e
Start changing the upload to two calls
rodrigok Apr 27, 2024
59d99a6
Start using content property in place of e2e
rodrigok Apr 28, 2024
d84ce58
Readd e2e property
rodrigok Apr 28, 2024
e6a4330
Client side attachment generation
rodrigok Apr 28, 2024
677f0ef
Cleanup
rodrigok Apr 28, 2024
7c7eb29
Encrypt content
rodrigok Apr 28, 2024
a9add79
Fix file description
rodrigok Apr 28, 2024
69f815e
Small improvements
rodrigok Apr 28, 2024
ebbe64f
Cleanup
rodrigok Apr 28, 2024
b43f57b
Cleanup
rodrigok Apr 28, 2024
ec06eb3
Improve TS
rodrigok Apr 28, 2024
f70d2e1
Change content data structure
rodrigok Apr 30, 2024
445c528
Move attachment key info to inside encryption property
rodrigok Apr 30, 2024
6daab1a
Set encrypted file name as a hash sha-256 of the name
rodrigok Apr 30, 2024
d14a0e0
Merge remote-tracking branch 'origin/develop' into feat/encrypted-files
rodrigok Apr 30, 2024
fd5fcd2
Fix lint and TS
rodrigok Apr 30, 2024
2e1f78a
Fix regression
rodrigok Apr 30, 2024
d307519
Merge branch 'develop' into feat/encrypted-files
rodrigok May 9, 2024
1e25638
Mark uploads as temporary and confirm on send message
rodrigok May 9, 2024
574169f
Fix API test
rodrigok May 9, 2024
7154756
Implement cronjob
rodrigok May 10, 2024
222cbf3
Merge branch 'develop' into feat/encrypted-files
rodrigok May 10, 2024
aff80f3
Skip UI attachment test for now
rodrigok May 10, 2024
de5f0f2
Do not generate attachment on backend for e2ee messages
rodrigok May 10, 2024
939940d
Download through serviceworker
ggazzo May 14, 2024
7fb9618
Merge remote-tracking branch 'origin/develop' into feat/encrypted-files
rodrigok May 14, 2024
26e2eb8
👀
ggazzo May 15, 2024
3234c56
Merge branch 'develop' into feat/encrypted-files
MarcosSpessatto May 25, 2024
d894d30
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 10, 2024
aacf63d
testing with e2e
abhipatel0211 Jun 12, 2024
ee3fe8a
Move encryption of msg to inside content
rodrigok Jun 12, 2024
956316e
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 12, 2024
13566ab
Merge remote-tracking branch 'upstream/feat/encrypted-files' into fea…
abhipatel0211 Jun 13, 2024
611f91e
Merge branch 'RocketChat:develop' into feat/encrypted-file
abhipatel0211 Jun 13, 2024
48a97f7
Fix placeholder message for threads
rodrigok Jun 13, 2024
446b1a7
Unskip test
rodrigok Jun 13, 2024
35363b6
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 13, 2024
c258b21
Fix ts
rodrigok Jun 13, 2024
989c61c
Fix tests
rodrigok Jun 13, 2024
0a3cb4d
Merge remote-tracking branch 'upstream/feat/encrypted-files' into fea…
abhipatel0211 Jun 14, 2024
403ced3
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 14, 2024
ae670ff
Merge branch 'RocketChat:develop' into feat/encrypted-file
abhipatel0211 Jun 14, 2024
de94f83
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 14, 2024
9da9640
Add test for old e2ee msg format
rodrigok Jun 14, 2024
8c7310f
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 18, 2024
5228bdb
Add tests for new upload API
rodrigok Jun 18, 2024
9e83634
Save encrypted content info to the file upload
rodrigok Jun 19, 2024
8f81edd
Add dimensions to image attachments
rodrigok Jun 19, 2024
b9ff006
Fix TS
rodrigok Jun 19, 2024
9a39914
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 19, 2024
20962c4
Fix tests
rodrigok Jun 19, 2024
74cfee1
Fix image preview
rodrigok Jun 19, 2024
6508ebe
Prevent keys to be set on top of existent keys
rodrigok Jun 19, 2024
1a1788e
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 19, 2024
64a27cb
Fix API tests
rodrigok Jun 19, 2024
b5e1ba5
Fix e2ee change password
rodrigok Jun 19, 2024
f108fd4
Fix TS
rodrigok Jun 19, 2024
ae76481
Fix API tests
rodrigok Jun 19, 2024
18d0e87
Decrypt room's last message correctly
rodrigok Jun 19, 2024
e984ad2
Merge remote-tracking branch 'origin/develop' into feat/encrypted-files
rodrigok Jun 19, 2024
c251e17
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 19, 2024
a96fa61
Try to fix tests
rodrigok Jun 19, 2024
3f480b0
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 19, 2024
fa2456a
Fix tests
rodrigok Jun 20, 2024
365cef8
Fix preview of encrypted files
rodrigok Jun 20, 2024
bd90357
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 20, 2024
81dad69
Fix download button
rodrigok Jun 20, 2024
8402305
Fix download from files list
rodrigok Jun 20, 2024
503218e
Merge branch 'develop' into feat/encrypted-files
rodrigok Jun 20, 2024
09e3bb7
Force cors on SW
rodrigok Jun 20, 2024
f6162af
Merge remote-tracking branch 'upstream/feat/encrypted-files' into fea…
abhipatel0211 Jun 21, 2024
b739659
feat: multiple file sharing feature with encryption
abhipatel0211 Jun 29, 2024
a1f7848
Merge remote-tracking branch 'upstream/develop' into e2e_multiple_mer…
abhipatel0211 Jun 29, 2024
74ed1f2
fix: file name issue
abhipatel0211 Jun 29, 2024
cbb41bb
Merge branch 'develop' into feat/multiple_files_in_one_msg
rodrigok Jul 5, 2024
c93da30
multiple files shared one at a time
abhipatel0211 Jul 7, 2024
cfc177c
Change message API to handle file upload
abhipatel0211 Jul 16, 2024
2e344a1
fix: Ensure correct preview of multiple images in shared in single me…
abhipatel0211 Jul 17, 2024
7f0b615
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Jul 18, 2024
671fd31
solved merge conflict
abhipatel0211 Jul 18, 2024
8379c94
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Jul 25, 2024
9a97c3d
fix: type error of fileContent and remove extra code
abhipatel0211 Jul 25, 2024
62fbc56
added support for single file upload
abhipatel0211 Jul 31, 2024
f88cd26
UI update added cross button on hover and added the functionality of …
abhipatel0211 Jul 31, 2024
f39042b
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 6, 2024
5a9f646
merge develop
abhipatel0211 Aug 6, 2024
771314e
feat: Added a file upload preview inside the messageBox
abhipatel0211 Aug 7, 2024
755c08b
Fix issue in uploads.ts causing duplicate messages on send
abhipatel0211 Aug 7, 2024
f2bd552
Cleanup: Remove unnecessary code
abhipatel0211 Aug 7, 2024
39ff2a3
removed unused space
abhipatel0211 Aug 7, 2024
23eb009
fix: lint errors
abhipatel0211 Aug 8, 2024
e786f70
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 8, 2024
f4b60d5
fix: lint and TS errors
abhipatel0211 Aug 8, 2024
1c0ddde
fix: ensure file handling as array to resolve type errors in uploads
abhipatel0211 Aug 8, 2024
f5213b0
fix: lint error and TS errors
abhipatel0211 Aug 8, 2024
6f398b4
fix: lint and TS errors
abhipatel0211 Aug 8, 2024
cdc0ff5
removed unused code
abhipatel0211 Aug 8, 2024
a1faa22
fix: reorder imports to fix ESLint errors and removed unused changes
abhipatel0211 Aug 8, 2024
326a197
fix: changed the variable name with camelCase and removed unwanted ch…
abhipatel0211 Aug 8, 2024
c078083
fix: changed variable names to cameCase
abhipatel0211 Aug 8, 2024
0e4d827
fix: added toast message while uploading file
abhipatel0211 Aug 9, 2024
60a80f9
Added the files to upload in the sendMessage in the executeSendMessage
abhipatel0211 Aug 10, 2024
7ac5841
fix: Revert back as using message API
abhipatel0211 Aug 10, 2024
9f74219
Removed unused import
abhipatel0211 Aug 10, 2024
9afeee6
Remove unwanted code
abhipatel0211 Aug 10, 2024
97f743b
Added defineProperty for all the files selected
abhipatel0211 Aug 12, 2024
68f45dc
Added different function for files and encrypted files sharing
abhipatel0211 Aug 13, 2024
d7b92cc
changed uploadFiles.ts and FileUploadModal.tsx to handle single file …
abhipatel0211 Aug 13, 2024
21005c0
Merge branch 'develop' into feat/multiple_files_in_one_msg
rodrigok Aug 13, 2024
a0f6c83
Added the type check for the filesToUpload and also removed the refer…
abhipatel0211 Aug 14, 2024
de319d8
Added isUploading and removed the unnecessary changes
abhipatel0211 Aug 14, 2024
3ad5e63
Added a folder of FilePreview near the messageBox and also changed th…
abhipatel0211 Aug 15, 2024
72bc00d
feat: Enable file attachments after typing a message
abhipatel0211 Aug 16, 2024
fe2b428
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 16, 2024
b3db9fc
added title to the generic and image preview
abhipatel0211 Aug 16, 2024
3aa8c3d
fix: issue while sharing the message after file shared
abhipatel0211 Aug 17, 2024
2eb9b64
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 18, 2024
11aac8e
passed uploadIdsToConfirm to the sendMessage in executeSendMessage
abhipatel0211 Aug 18, 2024
9ff1b9f
Added newe function parseMultipleFilesIntoMessageAttachments
abhipatel0211 Aug 18, 2024
2370b14
added ui changes and also added the transition
abhipatel0211 Aug 19, 2024
47b592e
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 19, 2024
9722194
shifted confirm files at last after save message and attached multipl…
abhipatel0211 Aug 21, 2024
84bfcae
fix: image thumbnail display and remove extra msgData parameter
abhipatel0211 Aug 22, 2024
335e886
removed console logs
abhipatel0211 Aug 22, 2024
a5598f7
added a function for parse and also solved eslint error of reshuffling
abhipatel0211 Aug 22, 2024
7ea18d7
fix: solved lint errors messageBox and uploadfiles
abhipatel0211 Aug 23, 2024
822e2c5
fix: lint and TS errors
abhipatel0211 Aug 23, 2024
d1b6922
fix: lint error and converted description to msg
abhipatel0211 Aug 23, 2024
b13bdd2
fix: added description for TS error
abhipatel0211 Aug 23, 2024
a8cff84
Merge branch 'develop' into feat/multiple_files_in_one_msg
rodrigok Aug 23, 2024
0fe3aee
Changed the location of parsing file into attachments and also added …
abhipatel0211 Aug 24, 2024
7347447
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Aug 24, 2024
65c7be7
fix: maintain file upload order to ensure consistent fileId, fileUrl …
abhipatel0211 Aug 31, 2024
c4fb104
Added different function for file upload
abhipatel0211 Aug 31, 2024
12abfc5
removed unnecessary changes
abhipatel0211 Sep 2, 2024
ed463c0
Merge remote-tracking branch 'upstream/develop' into feat/multiple_fi…
abhipatel0211 Sep 2, 2024
8c91c8c
added file which upload the file and return back the file IDs and fil…
abhipatel0211 Sep 3, 2024
7e5081b
fix: added condition so it will remove extra space
abhipatel0211 Sep 5, 2024
e45e376
feat: Add drag-and-drop file upload to message box
abhipatel0211 Sep 8, 2024
d21dd7f
fix: added encryption of message also
abhipatel0211 Sep 11, 2024
8508954
fix: Issue inside the thread messages
abhipatel0211 Sep 20, 2024
ea689a2
fix: multiple dispatch messages
abhipatel0211 Sep 20, 2024
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
4 changes: 4 additions & 0 deletions apps/meteor/app/file-upload/server/methods/sendFileMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@

try {
attachment.image_preview = await FileUpload.resizeImagePreview(file);
console.log('attachement image preview ' + attachment.image_preview);

Check failure on line 73 in apps/meteor/app/file-upload/server/methods/sendFileMessage.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Unexpected string concatenation
abhipatel0211 marked this conversation as resolved.
Show resolved Hide resolved
const thumbResult = await FileUpload.createImageThumbnail(file);
console.log('thumbResult ' + thumbResult);

Check failure on line 75 in apps/meteor/app/file-upload/server/methods/sendFileMessage.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Unexpected string concatenation
if (thumbResult) {
const { data: thumbBuffer, width, height, thumbFileType, thumbFileName, originalFileId } = thumbResult;
const thumbnail = await FileUpload.uploadImageThumbnail(
Expand All @@ -83,6 +85,7 @@
roomId,
user._id,
);
console.log('thumbnail ' + thumbnail);

Check failure on line 88 in apps/meteor/app/file-upload/server/methods/sendFileMessage.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Unexpected string concatenation
const thumbUrl = FileUpload.getPath(`${thumbnail._id}/${encodeURI(file.name || '')}`);
attachment.image_url = thumbUrl;
attachment.image_type = thumbnail.type;
Expand All @@ -97,6 +100,7 @@
size: thumbnail.size || 0,
format: thumbnail.identify?.format || '',
});
console.log(files);
}
} catch (e) {
SystemLogger.error(e);
Expand Down
46 changes: 43 additions & 3 deletions apps/meteor/app/lib/server/functions/sendMessage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Apps } from '@rocket.chat/apps';
import { api, Message } from '@rocket.chat/core-services';
import type { IMessage, IRoom } from '@rocket.chat/core-typings';
import { Messages } from '@rocket.chat/models';
import type { IMessage, IRoom, IUpload, FileProp, MessageAttachment } from '@rocket.chat/core-typings';
import { Messages, Uploads } from '@rocket.chat/models';
import { Match, check } from 'meteor/check';

import { isRelativeURL } from '../../../../lib/utils/isRelativeURL';
Expand All @@ -13,6 +13,7 @@
import { notifyOnRoomChangedById, notifyOnMessageChange } from '../lib/notifyListener';
import { validateCustomMessageFields } from '../lib/validateCustomMessageFields';
import { parseUrlsInMessage } from './parseUrlsInMessage';
import { parseFileIntoMessageAttachments } from '../../../../app/file-upload/server/methods/sendFileMessage';

Check failure on line 16 in apps/meteor/app/lib/server/functions/sendMessage.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

`../../../../app/file-upload/server/methods/sendFileMessage` import should occur before import of `../../../../lib/utils/isRelativeURL`

Check failure on line 16 in apps/meteor/app/lib/server/functions/sendMessage.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Useless path segments for "../../../../app/file-upload/server/methods/sendFileMessage", should be "../../../file-upload/server/methods/sendFileMessage"
abhipatel0211 marked this conversation as resolved.
Show resolved Hide resolved

// TODO: most of the types here are wrong, but I don't want to change them now

Expand Down Expand Up @@ -215,11 +216,46 @@
/**
* Validates and sends the message object.
*/
export const sendMessage = async function (user: any, message: any, room: any, upsert = false, previewUrls?: string[]) {
export const sendMessage = async function (
user: any,
message: any,
room: any,
upsert = false,
previewUrls?: string[],
uploadIdsToConfirm?: string[],
) {
if (!user || !message || !room._id) {
return false;
}

if (uploadIdsToConfirm !== undefined) {
const filesToConfirm: Partial<IUpload>[] = await Promise.all(
uploadIdsToConfirm.map(async (fileid) => {
const file = await Uploads.findOneById(fileid);
if (!file) {
throw new Meteor.Error('invalid-file');
}
return file;
}),
);
if (message?.t !== 'e2e') {
const messageFiles: FileProp[] = [];
const messageAttachments: MessageAttachment[] = [];
const fileAttachmentPromises = filesToConfirm.map(async (file) => {
const roomId = message.rid;
const { files, attachments } = await parseFileIntoMessageAttachments(file, roomId, user);
return { files, attachments };
});
const filesAndAttachments = await Promise.all(fileAttachmentPromises);
filesAndAttachments.forEach(({ files, attachments }) => {
messageFiles.push(...files);
messageAttachments.push(...attachments);
});
message.files = messageFiles;
message.attachments = messageAttachments;
abhipatel0211 marked this conversation as resolved.
Show resolved Hide resolved
}
}

await validateMessage(message, room, user);
prepareMessageObject(message, room._id, user);

Expand Down Expand Up @@ -292,6 +328,10 @@
// TODO: is there an opportunity to send returned data to notifyOnMessageChange?
await afterSaveMessage(message, room);

if (uploadIdsToConfirm !== undefined) {
await Promise.all(uploadIdsToConfirm.map((fileid) => Uploads.confirmTemporaryFile(fileid, user._id)));
}

void notifyOnMessageChange({ id: message._id });

void notifyOnRoomChangedById(message.rid);
Expand Down
16 changes: 10 additions & 6 deletions apps/meteor/app/lib/server/methods/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import { MessageTypes } from '../../../ui-utils/server';
import { sendMessage } from '../functions/sendMessage';
import { RateLimiter } from '../lib';

export async function executeSendMessage(uid: IUser['_id'], message: AtLeast<IMessage, 'rid'>, previewUrls?: string[]) {
export async function executeSendMessage(
uid: IUser['_id'],
message: AtLeast<IMessage, 'rid'>,
previewUrls?: string[],
uploadIdsToConfirm?: string[],
) {
if (message.tshow && !message.tmid) {
throw new Meteor.Error('invalid-params', 'tshow provided but missing tmid', {
method: 'sendMessage',
Expand Down Expand Up @@ -93,7 +98,7 @@ export async function executeSendMessage(uid: IUser['_id'], message: AtLeast<IMe
}

metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736
return await sendMessage(user, message, room, false, previewUrls);
return await sendMessage(user, message, room, false, previewUrls, uploadIdsToConfirm);
} catch (err: any) {
SystemLogger.error({ msg: 'Error sending message:', err });

Expand All @@ -114,12 +119,12 @@ export async function executeSendMessage(uid: IUser['_id'], message: AtLeast<IMe
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
sendMessage(message: AtLeast<IMessage, '_id' | 'rid' | 'msg'>, previewUrls?: string[]): any;
sendMessage(message: AtLeast<IMessage, '_id' | 'rid' | 'msg'>, previewUrls?: string[], uploadIdsToConfirm?: string[]): any;
}
}

Meteor.methods<ServerMethods>({
async sendMessage(message, previewUrls) {
async sendMessage(message, previewUrls, uploadIdsToConfirm) {
check(message, Object);

const uid = Meteor.userId();
Expand All @@ -132,9 +137,8 @@ Meteor.methods<ServerMethods>({
if (MessageTypes.isSystemMessage(message)) {
throw new Error("Cannot send system messages using 'sendMessage'");
}

abhipatel0211 marked this conversation as resolved.
Show resolved Hide resolved
try {
return await executeSendMessage(uid, message, previewUrls);
return await executeSendMessage(uid, message, previewUrls, uploadIdsToConfirm);
} catch (error: any) {
if ((error.error || error.message) === 'error-not-allowed') {
throw new Meteor.Error(error.error || error.message, error.reason, {
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/client/lib/chats/ChatAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ export type UploadsAPI = {
wipeFailedOnes(): void;
cancel(id: Upload['id']): void;
send(
file: File,
file: File[] | File,
{ description, msg, t, e2e }: { description?: string; msg?: string; t?: IMessage['t']; e2e?: IMessage['e2e'] },
getContent?: (fileId: string, fileUrl: string) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted: IE2EEMessage['content'] },
getContent?: (fileId: string[], fileUrl: string[]) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted?: { algorithm: string; ciphertext: string } | undefined },
): Promise<void>;
};

Expand Down
113 changes: 62 additions & 51 deletions apps/meteor/client/lib/chats/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
};

const send = async (
file: File,
file: File[] | File,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API should continue sending only a single file a time. The places where we send multiple files should call this API multiple times

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification @rodrigok

I have currently implemented it so that if there's a single file, it's converted to an array and sent using the API. For multiple files, I'm looping through each file and sending them one at a time using the API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abhipatel0211 got it, but that is what is wrong. This API should only make the file upload. Should not even receive the message content to call the sendMessage inside it. The responsibility of this API should be to upload the file and return the file data to be stored in memory in the message composer. There you will call the sendMessage passing the list of files to be confirmed.

This code was like that because the flow to upload the file was coming from the modal and the old API was doing both things (upload and message send) together.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think that you don't need to upload the files only when the message is sent. You can upload each file when you are attaching it to the message box, so when you send the message later the files are already uploaded and you only confirm the uploads via ID. If the user forget the message in composing status the files will end up deleted after a while because they were not confirmed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rodrigok sir so is it good to create an another uploadsFiles function which will be just used for the the fileUpload and return id. As this uploads function can be also used from uploadfiles and other places also (like live audio and video is sharing).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you should extract the upload logic to another function

{
description,

Check failure on line 35 in apps/meteor/client/lib/chats/uploads.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Parameter name `description` must have one leading underscore(s)

Check failure on line 35 in apps/meteor/client/lib/chats/uploads.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

'description' is defined but never used. Allowed unused args must match /^_/u
msg,
rid,
tmid,
Expand All @@ -44,41 +44,41 @@
tmid?: string;
t?: IMessage['t'];
},
getContent?: (fileId: string, fileUrl: string) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted: IE2EEMessage['content'] },
getContent?: (fileId: string[], fileUrl: string[]) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted?: { algorithm: string; ciphertext: string } | undefined },
): Promise<void> => {
const files = Array.isArray(file) ? file : [file];
const id = Random.id();

updateUploads((uploads) => [
...uploads,
{
id,
name: fileContent?.raw.name || file.name,
name: files[0].name || fileContent?.raw.name || 'unknown',
percentage: 0,
},
]);

try {
await new Promise((resolve, reject) => {
const fileIds: string[] = [];
const fileUrls: string[] = [];

files.forEach((f) => {
new Promise<void>((resolve, reject) => {
const xhr = sdk.rest.upload(
`/v1/rooms.media/${rid}`,
{
file,
file: f,
...(fileContent && {
content: JSON.stringify(fileContent.encrypted),
}),
},
{
load: (event) => {
resolve(event);
},
progress: (event) => {
if (!event.lengthComputable) {
return;
}
const progress = (event.loaded / event.total) * 100;
if (progress === 100) {
return;
resolve();
}

updateUploads((uploads) =>
Expand Down Expand Up @@ -116,51 +116,62 @@
xhr.onload = async () => {
if (xhr.readyState === xhr.DONE && xhr.status === 200) {
const result = JSON.parse(xhr.responseText);
let content;
if (getContent) {
content = await getContent(result.file._id, result.file.url);
}
fileIds.push(result.file._id);
fileUrls.push(result.file.url);
if (fileIds.length === files.length) {
if (msg === undefined) {
msg = '';
}

await sdk.rest.post(`/v1/rooms.mediaConfirm/${rid}/${result.file._id}`, {
msg,
tmid,
description,
t,
content,
});
try {
let content;
if (getContent) {
content = await getContent(fileIds, fileUrls);
}
const text: IMessage = {
rid,
_id: id,
msg: msg || '',
ts: new Date(),
u: { _id: id, username: id },
_updatedAt: new Date(),
tmid,
t,
content,
};
await sdk.call('sendMessage', text, fileUrls, fileIds);

updateUploads((uploads) => uploads.filter((upload) => upload.id !== id));
} catch (error) {
updateUploads((uploads) =>
uploads.map((upload) => {
if (upload.id !== id) {
return upload;
}

return {
...upload,
percentage: 0,
error: new Error(getErrorMessage(error)),
};
}),
);
} finally {
if (!uploads.length) {
UserAction.stop(rid, USER_ACTIVITIES.USER_UPLOADING, { tmid });
}
}
}
}
};

if (uploads.length) {
UserAction.performContinuously(rid, USER_ACTIVITIES.USER_UPLOADING, { tmid });
}

emitter.once(`cancelling-${id}`, () => {
xhr.abort();
updateUploads((uploads) => uploads.filter((upload) => upload.id !== id));
reject(new Error('Upload cancelled'));
});
});

updateUploads((uploads) => uploads.filter((upload) => upload.id !== id));
} catch (error: unknown) {
updateUploads((uploads) =>
uploads.map((upload) => {
if (upload.id !== id) {
return upload;
}

return {
...upload,
percentage: 0,
error: new Error(getErrorMessage(error)),
};
}),
);
} finally {
if (!uploads.length) {
UserAction.stop(rid, USER_ACTIVITIES.USER_UPLOADING, { tmid });
}
}
});
};

export const createUploadsAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid?: IMessage['_id'] }): UploadsAPI => ({
Expand All @@ -169,9 +180,9 @@
wipeFailedOnes,
cancel,
send: (
file: File,
file: File[] | File,
{ description, msg, t }: { description?: string; msg?: string; t?: IMessage['t'] },
getContent?: (fileId: string, fileUrl: string) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted: IE2EEMessage['content'] },
getContent?: (fileId: string[], fileUrl: string[]) => Promise<IE2EEMessage['content']>,
fileContent?: { raw: Partial<IUpload>; encrypted?: { algorithm: string; ciphertext: string } | undefined },
): Promise<void> => send(file, { description, msg, rid, tmid, t }, getContent, fileContent),
});
4 changes: 3 additions & 1 deletion apps/meteor/client/providers/ImageGalleryProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ const ImageGalleryProvider = ({ children }: ImageGalleryProviderProps) => {
return setSingleImageUrl(target.dataset.id);
}
if (target?.classList.contains('gallery-item')) {
const id1 = target.dataset.src?.split('/file-upload/')[1].split('/')[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, when sharing multiple files in one message, the preview always shows the very first image from the set, even if a different image is clicked. The preview should display the selected image correctly.

I've made adjustments to address this issue, ensuring that the correct image is displayed when clicked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, we need to solve the root issue later, the issue happens here https://github.com/abhipatel0211/rocket.chat/blob/cdc0ff5ff9f82be59af8bdf4b4e70e478ebf129d/apps/meteor/client/components/message/variants/room/RoomMessageContent.tsx#L73 since we pass only the first file id to the attachment elements. We, probably, have to save the file id inside the attachment to use it there and use the first id passed as fallback (for the old records)


const id = target.closest('.gallery-item-container')?.getAttribute('data-id') || undefined;
return setImageId(target.dataset.id || id);
return setImageId(id1 || target.dataset.id || id);
}
if (target?.classList.contains('gallery-item-container')) {
return setImageId(target.dataset.id);
Expand Down
Loading
Loading