Merge branch 'main' into fix-dev-server-crash
This commit is contained in:
commit
b433b37e08
|
@ -72,8 +72,10 @@ interface Props {
|
|||
}
|
||||
|
||||
type SourceURL = {
|
||||
imageURL?: string;
|
||||
videoURL?: string;
|
||||
originalImageURL?: string;
|
||||
originalVideoURL?: string;
|
||||
convertedImageURL?: string;
|
||||
convertedVideoURL?: string;
|
||||
};
|
||||
|
||||
const PhotoFrame = ({
|
||||
|
@ -199,9 +201,16 @@ const PhotoFrame = ({
|
|||
}, [files]);
|
||||
|
||||
const collectionNameMap = useMemo(() => {
|
||||
return new Map<number, string>(
|
||||
collections.map((collection) => [collection.id, collection.name])
|
||||
);
|
||||
if (collections) {
|
||||
return new Map<number, string>(
|
||||
collections.map((collection) => [
|
||||
collection.id,
|
||||
collection.name,
|
||||
])
|
||||
);
|
||||
} else {
|
||||
return new Map();
|
||||
}
|
||||
}, [collections]);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -320,17 +329,25 @@ const PhotoFrame = ({
|
|||
};
|
||||
|
||||
const updateSrcURL = async (id: number, srcURL: SourceURL) => {
|
||||
const { videoURL, imageURL } = srcURL;
|
||||
const isPlayable = videoURL && (await isPlaybackPossible(videoURL));
|
||||
const {
|
||||
originalImageURL,
|
||||
convertedImageURL,
|
||||
originalVideoURL,
|
||||
convertedVideoURL,
|
||||
} = srcURL;
|
||||
const isPlayable =
|
||||
convertedVideoURL && (await isPlaybackPossible(convertedVideoURL));
|
||||
const updateFile = (file: EnteFile) => {
|
||||
file.w = window.innerWidth;
|
||||
file.h = window.innerHeight;
|
||||
|
||||
file.isSourceLoaded = true;
|
||||
file.originalImageURL = originalImageURL;
|
||||
file.originalVideoURL = originalVideoURL;
|
||||
if (file.metadata.fileType === FILE_TYPE.VIDEO) {
|
||||
if (isPlayable) {
|
||||
file.html = `
|
||||
<video controls onContextMenu="return false;">
|
||||
<source src="${videoURL}" />
|
||||
<source src="${convertedVideoURL}" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
`;
|
||||
|
@ -340,7 +357,7 @@ const PhotoFrame = ({
|
|||
<img src="${file.msrc}" onContextMenu="return false;"/>
|
||||
<div class="download-banner" >
|
||||
${constants.VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD}
|
||||
<a class="btn btn-outline-success" href=${videoURL} download="${file.metadata.title}"">Download</a>
|
||||
<a class="btn btn-outline-success" href=${convertedVideoURL} download="${file.metadata.title}"">Download</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -349,9 +366,9 @@ const PhotoFrame = ({
|
|||
if (isPlayable) {
|
||||
file.html = `
|
||||
<div class = 'pswp-item-container'>
|
||||
<img id = "live-photo-image-${file.id}" src="${imageURL}" onContextMenu="return false;"/>
|
||||
<img id = "live-photo-image-${file.id}" src="${convertedImageURL}" onContextMenu="return false;"/>
|
||||
<video id = "live-photo-video-${file.id}" loop muted onContextMenu="return false;">
|
||||
<source src="${videoURL}" />
|
||||
<source src="${convertedVideoURL}" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
|
@ -368,7 +385,7 @@ const PhotoFrame = ({
|
|||
`;
|
||||
}
|
||||
} else {
|
||||
file.src = imageURL;
|
||||
file.src = convertedImageURL;
|
||||
}
|
||||
return file;
|
||||
};
|
||||
|
@ -500,6 +517,9 @@ const PhotoFrame = ({
|
|||
item.msrc = newFile.msrc;
|
||||
item.html = newFile.html;
|
||||
item.src = newFile.src;
|
||||
item.isSourceLoaded = newFile.isSourceLoaded;
|
||||
item.originalImageURL = newFile.originalImageURL;
|
||||
item.originalVideoURL = newFile.originalVideoURL;
|
||||
item.w = newFile.w;
|
||||
item.h = newFile.h;
|
||||
|
||||
|
@ -522,10 +542,13 @@ const PhotoFrame = ({
|
|||
if (!fetching[item.id]) {
|
||||
try {
|
||||
fetching[item.id] = true;
|
||||
let urls: string[];
|
||||
let urls: { original: string[]; converted: string[] };
|
||||
if (galleryContext.files.has(item.id)) {
|
||||
const mergedURL = galleryContext.files.get(item.id);
|
||||
urls = mergedURL.split(',');
|
||||
urls = {
|
||||
original: mergedURL.original.split(','),
|
||||
converted: mergedURL.converted.split(','),
|
||||
};
|
||||
} else {
|
||||
appContext.startLoading();
|
||||
if (
|
||||
|
@ -541,26 +564,39 @@ const PhotoFrame = ({
|
|||
urls = await DownloadManager.getFile(item, true);
|
||||
}
|
||||
appContext.finishLoading();
|
||||
const mergedURL = urls.join(',');
|
||||
const mergedURL = {
|
||||
original: urls.original.join(','),
|
||||
converted: urls.converted.join(','),
|
||||
};
|
||||
galleryContext.files.set(item.id, mergedURL);
|
||||
}
|
||||
let imageURL;
|
||||
let videoURL;
|
||||
let originalImageURL;
|
||||
let originalVideoURL;
|
||||
let convertedImageURL;
|
||||
let convertedVideoURL;
|
||||
|
||||
if (item.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
|
||||
[imageURL, videoURL] = urls;
|
||||
[originalImageURL, originalVideoURL] = urls.converted;
|
||||
} else if (item.metadata.fileType === FILE_TYPE.VIDEO) {
|
||||
[videoURL] = urls;
|
||||
[originalVideoURL] = urls.original;
|
||||
[convertedVideoURL] = urls.converted;
|
||||
} else {
|
||||
[imageURL] = urls;
|
||||
[originalImageURL] = urls.original;
|
||||
[convertedImageURL] = urls.converted;
|
||||
}
|
||||
setIsSourceLoaded(false);
|
||||
const newFile = await updateSrcURL(item.id, {
|
||||
imageURL,
|
||||
videoURL,
|
||||
originalImageURL,
|
||||
originalVideoURL,
|
||||
convertedImageURL,
|
||||
convertedVideoURL,
|
||||
});
|
||||
item.msrc = newFile.msrc;
|
||||
item.html = newFile.html;
|
||||
item.src = newFile.src;
|
||||
item.isSourceLoaded = newFile.isSourceLoaded;
|
||||
item.originalImageURL = newFile.originalImageURL;
|
||||
item.originalVideoURL = newFile.originalVideoURL;
|
||||
item.w = newFile.w;
|
||||
item.h = newFile.h;
|
||||
try {
|
||||
|
|
|
@ -44,6 +44,7 @@ interface Iprops {
|
|||
refreshPhotoswipe: () => void;
|
||||
fileToCollectionsMap: Map<number, number[]>;
|
||||
collectionNameMap: Map<number, string>;
|
||||
isTrashCollection: boolean;
|
||||
}
|
||||
|
||||
function BasicDeviceCamera({
|
||||
|
@ -77,6 +78,7 @@ export function FileInfo({
|
|||
refreshPhotoswipe,
|
||||
fileToCollectionsMap,
|
||||
collectionNameMap,
|
||||
isTrashCollection,
|
||||
}: Iprops) {
|
||||
const [location, setLocation] = useState<Location>(null);
|
||||
const [parsedExifData, setParsedExifData] = useState<Record<string, any>>();
|
||||
|
@ -107,6 +109,7 @@ export function FileInfo({
|
|||
|
||||
useEffect(() => {
|
||||
if (!exif) {
|
||||
setParsedExifData({});
|
||||
return;
|
||||
}
|
||||
const parsedExifData = {};
|
||||
|
@ -188,33 +191,33 @@ export function FileInfo({
|
|||
/>
|
||||
)}
|
||||
|
||||
{/* {location && ( */}
|
||||
<InfoItem
|
||||
icon={<LocationOnOutlined />}
|
||||
title={constants.LOCATION}
|
||||
caption={
|
||||
<Link
|
||||
href={getOpenStreetMapLink({
|
||||
latitude: file.metadata.latitude,
|
||||
longitude: file.metadata.longitude,
|
||||
})}
|
||||
target="_blank"
|
||||
sx={{ fontWeight: 'bold' }}>
|
||||
{constants.SHOW_ON_MAP}
|
||||
</Link>
|
||||
}
|
||||
customEndButton={
|
||||
<CopyButton
|
||||
code={getOpenStreetMapLink({
|
||||
latitude: file.metadata.latitude,
|
||||
longitude: file.metadata.longitude,
|
||||
})}
|
||||
color="secondary"
|
||||
size="medium"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{/* )} */}
|
||||
{location && (
|
||||
<InfoItem
|
||||
icon={<LocationOnOutlined />}
|
||||
title={constants.LOCATION}
|
||||
caption={
|
||||
<Link
|
||||
href={getOpenStreetMapLink({
|
||||
latitude: file.metadata.latitude,
|
||||
longitude: file.metadata.longitude,
|
||||
})}
|
||||
target="_blank"
|
||||
sx={{ fontWeight: 'bold' }}>
|
||||
{constants.SHOW_ON_MAP}
|
||||
</Link>
|
||||
}
|
||||
customEndButton={
|
||||
<CopyButton
|
||||
code={getOpenStreetMapLink({
|
||||
latitude: file.metadata.latitude,
|
||||
longitude: file.metadata.longitude,
|
||||
})}
|
||||
color="secondary"
|
||||
size="medium"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<InfoItem
|
||||
icon={<TextSnippetOutlined />}
|
||||
title={constants.DETAILS}
|
||||
|
@ -243,23 +246,27 @@ export function FileInfo({
|
|||
caption={formatTime(file.metadata.modificationTime / 1000)}
|
||||
hideEditOption
|
||||
/>
|
||||
|
||||
<InfoItem icon={<FolderOutlined />} hideEditOption>
|
||||
<Box
|
||||
display={'flex'}
|
||||
gap={1}
|
||||
flexWrap="wrap"
|
||||
justifyContent={'flex-start'}
|
||||
alignItems={'flex-start'}>
|
||||
{fileToCollectionsMap
|
||||
.get(file.id)
|
||||
?.map((collectionID) => (
|
||||
<Chip key={collectionID}>
|
||||
{collectionNameMap.get(collectionID)}
|
||||
</Chip>
|
||||
))}
|
||||
</Box>
|
||||
</InfoItem>
|
||||
{!isTrashCollection && (
|
||||
<InfoItem icon={<FolderOutlined />} hideEditOption>
|
||||
<Box
|
||||
display={'flex'}
|
||||
gap={1}
|
||||
flexWrap="wrap"
|
||||
justifyContent={'flex-start'}
|
||||
alignItems={'flex-start'}>
|
||||
{fileToCollectionsMap
|
||||
.get(file.id)
|
||||
?.filter((collectionID) =>
|
||||
collectionNameMap.has(collectionID)
|
||||
)
|
||||
?.map((collectionID) => (
|
||||
<Chip key={collectionID}>
|
||||
{collectionNameMap.get(collectionID)}
|
||||
</Chip>
|
||||
))}
|
||||
</Box>
|
||||
</InfoItem>
|
||||
)}
|
||||
</Stack>
|
||||
<ExifData
|
||||
exif={exif}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { livePhotoBtnHTML } from 'components/LivePhotoBtn';
|
|||
import { logError } from 'utils/sentry';
|
||||
|
||||
import { FILE_TYPE } from 'constants/file';
|
||||
import { isClipboardItemPresent, sleep } from 'utils/common';
|
||||
import { isClipboardItemPresent } from 'utils/common';
|
||||
import { playVideo, pauseVideo } from 'utils/photoFrame';
|
||||
import { PublicCollectionGalleryContext } from 'utils/publicCollectionGallery';
|
||||
import { AppContext } from 'pages/_app';
|
||||
|
@ -79,7 +79,9 @@ function PhotoViewer(props: Iprops) {
|
|||
const { isOpen, items, isSourceLoaded } = props;
|
||||
const [isFav, setIsFav] = useState(false);
|
||||
const [showInfo, setShowInfo] = useState(false);
|
||||
const [exif, setExif] = useState<any>(null);
|
||||
const [exif, setExif] =
|
||||
useState<{ key: string; value: Record<string, any> }>();
|
||||
const exifCopy = useRef(null);
|
||||
const [livePhotoBtnOptions, setLivePhotoBtnOptions] = useState(
|
||||
defaultLivePhotoDefaultOptions
|
||||
);
|
||||
|
@ -89,6 +91,7 @@ function PhotoViewer(props: Iprops) {
|
|||
);
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const exifExtractionInProgress = useRef<string>(null);
|
||||
const [shouldShowCopyOption] = useState(isClipboardItemPresent());
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -235,8 +238,12 @@ function PhotoViewer(props: Iprops) {
|
|||
}
|
||||
}, [photoSwipe?.currItem, isOpen, isSourceLoaded]);
|
||||
|
||||
function updateFavButton() {
|
||||
setIsFav(isInFav(this?.currItem));
|
||||
useEffect(() => {
|
||||
exifCopy.current = exif;
|
||||
}, [exif]);
|
||||
|
||||
function updateFavButton(file: EnteFile) {
|
||||
setIsFav(isInFav(file));
|
||||
}
|
||||
|
||||
const openPhotoSwipe = () => {
|
||||
|
@ -298,11 +305,31 @@ function PhotoViewer(props: Iprops) {
|
|||
});
|
||||
}
|
||||
});
|
||||
photoSwipe.listen('beforeChange', function () {
|
||||
updateInfo.call(this);
|
||||
updateFavButton.call(this);
|
||||
photoSwipe.listen('beforeChange', () => {
|
||||
const currItem = photoSwipe?.currItem as EnteFile;
|
||||
if (
|
||||
!currItem ||
|
||||
!exifCopy?.current?.value === null ||
|
||||
exifCopy?.current?.key === currItem.src
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setExif({ key: currItem.src, value: undefined });
|
||||
checkExifAvailable(currItem);
|
||||
updateFavButton(currItem);
|
||||
});
|
||||
photoSwipe.listen('resize', () => {
|
||||
const currItem = photoSwipe?.currItem as EnteFile;
|
||||
if (
|
||||
!currItem ||
|
||||
!exifCopy?.current?.value === null ||
|
||||
exifCopy?.current?.key === currItem.src
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setExif({ key: currItem.src, value: undefined });
|
||||
checkExifAvailable(currItem);
|
||||
});
|
||||
photoSwipe.listen('resize', checkExifAvailable);
|
||||
photoSwipe.init();
|
||||
needUpdate.current = false;
|
||||
setPhotoSwipe(photoSwipe);
|
||||
|
@ -323,7 +350,7 @@ function PhotoViewer(props: Iprops) {
|
|||
}
|
||||
handleCloseInfo();
|
||||
};
|
||||
const isInFav = (file) => {
|
||||
const isInFav = (file: EnteFile) => {
|
||||
const { favItemIds } = props;
|
||||
if (favItemIds && file) {
|
||||
return favItemIds.has(file.id);
|
||||
|
@ -331,7 +358,7 @@ function PhotoViewer(props: Iprops) {
|
|||
return false;
|
||||
};
|
||||
|
||||
const onFavClick = async (file) => {
|
||||
const onFavClick = async (file: EnteFile) => {
|
||||
const { favItemIds } = props;
|
||||
if (!isInFav(file)) {
|
||||
favItemIds.add(file.id);
|
||||
|
@ -386,33 +413,37 @@ function PhotoViewer(props: Iprops) {
|
|||
}
|
||||
};
|
||||
|
||||
const checkExifAvailable = async () => {
|
||||
await sleep(100);
|
||||
const checkExifAvailable = async (file: EnteFile) => {
|
||||
try {
|
||||
const img: HTMLImageElement = document.querySelector(
|
||||
'.pswp__img:not(.pswp__img--placeholder)'
|
||||
);
|
||||
if (img) {
|
||||
const exifData = await exifr.parse(img);
|
||||
if (exifData) {
|
||||
setExif(exifData);
|
||||
} else {
|
||||
setExif(null);
|
||||
if (exifExtractionInProgress.current === file.src) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (file.isSourceLoaded) {
|
||||
exifExtractionInProgress.current = file.src;
|
||||
const imageBlob = await (
|
||||
await fetch(file.originalImageURL)
|
||||
).blob();
|
||||
const exifData = (await exifr.parse(imageBlob)) as Record<
|
||||
string,
|
||||
any
|
||||
>;
|
||||
if (exifExtractionInProgress.current === file.src) {
|
||||
if (exifData) {
|
||||
setExif({ key: file.src, value: exifData });
|
||||
} else {
|
||||
setExif({ key: file.src, value: null });
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
exifExtractionInProgress.current = null;
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e, 'exifr parsing failed');
|
||||
}
|
||||
};
|
||||
|
||||
function updateInfo() {
|
||||
const file: EnteFile = this?.currItem;
|
||||
if (file) {
|
||||
setExif(undefined);
|
||||
checkExifAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
const handleCloseInfo = () => {
|
||||
setShowInfo(false);
|
||||
};
|
||||
|
@ -553,7 +584,9 @@ function PhotoViewer(props: Iprops) {
|
|||
}
|
||||
className="pswp__button pswp__button--custom"
|
||||
onClick={() => {
|
||||
onFavClick(photoSwipe?.currItem);
|
||||
onFavClick(
|
||||
photoSwipe?.currItem as EnteFile
|
||||
);
|
||||
}}>
|
||||
{isFav ? (
|
||||
<FavoriteIcon fontSize="small" />
|
||||
|
@ -591,11 +624,12 @@ function PhotoViewer(props: Iprops) {
|
|||
</div>
|
||||
</div>
|
||||
<FileInfo
|
||||
isTrashCollection={props.isTrashCollection}
|
||||
shouldDisableEdits={props.isSharedCollection}
|
||||
showInfo={showInfo}
|
||||
handleCloseInfo={handleCloseInfo}
|
||||
file={photoSwipe?.currItem as EnteFile}
|
||||
exif={exif}
|
||||
exif={exif?.value}
|
||||
scheduleUpdate={scheduleUpdate}
|
||||
refreshPhotoswipe={refreshPhotoswipe}
|
||||
fileToCollectionsMap={props.fileToCollectionsMap}
|
||||
|
|
|
@ -26,6 +26,7 @@ import { styled } from '@mui/material';
|
|||
import { syncCollections } from 'services/collectionService';
|
||||
import EnteSpinner from 'components/EnteSpinner';
|
||||
import VerticallyCentered from 'components/Container';
|
||||
import { Collection } from 'types/collection';
|
||||
|
||||
export const DeduplicateContext = createContext<DeduplicateContextType>(
|
||||
DefaultDeduplicateContext
|
||||
|
@ -44,6 +45,7 @@ export default function Deduplicate() {
|
|||
setRedirectURL,
|
||||
} = useContext(AppContext);
|
||||
const [duplicateFiles, setDuplicateFiles] = useState<EnteFile[]>(null);
|
||||
const [collections, setCollection] = useState<Collection[]>([]);
|
||||
const [clubSameTimeFilesOnly, setClubSameTimeFilesOnly] = useState(false);
|
||||
const [fileSizeMap, setFileSizeMap] = useState(new Map<number, number>());
|
||||
const [collectionNameMap, setCollectionNameMap] = useState(
|
||||
|
@ -74,6 +76,7 @@ export default function Deduplicate() {
|
|||
const syncWithRemote = async () => {
|
||||
startLoading();
|
||||
const collections = await syncCollections();
|
||||
setCollection(collections);
|
||||
const collectionNameMap = new Map<number, string>();
|
||||
for (const collection of collections) {
|
||||
collectionNameMap.set(collection.id, collection.name);
|
||||
|
@ -174,6 +177,7 @@ export default function Deduplicate() {
|
|||
)}
|
||||
<PhotoFrame
|
||||
files={duplicateFiles}
|
||||
collections={collections}
|
||||
syncWithRemote={syncWithRemote}
|
||||
setSelected={setSelected}
|
||||
selected={selected}
|
||||
|
|
|
@ -18,7 +18,10 @@ import QueueProcessor, { PROCESSING_STRATEGY } from './queueProcessor';
|
|||
const MAX_PARALLEL_DOWNLOADS = 10;
|
||||
|
||||
class DownloadManager {
|
||||
private fileObjectURLPromise = new Map<string, Promise<string[]>>();
|
||||
private fileObjectURLPromise = new Map<
|
||||
string,
|
||||
Promise<{ original: string[]; converted: string[] }>
|
||||
>();
|
||||
private thumbnailObjectURLPromise = new Map<number, Promise<string>>();
|
||||
|
||||
private thumbnailDownloadRequestsProcessor = new QueueProcessor<any>(
|
||||
|
@ -95,12 +98,11 @@ class DownloadManager {
|
|||
if (forPreview) {
|
||||
return await getRenderableFileURL(file, fileBlob);
|
||||
} else {
|
||||
return [
|
||||
await createTypedObjectURL(
|
||||
fileBlob,
|
||||
file.metadata.title
|
||||
),
|
||||
];
|
||||
const fileURL = await createTypedObjectURL(
|
||||
fileBlob,
|
||||
file.metadata.title
|
||||
);
|
||||
return { converted: [fileURL], original: [fileURL] };
|
||||
}
|
||||
};
|
||||
if (!this.fileObjectURLPromise.get(fileKey)) {
|
||||
|
|
|
@ -244,10 +244,7 @@ class ExportService {
|
|||
file,
|
||||
RecordType.FAILED
|
||||
);
|
||||
console.log(
|
||||
`export failed for fileID:${file.id}, reason:`,
|
||||
e
|
||||
);
|
||||
|
||||
logError(
|
||||
e,
|
||||
'download and save failed for file during export'
|
||||
|
@ -624,7 +621,6 @@ class ExportService {
|
|||
oldFileSavePath,
|
||||
newFileSavePath
|
||||
);
|
||||
console.log(oldFileMetadataSavePath, newFileMetadataSavePath);
|
||||
await this.electronAPIs.checkExistsAndRename(
|
||||
oldFileMetadataSavePath,
|
||||
newFileMetadataSavePath
|
||||
|
|
|
@ -17,7 +17,10 @@ import { CustomError } from 'utils/error';
|
|||
import QueueProcessor from './queueProcessor';
|
||||
|
||||
class PublicCollectionDownloadManager {
|
||||
private fileObjectURLPromise = new Map<string, Promise<string[]>>();
|
||||
private fileObjectURLPromise = new Map<
|
||||
string,
|
||||
Promise<{ original: string[]; converted: string[] }>
|
||||
>();
|
||||
private thumbnailObjectURLPromise = new Map<number, Promise<string>>();
|
||||
|
||||
private thumbnailDownloadRequestsProcessor = new QueueProcessor<any>(5);
|
||||
|
@ -121,12 +124,11 @@ class PublicCollectionDownloadManager {
|
|||
if (forPreview) {
|
||||
return await getRenderableFileURL(file, fileBlob);
|
||||
} else {
|
||||
return [
|
||||
await createTypedObjectURL(
|
||||
fileBlob,
|
||||
file.metadata.title
|
||||
),
|
||||
];
|
||||
const fileURL = await createTypedObjectURL(
|
||||
fileBlob,
|
||||
file.metadata.title
|
||||
);
|
||||
return { converted: [fileURL], original: [fileURL] };
|
||||
}
|
||||
};
|
||||
if (!this.fileObjectURLPromise.get(fileKey)) {
|
||||
|
|
|
@ -200,7 +200,6 @@ export const syncPublicFiles = async (
|
|||
const parsedError = parseSharingErrorCodes(e);
|
||||
logError(e, 'failed to sync shared collection files');
|
||||
if (parsedError.message === CustomError.TOKEN_EXPIRED) {
|
||||
console.log('invalid token or password');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ export async function updateCreationTimeWithExif(
|
|||
if (file.metadata.fileType !== FILE_TYPE.IMAGE) {
|
||||
continue;
|
||||
}
|
||||
const fileURL = await downloadManager.getFile(file)[0];
|
||||
const fileURL = (await downloadManager.getFile(file))
|
||||
.original[0];
|
||||
const fileObject = await getFileFromURL(fileURL);
|
||||
const fileTypeInfo = await getFileType(fileObject);
|
||||
const exifData = await getRawExif(fileObject, fileTypeInfo);
|
||||
|
|
|
@ -54,6 +54,9 @@ export interface EnteFile {
|
|||
isDeleted: boolean;
|
||||
isTrashed?: boolean;
|
||||
deleteBy?: number;
|
||||
isSourceLoaded?: boolean;
|
||||
originalVideoURL?: string;
|
||||
originalImageURL?: string;
|
||||
dataIndex: number;
|
||||
updationTime: number;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export type SetCollectionSelectorAttributes = React.Dispatch<
|
|||
|
||||
export type GalleryContextType = {
|
||||
thumbs: Map<number, string>;
|
||||
files: Map<number, string>;
|
||||
files: Map<number, { original: string; converted: string }>;
|
||||
showPlanSelectorModal: () => void;
|
||||
setActiveCollection: (collection: number) => void;
|
||||
syncWithRemote: (force?: boolean, silent?: boolean) => Promise<void>;
|
||||
|
|
|
@ -287,14 +287,25 @@ export async function getRenderableFileURL(file: EnteFile, fileBlob: Blob) {
|
|||
file.metadata.title,
|
||||
fileBlob
|
||||
);
|
||||
return [URL.createObjectURL(convertedBlob)];
|
||||
return {
|
||||
converted: [URL.createObjectURL(convertedBlob)],
|
||||
original: [URL.createObjectURL(fileBlob)],
|
||||
};
|
||||
}
|
||||
case FILE_TYPE.LIVE_PHOTO: {
|
||||
const livePhoto = await getRenderableLivePhoto(file, fileBlob);
|
||||
return livePhoto.map((asset) => URL.createObjectURL(asset));
|
||||
return {
|
||||
converted: livePhoto.map((asset) => URL.createObjectURL(asset)),
|
||||
original: [URL.createObjectURL(fileBlob)],
|
||||
};
|
||||
}
|
||||
default: {
|
||||
const previewURL = URL.createObjectURL(fileBlob);
|
||||
return {
|
||||
converted: [previewURL],
|
||||
original: [previewURL],
|
||||
};
|
||||
}
|
||||
default:
|
||||
return [URL.createObjectURL(fileBlob)];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue