|
@@ -1,7 +1,11 @@
|
|
|
import { getToken } from 'utils/common/key';
|
|
|
import { getFileUrl, getThumbnailUrl } from 'utils/common/apiUtil';
|
|
|
import CryptoWorker from 'utils/crypto';
|
|
|
-import { generateStreamFromArrayBuffer, convertForPreview } from 'utils/file';
|
|
|
+import {
|
|
|
+ generateStreamFromArrayBuffer,
|
|
|
+ convertForPreview,
|
|
|
+ needsConversionForPreview,
|
|
|
+} from 'utils/file';
|
|
|
import HTTPService from './HTTPService';
|
|
|
import { File, FILE_TYPE } from './fileService';
|
|
|
import { logError } from 'utils/sentry';
|
|
@@ -10,27 +14,36 @@ class DownloadManager {
|
|
|
private fileObjectUrlPromise = new Map<string, Promise<string>>();
|
|
|
private thumbnailObjectUrlPromise = new Map<number, Promise<string>>();
|
|
|
|
|
|
- public async getPreview(file: File) {
|
|
|
+ public async getThumbnail(file: File) {
|
|
|
try {
|
|
|
const token = getToken();
|
|
|
if (!token) {
|
|
|
return null;
|
|
|
}
|
|
|
- const thumbnailCache = await caches.open('thumbs');
|
|
|
- const cacheResp: Response = await thumbnailCache.match(
|
|
|
- file.id.toString()
|
|
|
- );
|
|
|
- if (cacheResp) {
|
|
|
- return URL.createObjectURL(await cacheResp.blob());
|
|
|
- }
|
|
|
if (!this.thumbnailObjectUrlPromise.get(file.id)) {
|
|
|
- const downloadPromise = this.downloadThumb(
|
|
|
- token,
|
|
|
- thumbnailCache,
|
|
|
- file
|
|
|
- );
|
|
|
- this.thumbnailObjectUrlPromise.set(file.id, downloadPromise);
|
|
|
+ const downloadPromise = async () => {
|
|
|
+ const thumbnailCache = await caches.open('thumbs');
|
|
|
+ const cacheResp: Response = await thumbnailCache.match(
|
|
|
+ file.id.toString()
|
|
|
+ );
|
|
|
+ if (cacheResp) {
|
|
|
+ return URL.createObjectURL(await cacheResp.blob());
|
|
|
+ }
|
|
|
+ const thumb = await this.downloadThumb(token, file);
|
|
|
+ const thumbBlob = new Blob([thumb]);
|
|
|
+ try {
|
|
|
+ await thumbnailCache.put(
|
|
|
+ file.id.toString(),
|
|
|
+ new Response(thumbBlob)
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ // TODO: handle storage full exception.
|
|
|
+ }
|
|
|
+ return URL.createObjectURL(thumbBlob);
|
|
|
+ };
|
|
|
+ this.thumbnailObjectUrlPromise.set(file.id, downloadPromise());
|
|
|
}
|
|
|
+
|
|
|
return await this.thumbnailObjectUrlPromise.get(file.id);
|
|
|
} catch (e) {
|
|
|
this.thumbnailObjectUrlPromise.delete(file.id);
|
|
@@ -39,24 +52,7 @@ class DownloadManager {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private downloadThumb = async (
|
|
|
- token: string,
|
|
|
- thumbnailCache: Cache,
|
|
|
- file: File
|
|
|
- ) => {
|
|
|
- const thumb = await this.getThumbnail(token, file);
|
|
|
- try {
|
|
|
- await thumbnailCache.put(
|
|
|
- file.id.toString(),
|
|
|
- new Response(new Blob([thumb]))
|
|
|
- );
|
|
|
- } catch (e) {
|
|
|
- // TODO: handle storage full exception.
|
|
|
- }
|
|
|
- return URL.createObjectURL(new Blob([thumb]));
|
|
|
- };
|
|
|
-
|
|
|
- getThumbnail = async (token: string, file: File) => {
|
|
|
+ downloadThumb = async (token: string, file: File) => {
|
|
|
const resp = await HTTPService.get(
|
|
|
getThumbnailUrl(file.id),
|
|
|
null,
|
|
@@ -73,36 +69,36 @@ class DownloadManager {
|
|
|
};
|
|
|
|
|
|
getFile = async (file: File, forPreview = false) => {
|
|
|
- let fileUID: string;
|
|
|
- if (file.metadata.fileType === FILE_TYPE.VIDEO) {
|
|
|
- fileUID = file.id.toString();
|
|
|
- } else {
|
|
|
- fileUID = `${file.id}_forPreview=${forPreview}`;
|
|
|
- }
|
|
|
+ const shouldBeConverted = forPreview && needsConversionForPreview(file);
|
|
|
+ const fileKey = shouldBeConverted
|
|
|
+ ? `${file.id}_converted`
|
|
|
+ : `${file.id}`;
|
|
|
try {
|
|
|
- const getFilePromise = async () => {
|
|
|
+ const getFilePromise = async (convert: boolean) => {
|
|
|
const fileStream = await this.downloadFile(file);
|
|
|
let fileBlob = await new Response(fileStream).blob();
|
|
|
- if (forPreview) {
|
|
|
+ if (convert) {
|
|
|
fileBlob = await convertForPreview(file, fileBlob);
|
|
|
}
|
|
|
return URL.createObjectURL(fileBlob);
|
|
|
};
|
|
|
- if (!this.fileObjectUrlPromise.get(fileUID)) {
|
|
|
- this.fileObjectUrlPromise.set(fileUID, getFilePromise());
|
|
|
+ if (!this.fileObjectUrlPromise.get(fileKey)) {
|
|
|
+ this.fileObjectUrlPromise.set(
|
|
|
+ fileKey,
|
|
|
+ getFilePromise(shouldBeConverted)
|
|
|
+ );
|
|
|
}
|
|
|
- return await this.fileObjectUrlPromise.get(fileUID);
|
|
|
+ const fileURL = await this.fileObjectUrlPromise.get(fileKey);
|
|
|
+ return fileURL;
|
|
|
} catch (e) {
|
|
|
- this.fileObjectUrlPromise.delete(fileUID);
|
|
|
+ this.fileObjectUrlPromise.delete(fileKey);
|
|
|
logError(e, 'Failed to get File');
|
|
|
throw e;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- public async getCachedFile(file: File) {
|
|
|
- return await this.fileObjectUrlPromise.get(
|
|
|
- `${file.id}_forPreview=false`
|
|
|
- );
|
|
|
+ public async getCachedOriginalFile(file: File) {
|
|
|
+ return await this.fileObjectUrlPromise.get(file.id.toString());
|
|
|
}
|
|
|
|
|
|
async downloadFile(file: File) {
|