moved file reading ot worker

This commit is contained in:
Abhinav-grd 2021-08-18 10:02:27 +05:30
parent 9270d80d24
commit 9b49e15d5c
6 changed files with 69 additions and 15 deletions

View file

@ -82,8 +82,11 @@ class DownloadManager {
const typeFromExtension =
file.metadata.title.split('.')[-1];
const worker = await new CryptoWorker();
const mimeType =
(await getMimeTypeFromBlob(
worker,
new FileReader(),
fileBlob
)) ?? typeFromExtension;

View file

@ -8,20 +8,25 @@ const TYPE_IMAGE = 'image';
const EDITED_FILE_SUFFIX = '-edited';
const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100;
export async function getFileData(reader: FileReader, file: globalThis.File) {
export async function getFileData(
worker,
reader: FileReader,
file: globalThis.File
) {
if (file.size > MULTIPART_PART_SIZE) {
return getFileStream(reader, file, FILE_READER_CHUNK_SIZE);
return getFileStream(worker, reader, file, FILE_READER_CHUNK_SIZE);
} else {
return await getUint8ArrayView(reader, file);
return await worker.getUint8ArrayView(file);
}
}
export async function getFileType(
worker,
reader: FileReader,
receivedFile: globalThis.File
) {
let fileType: FILE_TYPE;
const mimeType = await getMimeType(reader, receivedFile);
const mimeType = await getMimeType(worker, reader, receivedFile);
const majorType = mimeType?.split('/')[0].toLowerCase();
switch (majorType) {
case TYPE_IMAGE:
@ -52,23 +57,33 @@ export function getFileOriginalName(file: globalThis.File) {
return originalName;
}
async function getMimeType(reader: FileReader, file: globalThis.File) {
async function getMimeType(worker, reader: FileReader, file: globalThis.File) {
const fileChunkBlob = file.slice(0, CHUNK_SIZE_FOR_TYPE_DETECTION);
return getMimeTypeFromBlob(reader, fileChunkBlob);
return getMimeTypeFromBlob(worker, reader, fileChunkBlob);
}
export async function getMimeTypeFromBlob(reader: FileReader, fileBlob: Blob) {
const initialFiledata = await getUint8ArrayView(reader, fileBlob);
export async function getMimeTypeFromBlob(
worker,
reader: FileReader,
fileBlob: Blob
) {
const initialFiledata = await worker.getUint8ArrayView(fileBlob);
const result = await FileType.fromBuffer(initialFiledata);
return result?.mime;
}
function getFileStream(
worker,
reader: FileReader,
file: globalThis.File,
chunkSize: number
) {
const fileChunkReader = fileChunkReaderMaker(reader, file, chunkSize);
const fileChunkReader = fileChunkReaderMaker(
worker,
reader,
file,
chunkSize
);
const stream = new ReadableStream<Uint8Array>({
async pull(controller: ReadableStreamDefaultController) {
@ -88,6 +103,7 @@ function getFileStream(
}
async function* fileChunkReaderMaker(
worker,
reader: FileReader,
file: globalThis.File,
chunkSize: number
@ -95,7 +111,7 @@ async function* fileChunkReaderMaker(
let offset = 0;
while (offset < file.size) {
const blob = file.slice(offset, chunkSize + offset);
const fileChunk = await getUint8ArrayView(reader, blob);
const fileChunk = await worker.getUint8ArrayView(blob);
yield fileChunk;
offset += chunkSize;
}

View file

@ -2,7 +2,6 @@ import { FILE_TYPE } from 'services/fileService';
import { CustomError } from 'utils/common/errorUtil';
import { convertHEIC2JPEG } from 'utils/file';
import { logError } from 'utils/sentry';
import { getUint8ArrayView } from './readFileService';
const THUMBNAIL_HEIGHT = 720;
const MAX_ATTEMPTS = 3;
@ -11,6 +10,7 @@ const MIN_THUMBNAIL_SIZE = 50000;
const WAIT_TIME_THUMBNAIL_GENERATION = 10 * 1000;
export async function generateThumbnail(
worker,
reader: FileReader,
file: globalThis.File,
fileType: FILE_TYPE,
@ -31,7 +31,7 @@ export async function generateThumbnail(
hasStaticThumbnail = true;
}
const thumbnailBlob = await thumbnailCanvasToBlob(canvas);
const thumbnail = await getUint8ArrayView(reader, thumbnailBlob);
const thumbnail = await worker.getUint8ArrayView(thumbnailBlob);
return { thumbnail, hasStaticThumbnail };
} catch (e) {
logError(e, 'Error generating thumbnail');

View file

@ -99,11 +99,16 @@ class UploadService {
}
async readFile(
worker,
reader: FileReader,
rawFile: globalThis.File,
collection: Collection
): Promise<FileInMemory> {
const { fileType, mimeType } = await getFileType(reader, rawFile);
const { fileType, mimeType } = await getFileType(
worker,
reader,
rawFile
);
if (fileType === FILE_TYPE.OTHERS) {
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
}
@ -111,6 +116,7 @@ class UploadService {
const isHEIC = fileIsHEIC(mimeType);
const { thumbnail, hasStaticThumbnail } = await generateThumbnail(
worker,
reader,
rawFile,
fileType,
@ -137,7 +143,7 @@ class UploadService {
extractedMetadata[key] = value;
}
const filedata = await getFileData(reader, rawFile);
const filedata = await getFileData(worker, reader, rawFile);
return {
filedata,

View file

@ -33,7 +33,12 @@ export default async function uploader(
let file: FileInMemory = null;
let encryptedFile: EncryptedFile = null;
try {
file = await UploadService.readFile(reader, rawFile, collection);
file = await UploadService.readFile(
worker,
reader,
rawFile,
collection
);
if (fileAlreadyInCollection(existingFilesInCollection, file)) {
UIService.setFileProgress(rawFile.name, FileUploadResults.SKIPPED);
@ -68,6 +73,7 @@ export default async function uploader(
file: decryptedFile,
};
} catch (e) {
console.log(e);
logError(e, 'file upload failed');
handleError(e);
switch (e.message) {

View file

@ -147,6 +147,29 @@ export class Crypto {
async fromHex(string) {
return libsodium.fromHex(string);
}
async getUint8ArrayView(file) {
try {
return await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onabort = () =>
reject(Error('file reading was aborted'));
reader.onerror = () => reject(Error('file reading has failed'));
reader.onload = () => {
// Do whatever you want with the file contents
const result =
typeof reader.result === 'string'
? new TextEncoder().encode(reader.result)
: new Uint8Array(reader.result);
resolve(result);
};
reader.readAsArrayBuffer(file);
});
} catch (e) {
console.log(e, 'error reading file to byte-array');
throw e;
}
}
}
Comlink.expose(Crypto);