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
63 changes: 34 additions & 29 deletions app/lib/methods/sendFileMessage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';

import FileUpload from '../../utils/fileUpload';
import database from '../database';
import log from '../../utils/log';

Expand All @@ -12,7 +13,11 @@ export function isUploadActive(path) {

export async function cancelUpload(item) {
if (uploadQueue[item.path]) {
uploadQueue[item.path].abort();
try {
await uploadQueue[item.path].cancel();
} catch {
// Do nothing
}
try {
const db = database.active;
await db.action(async() => {
Expand All @@ -32,9 +37,6 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {

const uploadUrl = `${ server }/api/v1/rooms.upload/${ rid }`;

const xhr = new XMLHttpRequest();
const formData = new FormData();

fileInfo.rid = rid;

const db = database.active;
Expand All @@ -56,31 +58,38 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
}
}

uploadQueue[fileInfo.path] = xhr;
xhr.open('POST', uploadUrl);

formData.append('file', {
uri: fileInfo.path,
const formData = [];
formData.push({
name: 'file',
type: fileInfo.type,
name: encodeURI(fileInfo.name) || 'fileMessage'
filename: fileInfo.name || 'fileMessage',
uri: fileInfo.path
});

if (fileInfo.description) {
formData.append('description', fileInfo.description);
formData.push({
name: 'description',
data: fileInfo.description
});
}

if (tmid) {
formData.append('tmid', tmid);
formData.push({
name: 'tmid',
data: tmid
});
}

xhr.setRequestHeader('X-Auth-Token', token);
xhr.setRequestHeader('X-User-Id', id);
const { customHeaders } = RocketChatSettings;
Object.keys(customHeaders).forEach((key) => {
xhr.setRequestHeader(key, customHeaders[key]);
});
const headers = {
...RocketChatSettings.customHeaders,
'Content-Type': 'multipart/form-data',
'X-Auth-Token': token,
'X-User-Id': id
};

uploadQueue[fileInfo.path] = FileUpload.fetch('POST', uploadUrl, headers, formData);

xhr.upload.onprogress = async({ total, loaded }) => {
uploadQueue[fileInfo.path].uploadProgress(async(loaded, total) => {
try {
await db.action(async() => {
await uploadRecord.update((u) => {
Expand All @@ -90,15 +99,14 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
} catch (e) {
log(e);
}
};
});

xhr.onload = async() => {
if (xhr.status >= 200 && xhr.status < 400) { // If response is all good...
uploadQueue[fileInfo.path].then(async(response) => {
if (response.respInfo.status >= 200 && response.respInfo.status < 400) { // If response is all good...
try {
await db.action(async() => {
await uploadRecord.destroyPermanently();
});
const response = JSON.parse(xhr.response);
resolve(response);
} catch (e) {
log(e);
Expand All @@ -114,15 +122,14 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
log(e);
}
try {
const response = JSON.parse(xhr.response);
reject(response);
} catch (e) {
reject(e);
}
}
};
});

xhr.onerror = async(error) => {
uploadQueue[fileInfo.path].catch(async(error) => {
try {
await db.action(async() => {
await uploadRecord.update((u) => {
Expand All @@ -133,9 +140,7 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
log(e);
}
reject(error);
};

xhr.send(formData);
});
} catch (e) {
log(e);
}
Expand Down
22 changes: 22 additions & 0 deletions app/utils/fileUpload/index.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import RNFetchBlob from 'rn-fetch-blob';

class FileUpload {
fetch = (method, url, headers, data) => {
const formData = data.map((item) => {
if (item.uri) {
return {
name: item.name,
type: item.type,
filename: item.filename,
data: RNFetchBlob.wrap(decodeURI(item.uri))
};
}
return item;
});

return RNFetchBlob.fetch(method, url, headers, formData);
}
}

const fileUpload = new FileUpload();
export default fileUpload;
48 changes: 48 additions & 0 deletions app/utils/fileUpload/index.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class FileUpload {
_xhr = new XMLHttpRequest();

_formData = new FormData();

fetch = (method, url, headers, data) => {
this._xhr.open(method, url);

Object.keys(headers).forEach((key) => {
this._xhr.setRequestHeader(key, headers[key]);
});

data.forEach((item) => {
if (item.uri) {
this._formData.append(item.name, {
uri: item.uri,
type: item.type,
name: item.filename
});
} else {
this._formData.append(item.name, item.data);
}
});

return this;
}

then = (callback) => {
this._xhr.onload = () => callback({ respInfo: this._xhr });
this._xhr.send(this._formData);
}

catch = (callback) => {
this._xhr.onerror = callback;
}

uploadProgress = (callback) => {
this._xhr.upload.onprogress = ({ total, loaded }) => callback(loaded, total);
}

cancel = () => {
this._xhr.abort();
return Promise.resolve();
}
}

const fileUpload = new FileUpload();
export default fileUpload;
2 changes: 1 addition & 1 deletion app/views/ShareListView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class ShareListView extends React.Component {
}
const info = await Promise.all(data.filter(item => item.type === 'media').map(file => FileSystem.getInfoAsync(this.uriToPath(file.value), { size: true })));
const attachments = info.map(file => ({
filename: file.uri.substring(file.uri.lastIndexOf('/') + 1),
filename: decodeURIComponent(file.uri.substring(file.uri.lastIndexOf('/') + 1)),
description: '',
size: file.size,
mime: mime.lookup(file.uri),
Expand Down
12 changes: 12 additions & 0 deletions patches/react-native-image-crop-picker+0.31.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
index 3500542..94e45b6 100644
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
@@ -584,6 +584,7 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
image.putInt("height", options.outHeight);
image.putString("mime", options.outMimeType);
image.putInt("size", (int) new File(compressedImagePath).length());
+ image.putString("filename", compressedImage.getName());
image.putString("modificationDate", String.valueOf(modificationDate));

if (includeBase64) {