add support to show conversion failed message
This commit is contained in:
parent
4e7bd830f1
commit
67eabd5d02
|
@ -80,6 +80,7 @@ const PhotoFrame = ({
|
|||
const [isShiftKeyPressed, setIsShiftKeyPressed] = useState(false);
|
||||
const router = useRouter();
|
||||
const [isSourceLoaded, setIsSourceLoaded] = useState(false);
|
||||
const [conversionFailed, setConversionFailed] = useState(false);
|
||||
|
||||
const displayFiles = useMemoSingleThreaded(() => {
|
||||
return files.map((item) => {
|
||||
|
@ -196,7 +197,8 @@ const PhotoFrame = ({
|
|||
const updateSrcURL = async (
|
||||
index: number,
|
||||
id: number,
|
||||
mergedSrcURL: MergedSourceURL
|
||||
mergedSrcURL: MergedSourceURL,
|
||||
conversionFailed: boolean
|
||||
) => {
|
||||
const file = displayFiles[index];
|
||||
// this is to prevent outdate updateSrcURL call from updating the wrong file
|
||||
|
@ -217,6 +219,21 @@ const PhotoFrame = ({
|
|||
'PhotoSwipe updateSrcURL called when source already loaded'
|
||||
);
|
||||
return;
|
||||
} else if (file.conversionFailed) {
|
||||
addLogLine(
|
||||
`PhotoSwipe: updateSrcURL: conversion failed: ${file.id}`
|
||||
);
|
||||
logError(
|
||||
new Error(
|
||||
`PhotoSwipe: updateSrcURL: conversion failed: ${file.id}`
|
||||
),
|
||||
'PhotoSwipe updateSrcURL called when conversion failed'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (conversionFailed) {
|
||||
setConversionFailed(true);
|
||||
return;
|
||||
}
|
||||
await updateFileSrcProps(file, mergedSrcURL);
|
||||
setIsSourceLoaded(true);
|
||||
|
@ -406,18 +423,28 @@ const PhotoFrame = ({
|
|||
logError(e, 'getSlideData failed get msrc url failed');
|
||||
}
|
||||
}
|
||||
|
||||
if (item.isSourceLoaded) {
|
||||
setIsSourceLoaded(true);
|
||||
addLogLine(`[${item.id}] source already loaded`);
|
||||
return;
|
||||
}
|
||||
if (item.conversionFailed) {
|
||||
setConversionFailed(true);
|
||||
addLogLine(`[${item.id}] conversion failed`);
|
||||
return;
|
||||
}
|
||||
if (fetching[item.id]) {
|
||||
addLogLine(`[${item.id}] file download already in progress`);
|
||||
return;
|
||||
}
|
||||
setIsSourceLoaded(false);
|
||||
setConversionFailed(false);
|
||||
try {
|
||||
addLogLine(`[${item.id}] new file src request`);
|
||||
fetching[item.id] = true;
|
||||
let srcURL: MergedSourceURL;
|
||||
let conversionFailed: boolean = false;
|
||||
if (galleryContext.files.has(item.id)) {
|
||||
addLogLine(
|
||||
`[${item.id}] gallery context cache hit, using cached file`
|
||||
|
@ -428,7 +455,10 @@ const PhotoFrame = ({
|
|||
`[${item.id}] gallery context cache miss, calling downloadManager to get file`
|
||||
);
|
||||
appContext.startLoading();
|
||||
let downloadedURL;
|
||||
let downloadedURL: {
|
||||
original: string[];
|
||||
converted: string[];
|
||||
};
|
||||
if (publicCollectionGalleryContext.accessedThroughSharedURL) {
|
||||
downloadedURL =
|
||||
await PublicCollectionDownloadManager.getFile(
|
||||
|
@ -441,15 +471,21 @@ const PhotoFrame = ({
|
|||
downloadedURL = await DownloadManager.getFile(item, true);
|
||||
}
|
||||
appContext.finishLoading();
|
||||
const mergedURL: MergedSourceURL = {
|
||||
original: downloadedURL.original.join(','),
|
||||
converted: downloadedURL.converted.join(','),
|
||||
};
|
||||
galleryContext.files.set(item.id, mergedURL);
|
||||
srcURL = mergedURL;
|
||||
if (
|
||||
downloadedURL.converted.filter((url) => !!url).length !==
|
||||
downloadedURL.converted.length
|
||||
) {
|
||||
conversionFailed = true;
|
||||
} else {
|
||||
const mergedURL: MergedSourceURL = {
|
||||
original: downloadedURL.original.join(','),
|
||||
converted: downloadedURL.converted.join(','),
|
||||
};
|
||||
galleryContext.files.set(item.id, mergedURL);
|
||||
srcURL = mergedURL;
|
||||
}
|
||||
}
|
||||
setIsSourceLoaded(false);
|
||||
await updateSrcURL(index, item.id, srcURL);
|
||||
await updateSrcURL(index, item.id, srcURL, conversionFailed);
|
||||
|
||||
try {
|
||||
addLogLine(
|
||||
|
@ -498,6 +534,7 @@ const PhotoFrame = ({
|
|||
isHiddenCollection={activeCollection === HIDDEN_SECTION}
|
||||
enableDownload={enableDownload}
|
||||
isSourceLoaded={isSourceLoaded}
|
||||
conversionFailed={conversionFailed}
|
||||
fileToCollectionsMap={fileToCollectionsMap}
|
||||
collectionNameMap={collectionNameMap}
|
||||
/>
|
||||
|
|
|
@ -42,6 +42,7 @@ import ChevronLeft from '@mui/icons-material/ChevronLeft';
|
|||
import { t } from 'i18next';
|
||||
import { getParsedExifData } from 'services/upload/exifService';
|
||||
import { getFileType } from 'services/typeDetectionService';
|
||||
import { ConversionFailedBtn } from './styledComponents/ConversionFailedBtn';
|
||||
|
||||
interface PhotoswipeFullscreenAPI {
|
||||
enter: () => void;
|
||||
|
@ -75,6 +76,7 @@ interface Iprops {
|
|||
isHiddenCollection: boolean;
|
||||
enableDownload: boolean;
|
||||
isSourceLoaded: boolean;
|
||||
conversionFailed: boolean;
|
||||
fileToCollectionsMap: Map<number, number[]>;
|
||||
collectionNameMap: Map<number, string>;
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ function PhotoViewer(props: Iprops) {
|
|||
const [photoSwipe, setPhotoSwipe] =
|
||||
useState<Photoswipe<Photoswipe.Options>>();
|
||||
|
||||
const { isOpen, items, isSourceLoaded } = props;
|
||||
const { isOpen, items, isSourceLoaded, conversionFailed } = props;
|
||||
const [isFav, setIsFav] = useState(false);
|
||||
const [showInfo, setShowInfo] = useState(false);
|
||||
const [exif, setExif] =
|
||||
|
@ -559,6 +561,16 @@ function PhotoViewer(props: Iprops) {
|
|||
{livePhotoBtnHTML} {t('LIVE')}
|
||||
</LivePhotoBtn>
|
||||
)}
|
||||
{conversionFailed && (
|
||||
<ConversionFailedBtn
|
||||
onClick={() =>
|
||||
downloadFileHelper(photoSwipe.currItem)
|
||||
}>
|
||||
{' '}
|
||||
DOWNLOAD{' '}
|
||||
</ConversionFailedBtn>
|
||||
)}
|
||||
|
||||
<div className="pswp__container">
|
||||
<div className="pswp__item" />
|
||||
<div className="pswp__item" />
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { styled } from '@mui/material';
|
||||
export const ConversionFailedBtn = styled('button')`
|
||||
position: absolute;
|
||||
bottom: 6vh;
|
||||
left: 6vh;
|
||||
height: 40px;
|
||||
width: 80px;
|
||||
background: #d7d7d7;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 10%;
|
||||
z-index: 10;
|
||||
cursor: ${(props) => (props.disabled ? 'not-allowed' : 'pointer')};
|
||||
}
|
||||
`;
|
|
@ -60,6 +60,7 @@ export interface EnteFile
|
|||
originalVideoURL?: string;
|
||||
originalImageURL?: string;
|
||||
dataIndex?: number;
|
||||
conversionFailed?: boolean;
|
||||
}
|
||||
|
||||
export interface TrashRequest {
|
||||
|
|
|
@ -286,14 +286,18 @@ export async function getRenderableFileURL(file: EnteFile, fileBlob: Blob) {
|
|||
fileBlob
|
||||
);
|
||||
return {
|
||||
converted: [URL.createObjectURL(convertedBlob)],
|
||||
converted: [
|
||||
convertedBlob ? URL.createObjectURL(convertedBlob) : null,
|
||||
],
|
||||
original: [URL.createObjectURL(fileBlob)],
|
||||
};
|
||||
}
|
||||
case FILE_TYPE.LIVE_PHOTO: {
|
||||
const livePhoto = await getRenderableLivePhoto(file, fileBlob);
|
||||
return {
|
||||
converted: livePhoto.map((asset) => URL.createObjectURL(asset)),
|
||||
converted: livePhoto.map((asset) =>
|
||||
asset ? URL.createObjectURL(asset) : null
|
||||
),
|
||||
original: [URL.createObjectURL(fileBlob)],
|
||||
};
|
||||
}
|
||||
|
@ -330,52 +334,54 @@ async function getPlayableVideo(videoNameTitle: string, video: Uint8Array) {
|
|||
}
|
||||
|
||||
export async function getRenderableImage(fileName: string, imageBlob: Blob) {
|
||||
const tempFile = new File([imageBlob], fileName);
|
||||
const { exactType } = await getFileType(tempFile);
|
||||
let convertedImageBlob: Blob;
|
||||
if (isRawFile(exactType)) {
|
||||
try {
|
||||
if (!isSupportedRawFormat(exactType)) {
|
||||
throw Error(CustomError.UNSUPPORTED_RAW_FORMAT);
|
||||
}
|
||||
|
||||
if (!isElectron()) {
|
||||
throw Error(CustomError.NOT_AVAILABLE_ON_WEB);
|
||||
}
|
||||
addLogLine(
|
||||
`RawConverter called for ${fileName}-${convertBytesToHumanReadable(
|
||||
imageBlob.size
|
||||
)}`
|
||||
);
|
||||
convertedImageBlob = await imageProcessor.convertToJPEG(
|
||||
imageBlob,
|
||||
fileName
|
||||
);
|
||||
addLogLine(`${fileName} successfully converted`);
|
||||
} catch (e) {
|
||||
try {
|
||||
const tempFile = new File([imageBlob], fileName);
|
||||
const { exactType } = await getFileType(tempFile);
|
||||
let convertedImageBlob: Blob;
|
||||
if (isRawFile(exactType)) {
|
||||
try {
|
||||
if (!isFileHEIC(exactType)) {
|
||||
throw e;
|
||||
if (!isSupportedRawFormat(exactType)) {
|
||||
throw Error(CustomError.UNSUPPORTED_RAW_FORMAT);
|
||||
}
|
||||
|
||||
if (!isElectron()) {
|
||||
throw Error(CustomError.NOT_AVAILABLE_ON_WEB);
|
||||
}
|
||||
addLogLine(
|
||||
`HEICConverter called for ${fileName}-${convertBytesToHumanReadable(
|
||||
`RawConverter called for ${fileName}-${convertBytesToHumanReadable(
|
||||
imageBlob.size
|
||||
)}`
|
||||
);
|
||||
convertedImageBlob = await heicConversionService.convert(
|
||||
imageBlob
|
||||
convertedImageBlob = await imageProcessor.convertToJPEG(
|
||||
imageBlob,
|
||||
fileName
|
||||
);
|
||||
addLogLine(`${fileName} successfully converted`);
|
||||
} catch (e) {
|
||||
logError(e, 'get Renderable Image failed', {
|
||||
fileType: exactType,
|
||||
});
|
||||
throw Error(CustomError.NON_PREVIEWABLE_FILE);
|
||||
try {
|
||||
if (!isFileHEIC(exactType)) {
|
||||
throw e;
|
||||
}
|
||||
addLogLine(
|
||||
`HEICConverter called for ${fileName}-${convertBytesToHumanReadable(
|
||||
imageBlob.size
|
||||
)}`
|
||||
);
|
||||
convertedImageBlob = await heicConversionService.convert(
|
||||
imageBlob
|
||||
);
|
||||
addLogLine(`${fileName} successfully converted`);
|
||||
} catch (e) {
|
||||
throw Error(CustomError.NON_PREVIEWABLE_FILE);
|
||||
}
|
||||
}
|
||||
return convertedImageBlob;
|
||||
} else {
|
||||
return imageBlob;
|
||||
}
|
||||
return convertedImageBlob;
|
||||
} else {
|
||||
return imageBlob;
|
||||
} catch (e) {
|
||||
logError(e, 'get Renderable Image failed');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue