commit
b8cde01eb6
|
@ -51,3 +51,8 @@ If you would like to motivate us to keep building, you can do so by [starring](h
|
|||
Follow us on [Twitter](https://twitter.com/enteio) and join [r/enteio](https://reddit.com/r/enteio) to get regular updates, connect with other customers, and discuss your ideas.
|
||||
|
||||
An important part of our journey is to build better software by consistently listening to community feedback. Please feel free to [share your thoughts](mailto:feedback@ente.io) with us at any time.
|
||||
|
||||
---
|
||||
|
||||
Cross-browser testing provided by
|
||||
[<img src="https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780" width="115" height="25">](https://www.browserstack.com/open-source)
|
||||
|
|
|
@ -4,9 +4,9 @@ import { Location, ParsedExtractedMetadata } from 'types/upload';
|
|||
|
||||
// list of format that were missed by type-detection for some files.
|
||||
export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [
|
||||
{ fileType: FILE_TYPE.IMAGE, exactType: 'jpeg' },
|
||||
{ fileType: FILE_TYPE.IMAGE, exactType: 'jpg' },
|
||||
{ fileType: FILE_TYPE.VIDEO, exactType: 'webm' },
|
||||
{ fileType: FILE_TYPE.IMAGE, exactType: 'jpeg', mimeType: 'image/jpeg' },
|
||||
{ fileType: FILE_TYPE.IMAGE, exactType: 'jpg', mimeType: 'image/jpeg' },
|
||||
{ fileType: FILE_TYPE.VIDEO, exactType: 'webm', mimeType: 'video/webm' },
|
||||
];
|
||||
|
||||
// this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part.
|
||||
|
|
|
@ -32,7 +32,11 @@ export async function getFileType(
|
|||
default:
|
||||
fileType = FILE_TYPE.OTHERS;
|
||||
}
|
||||
return { fileType, exactType: typeResult.ext };
|
||||
return {
|
||||
fileType,
|
||||
exactType: typeResult.ext,
|
||||
mimeType: typeResult.mime,
|
||||
};
|
||||
} catch (e) {
|
||||
const fileFormat = getFileExtension(receivedFile.name);
|
||||
const formatMissedByTypeDetection = FORMAT_MISSED_BY_FILE_TYPE_LIB.find(
|
||||
|
@ -44,7 +48,11 @@ export async function getFileType(
|
|||
logError(e, CustomError.TYPE_DETECTION_FAILED, {
|
||||
fileFormat,
|
||||
});
|
||||
return { fileType: FILE_TYPE.OTHERS, exactType: fileFormat };
|
||||
return {
|
||||
fileType: FILE_TYPE.OTHERS,
|
||||
exactType: fileFormat,
|
||||
mimeType: receivedFile.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +61,7 @@ async function extractFileType(reader: FileReader, file: File) {
|
|||
return getFileTypeFromBlob(reader, fileChunkBlob);
|
||||
}
|
||||
|
||||
export async function getFileTypeFromBlob(reader: FileReader, fileBlob: Blob) {
|
||||
async function getFileTypeFromBlob(reader: FileReader, fileBlob: Blob) {
|
||||
try {
|
||||
const initialFiledata = await getUint8ArrayView(reader, fileBlob);
|
||||
return await FileType.fromBuffer(initialFiledata);
|
||||
|
|
|
@ -74,7 +74,7 @@ export async function updateFileCreationDateInEXIF(
|
|||
}
|
||||
}
|
||||
|
||||
export async function convertImageToDataURL(reader: FileReader, url: string) {
|
||||
async function convertImageToDataURL(reader: FileReader, url: string) {
|
||||
const blob = await fetch(url).then((r) => r.blob());
|
||||
const dataURL = await new Promise<string>((resolve) => {
|
||||
reader.onload = () => resolve(reader.result as string);
|
||||
|
|
|
@ -48,6 +48,7 @@ export interface MultipartUploadURLs {
|
|||
export interface FileTypeInfo {
|
||||
fileType: FILE_TYPE;
|
||||
exactType: string;
|
||||
mimeType?: string;
|
||||
imageType?: string;
|
||||
videoType?: string;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
PublicMagicMetadataProps,
|
||||
} from 'types/file';
|
||||
import { decodeMotionPhoto } from 'services/motionPhotoService';
|
||||
import { getFileTypeFromBlob } from 'services/typeDetectionService';
|
||||
import { getFileType } from 'services/typeDetectionService';
|
||||
import DownloadManager from 'services/downloadManager';
|
||||
import { logError } from 'utils/sentry';
|
||||
import { User } from 'types/user';
|
||||
|
@ -25,7 +25,6 @@ import {
|
|||
import PublicCollectionDownloadManager from 'services/publicCollectionDownloadManager';
|
||||
import HEICConverter from 'services/heicConverter/heicConverterService';
|
||||
import ffmpegService from 'services/ffmpeg/ffmpegService';
|
||||
|
||||
export function downloadAsFile(filename: string, content: string) {
|
||||
const file = new Blob([content], {
|
||||
type: 'text/plain',
|
||||
|
@ -48,76 +47,80 @@ export async function downloadFile(
|
|||
token?: string,
|
||||
passwordToken?: string
|
||||
) {
|
||||
let fileURL: string;
|
||||
let tempURL: string;
|
||||
let fileBlob: Blob;
|
||||
const fileReader = new FileReader();
|
||||
if (accessedThroughSharedURL) {
|
||||
fileURL = await PublicCollectionDownloadManager.getCachedOriginalFile(
|
||||
file
|
||||
)[0];
|
||||
tempURL;
|
||||
const fileURL =
|
||||
await PublicCollectionDownloadManager.getCachedOriginalFile(
|
||||
file
|
||||
)[0];
|
||||
if (!fileURL) {
|
||||
tempURL = URL.createObjectURL(
|
||||
await new Response(
|
||||
await PublicCollectionDownloadManager.downloadFile(
|
||||
token,
|
||||
passwordToken,
|
||||
file
|
||||
)
|
||||
).blob()
|
||||
);
|
||||
console.log({ tempURL });
|
||||
fileURL = tempURL;
|
||||
fileBlob = await new Response(
|
||||
await PublicCollectionDownloadManager.downloadFile(
|
||||
token,
|
||||
passwordToken,
|
||||
file
|
||||
)
|
||||
).blob();
|
||||
} else {
|
||||
fileBlob = await (await fetch(fileURL)).blob();
|
||||
}
|
||||
} else {
|
||||
fileURL = await DownloadManager.getCachedOriginalFile(file)[0];
|
||||
const fileURL = await DownloadManager.getCachedOriginalFile(file)[0];
|
||||
if (!fileURL) {
|
||||
tempURL = URL.createObjectURL(
|
||||
await new Response(
|
||||
await DownloadManager.downloadFile(file)
|
||||
).blob()
|
||||
);
|
||||
fileURL = tempURL;
|
||||
fileBlob = await new Response(
|
||||
await DownloadManager.downloadFile(file)
|
||||
).blob();
|
||||
} else {
|
||||
fileBlob = await (await fetch(fileURL)).blob();
|
||||
}
|
||||
}
|
||||
|
||||
const fileType = getFileExtension(file.metadata.title);
|
||||
let tempEditedFileURL: string;
|
||||
const fileType = await getFileType(
|
||||
fileReader,
|
||||
new File([fileBlob], file.metadata.title)
|
||||
);
|
||||
if (
|
||||
file.pubMagicMetadata?.data.editedTime &&
|
||||
(fileType === TYPE_JPEG || fileType === TYPE_JPG)
|
||||
(fileType.exactType === TYPE_JPEG || fileType.exactType === TYPE_JPG)
|
||||
) {
|
||||
let fileBlob = await (await fetch(fileURL)).blob();
|
||||
|
||||
fileBlob = await updateFileCreationDateInEXIF(
|
||||
new FileReader(),
|
||||
fileReader,
|
||||
fileBlob,
|
||||
new Date(file.pubMagicMetadata.data.editedTime / 1000)
|
||||
);
|
||||
tempEditedFileURL = URL.createObjectURL(fileBlob);
|
||||
fileURL = tempEditedFileURL;
|
||||
}
|
||||
let tempImageURL: string;
|
||||
let tempVideoURL: string;
|
||||
let tempURL: string;
|
||||
|
||||
if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
|
||||
const fileBlob = await (await fetch(fileURL)).blob();
|
||||
const originalName = fileNameWithoutExtension(file.metadata.title);
|
||||
const motionPhoto = await decodeMotionPhoto(fileBlob, originalName);
|
||||
tempImageURL = URL.createObjectURL(new Blob([motionPhoto.image]));
|
||||
tempVideoURL = URL.createObjectURL(new Blob([motionPhoto.video]));
|
||||
downloadUsingAnchor(motionPhoto.imageNameTitle, tempImageURL);
|
||||
downloadUsingAnchor(motionPhoto.videoNameTitle, tempVideoURL);
|
||||
const image = new File([motionPhoto.image], motionPhoto.imageNameTitle);
|
||||
const imageType = await getFileType(fileReader, image);
|
||||
tempImageURL = URL.createObjectURL(
|
||||
new Blob([motionPhoto.image], { type: imageType.mimeType })
|
||||
);
|
||||
const video = new File([motionPhoto.video], motionPhoto.videoNameTitle);
|
||||
const videoType = await getFileType(fileReader, video);
|
||||
tempVideoURL = URL.createObjectURL(
|
||||
new Blob([motionPhoto.video], { type: videoType.mimeType })
|
||||
);
|
||||
downloadUsingAnchor(tempImageURL, motionPhoto.imageNameTitle);
|
||||
downloadUsingAnchor(tempVideoURL, motionPhoto.videoNameTitle);
|
||||
} else {
|
||||
downloadUsingAnchor(file.metadata.title, fileURL);
|
||||
fileBlob = new Blob([fileBlob], { type: fileType.mimeType });
|
||||
tempURL = URL.createObjectURL(fileBlob);
|
||||
downloadUsingAnchor(tempURL, file.metadata.title);
|
||||
}
|
||||
|
||||
tempURL && URL.revokeObjectURL(tempURL);
|
||||
tempEditedFileURL && URL.revokeObjectURL(tempEditedFileURL);
|
||||
tempImageURL && URL.revokeObjectURL(tempImageURL);
|
||||
tempVideoURL && URL.revokeObjectURL(tempVideoURL);
|
||||
}
|
||||
|
||||
function downloadUsingAnchor(name: string, link: string) {
|
||||
function downloadUsingAnchor(link: string, name: string) {
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = link;
|
||||
|
@ -335,11 +338,10 @@ export async function convertForPreview(
|
|||
fileBlob: Blob
|
||||
): Promise<Blob[]> {
|
||||
const convertIfHEIC = async (fileName: string, fileBlob: Blob) => {
|
||||
const typeFromExtension = getFileExtension(fileName);
|
||||
const reader = new FileReader();
|
||||
const mimeType =
|
||||
(await getFileTypeFromBlob(reader, fileBlob))?.mime ??
|
||||
typeFromExtension;
|
||||
const mimeType = (
|
||||
await getFileType(reader, new File([fileBlob], file.metadata.title))
|
||||
).exactType;
|
||||
if (isFileHEIC(mimeType)) {
|
||||
fileBlob = await HEICConverter.convert(fileBlob);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue