moved file reading ot worker
This commit is contained in:
parent
9270d80d24
commit
9b49e15d5c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue