fix minor bugs
This commit is contained in:
parent
87d635be58
commit
0fff2ee674
|
@ -77,6 +77,7 @@ export default function Upload(props: Props) {
|
|||
setFileProgress,
|
||||
setUploadResult,
|
||||
setUploadStage,
|
||||
setFilenames,
|
||||
},
|
||||
props.setFiles
|
||||
);
|
||||
|
@ -121,11 +122,6 @@ export default function Upload(props: Props) {
|
|||
if (props.acceptedFiles.length === 0) {
|
||||
return null;
|
||||
}
|
||||
setFilenames(
|
||||
new Map<number, string>(
|
||||
props.acceptedFiles.map((file, index) => [index, file.name])
|
||||
)
|
||||
);
|
||||
const paths: string[] = props.acceptedFiles.map((file) => file['path']);
|
||||
const getCharCount = (str: string) => (str.match(/\//g) ?? []).length;
|
||||
paths.sort((path1, path2) => getCharCount(path1) - getCharCount(path2));
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
EncryptedFile,
|
||||
EncryptionResult,
|
||||
FileWithMetadata,
|
||||
ParsedMetadataJSONMap,
|
||||
} from 'types/upload';
|
||||
import { logError } from 'utils/sentry';
|
||||
import { encryptFiledata } from './encryptionService';
|
||||
|
@ -40,13 +41,14 @@ export async function readFile(
|
|||
}
|
||||
|
||||
export async function getFileMetadata(
|
||||
parsedMetadataJSONMap: ParsedMetadataJSONMap,
|
||||
rawFile: File,
|
||||
collectionID: number,
|
||||
fileTypeInfo: FileTypeInfo
|
||||
) {
|
||||
const originalName = getFileOriginalName(rawFile);
|
||||
const googleMetadata =
|
||||
this.metadataMap.get(
|
||||
parsedMetadataJSONMap.get(
|
||||
getMetadataJSONMapKey(collectionID, originalName)
|
||||
) ?? {};
|
||||
const extractedMetadata: Metadata = await extractMetadata(
|
||||
|
|
|
@ -9,23 +9,33 @@ import {
|
|||
} from 'types/upload';
|
||||
import { splitFilenameAndExtension } from 'utils/file';
|
||||
import { readFile } from './fileService';
|
||||
import { getFileType } from './readFileService';
|
||||
import uploadService from './uploadService';
|
||||
import UploadService from './uploadService';
|
||||
export async function getLivePhotoFileType(
|
||||
worker,
|
||||
livePhotoAssets: LivePhotoAssets
|
||||
|
||||
export function getLivePhotoFileType(
|
||||
file1TypeInfo: FileTypeInfo,
|
||||
file2TypeInfo: FileTypeInfo
|
||||
) {
|
||||
const file1TypeInfo = await getFileType(worker, livePhotoAssets[0]);
|
||||
const file2TypeInfo = await getFileType(worker, livePhotoAssets[1]);
|
||||
return {
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
exactType: `${file1TypeInfo.exactType}+${file2TypeInfo.exactType}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function getLivePhotoMetadata(
|
||||
file1Metadata: Metadata,
|
||||
file2Metadata: Metadata
|
||||
) {
|
||||
return {
|
||||
...file1Metadata,
|
||||
...file2Metadata,
|
||||
title: splitFilenameAndExtension(file1Metadata.title)[0],
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
};
|
||||
}
|
||||
|
||||
export function getLivePhotoSize(livePhotoAssets: LivePhotoAssets) {
|
||||
return livePhotoAssets[0].size + livePhotoAssets[1].size;
|
||||
return livePhotoAssets.image.size + livePhotoAssets.video.size;
|
||||
}
|
||||
|
||||
export async function readLivePhoto(
|
||||
|
@ -37,13 +47,13 @@ export async function readLivePhoto(
|
|||
const image = await readFile(
|
||||
worker,
|
||||
reader,
|
||||
fileTypeInfo,
|
||||
{ exactType: fileTypeInfo.exactType, fileType: FILE_TYPE.IMAGE },
|
||||
livePhotoAssets.image
|
||||
);
|
||||
const video = await readFile(
|
||||
worker,
|
||||
reader,
|
||||
fileTypeInfo,
|
||||
{ exactType: fileTypeInfo.exactType, fileType: FILE_TYPE.VIDEO },
|
||||
livePhotoAssets.video
|
||||
);
|
||||
|
||||
|
@ -66,9 +76,14 @@ export async function readLivePhoto(
|
|||
|
||||
export function clusterLivePhotoFiles(mediaFiles: FileWithCollection[]) {
|
||||
const analysedMediaFiles: FileWithCollection[] = [];
|
||||
for (let i = 0; i < mediaFiles.length - 1; i++) {
|
||||
mediaFiles.sort((media1Files, media2Files) =>
|
||||
splitFilenameAndExtension(media1Files.file.name)[0].localeCompare(
|
||||
splitFilenameAndExtension(media2Files.file.name)[0]
|
||||
)
|
||||
);
|
||||
for (let i = 0; i < mediaFiles.length - 1; i += 2) {
|
||||
const mediaFile1 = mediaFiles[i];
|
||||
const mediaFile2 = mediaFiles[i];
|
||||
const mediaFile2 = mediaFiles[i + 1];
|
||||
const { fileTypeInfo: file1TypeInfo, metadata: file1Metadata } =
|
||||
UploadService.getFileMetadataAndFileTypeInfo(mediaFile1.localID);
|
||||
const { fileTypeInfo: file2TypeInfo, metadata: file2Metadata } =
|
||||
|
@ -93,15 +108,14 @@ export function clusterLivePhotoFiles(mediaFiles: FileWithCollection[]) {
|
|||
isLivePhoto: true,
|
||||
livePhotoAssets: { image: imageFile, video: videoFile },
|
||||
});
|
||||
const livePhotoFileTypeInfo: FileTypeInfo = {
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
exactType: `${file1TypeInfo.exactType} - ${file2TypeInfo.exactType}`,
|
||||
};
|
||||
const livePhotoMetadata: Metadata = {
|
||||
...file1Metadata,
|
||||
...file2Metadata,
|
||||
title: splitFilenameAndExtension(file1Metadata.title)[0],
|
||||
};
|
||||
const livePhotoFileTypeInfo: FileTypeInfo = getLivePhotoFileType(
|
||||
file1TypeInfo,
|
||||
file2TypeInfo
|
||||
);
|
||||
const livePhotoMetadata: Metadata = getLivePhotoMetadata(
|
||||
file1Metadata,
|
||||
file2Metadata
|
||||
);
|
||||
uploadService.setFileMetadataAndFileTypeInfo(livePhotoLocalID, {
|
||||
fileTypeInfo: { ...livePhotoFileTypeInfo },
|
||||
metadata: { ...livePhotoMetadata },
|
||||
|
@ -121,10 +135,22 @@ function areFilesLivePhotoAssets(
|
|||
mediaFile1: FileWithCollection,
|
||||
mediaFile2: FileWithCollection
|
||||
) {
|
||||
const { collectionID: file1collectionID, file: file1 } = mediaFile1;
|
||||
const { collectionID: file2collectionID, file: file2 } = mediaFile2;
|
||||
const file1Type = FILE_TYPE.OTHERS;
|
||||
const file2Type = FILE_TYPE.OTHERS;
|
||||
const {
|
||||
collectionID: file1collectionID,
|
||||
file: file1,
|
||||
localID: localID1,
|
||||
} = mediaFile1;
|
||||
const {
|
||||
collectionID: file2collectionID,
|
||||
file: file2,
|
||||
localID: localID2,
|
||||
} = mediaFile2;
|
||||
const {
|
||||
fileTypeInfo: { fileType: file1Type },
|
||||
} = UploadService.getFileMetadataAndFileTypeInfo(localID1);
|
||||
const {
|
||||
fileTypeInfo: { fileType: file2Type },
|
||||
} = UploadService.getFileMetadataAndFileTypeInfo(localID2);
|
||||
return (
|
||||
file1collectionID === file2collectionID &&
|
||||
file1Type !== file2Type &&
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { FILE_TYPE } from 'constants/file';
|
||||
import { logError } from 'utils/sentry';
|
||||
import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from 'constants/upload';
|
||||
import {
|
||||
FILE_READER_CHUNK_SIZE,
|
||||
FORMAT_MISSED_BY_FILE_TYPE_LIB,
|
||||
MULTIPART_PART_SIZE,
|
||||
} from 'constants/upload';
|
||||
import FileType from 'file-type/browser';
|
||||
import { CustomError } from 'utils/error';
|
||||
import { getFileExtension, splitFilenameAndExtension } from 'utils/file';
|
||||
|
@ -43,6 +47,15 @@ export async function getFileType(
|
|||
return { fileType, exactType: typeParts[1] };
|
||||
} catch (e) {
|
||||
const fileFormat = getFileExtension(receivedFile.name);
|
||||
const formatMissedByTypeDetection = FORMAT_MISSED_BY_FILE_TYPE_LIB.find(
|
||||
(a) => a.exactType === fileFormat
|
||||
);
|
||||
if (formatMissedByTypeDetection) {
|
||||
return formatMissedByTypeDetection;
|
||||
}
|
||||
logError(e, CustomError.TYPE_DETECTION_FAILED, {
|
||||
fileType: fileFormat,
|
||||
});
|
||||
return { fileType: FILE_TYPE.OTHERS, exactType: fileFormat };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ class UIService {
|
|||
this.progressUpdater.setPercentComplete(percent);
|
||||
}
|
||||
|
||||
setFilenames(filenames: Map<number, string>) {
|
||||
this.progressUpdater.setFilenames(filenames);
|
||||
}
|
||||
|
||||
increaseFileUploaded() {
|
||||
this.filesUploaded++;
|
||||
this.updateProgressBarUI();
|
||||
|
@ -97,18 +101,16 @@ class UIService {
|
|||
return {
|
||||
cancel,
|
||||
onUploadProgress: (event) => {
|
||||
fileLocalID &&
|
||||
this.fileProgress.set(
|
||||
fileLocalID,
|
||||
Math.min(
|
||||
Math.round(
|
||||
percentPerPart * index +
|
||||
(percentPerPart * event.loaded) /
|
||||
event.total
|
||||
),
|
||||
98
|
||||
)
|
||||
);
|
||||
this.fileProgress.set(
|
||||
fileLocalID,
|
||||
Math.min(
|
||||
Math.round(
|
||||
percentPerPart * index +
|
||||
(percentPerPart * event.loaded) / event.total
|
||||
),
|
||||
98
|
||||
)
|
||||
);
|
||||
this.updateProgressBarUI();
|
||||
if (event.loaded === event.total) {
|
||||
clearTimeout(timeout);
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
} from 'constants/upload';
|
||||
import { ComlinkWorker } from 'utils/comlink';
|
||||
import { FILE_TYPE } from 'constants/file';
|
||||
import uiService from './uiService';
|
||||
|
||||
const MAX_CONCURRENT_UPLOADS = 4;
|
||||
const FILE_UPLOAD_COMPLETED = 100;
|
||||
|
@ -96,7 +97,19 @@ class UploadManager {
|
|||
);
|
||||
UIService.setUploadStage(UPLOAD_STAGES.START);
|
||||
const analysedMediaFiles =
|
||||
UploadService.clusterLivePhotoFiles(mediaFiles);
|
||||
mediaFiles.length > 1
|
||||
? UploadService.clusterLivePhotoFiles(mediaFiles)
|
||||
: mediaFiles;
|
||||
uiService.setFilenames(
|
||||
new Map<number, string>(
|
||||
mediaFiles.map(({ localID }) => [
|
||||
localID,
|
||||
UploadService.getFileMetadataAndFileTypeInfo(
|
||||
localID
|
||||
).metadata.title,
|
||||
])
|
||||
)
|
||||
);
|
||||
await this.uploadMediaFiles(analysedMediaFiles);
|
||||
}
|
||||
UIService.setUploadStage(UPLOAD_STAGES.FINISH);
|
||||
|
@ -174,6 +187,7 @@ class UploadManager {
|
|||
}
|
||||
|
||||
private async uploadMediaFiles(mediaFiles: FileWithCollection[]) {
|
||||
this.filesToBeUploaded.push(...mediaFiles);
|
||||
UIService.reset(mediaFiles.length);
|
||||
|
||||
await UploadService.setFileCount(mediaFiles.length);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { logError } from 'utils/sentry';
|
|||
import UploadHttpClient from './uploadHttpClient';
|
||||
import { getFileMetadata } from './fileService';
|
||||
import { getFileType } from './readFileService';
|
||||
import { CustomError, handleUploadError } from 'utils/error';
|
||||
import { handleUploadError } from 'utils/error';
|
||||
import {
|
||||
B64EncryptionResult,
|
||||
BackupedFile,
|
||||
|
@ -22,8 +22,6 @@ import {
|
|||
UploadFile,
|
||||
UploadURL,
|
||||
} from 'types/upload';
|
||||
import { FILE_TYPE } from 'constants/file';
|
||||
import { FORMAT_MISSED_BY_FILE_TYPE_LIB } from 'constants/upload';
|
||||
import {
|
||||
clusterLivePhotoFiles,
|
||||
getLivePhotoSize,
|
||||
|
@ -71,25 +69,9 @@ class UploadService {
|
|||
}
|
||||
|
||||
async getFileType(reader: FileReader, file: File) {
|
||||
const fileTypeInfo = await getFileType(reader, file);
|
||||
if (fileTypeInfo.fileType !== FILE_TYPE.OTHERS) {
|
||||
return fileTypeInfo;
|
||||
}
|
||||
try {
|
||||
const formatMissedByTypeDetection =
|
||||
FORMAT_MISSED_BY_FILE_TYPE_LIB.find(
|
||||
(a) => a.exactType === fileTypeInfo.exactType
|
||||
);
|
||||
if (formatMissedByTypeDetection) {
|
||||
return formatMissedByTypeDetection;
|
||||
}
|
||||
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
|
||||
} catch (e) {
|
||||
logError(e, CustomError.TYPE_DETECTION_FAILED, {
|
||||
fileType: fileTypeInfo.exactType,
|
||||
});
|
||||
}
|
||||
return getFileType(reader, file);
|
||||
}
|
||||
|
||||
async readAsset(
|
||||
worker: any,
|
||||
reader: FileReader,
|
||||
|
@ -106,7 +88,12 @@ class UploadService {
|
|||
collectionID: number,
|
||||
fileTypeInfo: FileTypeInfo
|
||||
): Promise<Metadata> {
|
||||
return getFileMetadata(file, collectionID, fileTypeInfo);
|
||||
return getFileMetadata(
|
||||
this.parsedMetadataJSONMap,
|
||||
file,
|
||||
collectionID,
|
||||
fileTypeInfo
|
||||
);
|
||||
}
|
||||
|
||||
getFileMetadataAndFileTypeInfo(localID: number) {
|
||||
|
|
|
@ -37,14 +37,6 @@ export default async function uploader(
|
|||
throw Error(CustomError.NO_METADATA);
|
||||
}
|
||||
|
||||
// fileTypeInfo = await UploadService.getAssetType(worker, uploadAsset);
|
||||
|
||||
// metadata = await UploadService.getAssetMetadata(
|
||||
// uploadAsset,
|
||||
// collection,
|
||||
// fileTypeInfo
|
||||
// );
|
||||
|
||||
if (fileAlreadyInCollection(existingFilesInCollection, metadata)) {
|
||||
return { fileUploadResult: FileUploadResults.ALREADY_UPLOADED };
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ export interface ProgressUpdater {
|
|||
setUploadStage: React.Dispatch<React.SetStateAction<UPLOAD_STAGES>>;
|
||||
setFileProgress: React.Dispatch<React.SetStateAction<Map<number, number>>>;
|
||||
setUploadResult: React.Dispatch<React.SetStateAction<Map<number, number>>>;
|
||||
setFilenames: React.Dispatch<React.SetStateAction<Map<number, string>>>;
|
||||
}
|
||||
|
||||
export interface UploadAsset {
|
||||
|
@ -78,7 +79,6 @@ export interface FileWithCollection extends UploadAsset {
|
|||
collection?: Collection;
|
||||
collectionID?: number;
|
||||
}
|
||||
export type MetadataMap = Map<string, ParsedMetadataJSON>;
|
||||
export interface MetadataAndFileTypeInfo {
|
||||
metadata: Metadata;
|
||||
fileTypeInfo: FileTypeInfo;
|
||||
|
|
Loading…
Reference in a new issue