mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 07:28:26 +00:00
Reset failures
This commit is contained in:
parent
f47837f550
commit
b3100f098b
@ -147,15 +147,12 @@ body {
|
||||
overflow: hidden;
|
||||
width: 50px;
|
||||
height: 60px;
|
||||
/* "visibility" is used to toggle visibility, opacity is fixed to be similar
|
||||
to that of the loading indicator when it is visible. */
|
||||
opacity: 0.5;
|
||||
/* Unlike the loading indicator, "display" is used to toggle visibility, and
|
||||
the opacity is fixed to be similar to that of the counter. */
|
||||
opacity: 0.85;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pswp-ente .pswp__error .pswp__icn {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.pswp-ente .pswp__error--active .pswp__icn {
|
||||
visibility: visible;
|
||||
.pswp-ente .pswp__error--active {
|
||||
display: initial;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ export const itemDataForFile = (file: EnteFile, needsRefresh: () => void) => {
|
||||
// point of time. This assumption is currently valid.
|
||||
_state.needsRefreshByFileID.set(file.id, needsRefresh);
|
||||
|
||||
if (!itemData || itemData.failureReason) {
|
||||
if (!itemData) {
|
||||
itemData = {};
|
||||
_state.itemDataByFileID.set(file.id, itemData);
|
||||
void enqueueUpdates(file);
|
||||
@ -163,24 +163,37 @@ export const itemDataForFile = (file: EnteFile, needsRefresh: () => void) => {
|
||||
return itemData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset any failure reasons for the given {@link file}.
|
||||
*
|
||||
* This is called when the user moves away from a slide, so that when the come
|
||||
* back the next time, the entire process is retried.
|
||||
*/
|
||||
export const resetFailuresForFile = (file: EnteFile) => {
|
||||
if (_state.itemDataByFileID.get(file.id)?.failureReason) {
|
||||
_state.itemDataByFileID.delete(file.id);
|
||||
}
|
||||
};
|
||||
|
||||
const enqueueUpdates = async (file: EnteFile) => {
|
||||
const update = (itemData: ItemData) => {
|
||||
_state.itemDataByFileID.set(file.id, itemData);
|
||||
_state.needsRefreshByFileID.get(file.id)?.();
|
||||
};
|
||||
|
||||
let thumbnailData: ItemData;
|
||||
try {
|
||||
const thumbnailURL = await downloadManager.renderableThumbnailURL(file);
|
||||
// TODO(PS):
|
||||
const thumbnailData = await withDimensions(thumbnailURL!);
|
||||
thumbnailData = await withDimensions(thumbnailURL!);
|
||||
update({
|
||||
...thumbnailData,
|
||||
isContentLoading: true,
|
||||
isContentZoomable: false,
|
||||
});
|
||||
} catch (e) {
|
||||
// If we can't even get the thumbnail, then a persistent (for now)
|
||||
// network error is likely (download manager already has retries).
|
||||
// If we can't even get the thumbnail, then a network error is likely
|
||||
// (download manager already has retries).
|
||||
//
|
||||
// Notify the user of the error. The entire process will be retried when
|
||||
// they reopen the slide later.
|
||||
@ -189,33 +202,42 @@ const enqueueUpdates = async (file: EnteFile) => {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (file.metadata.fileType) {
|
||||
case FileType.image: {
|
||||
const sourceURLs = await downloadManager.renderableSourceURLs(file);
|
||||
// TODO(PS):
|
||||
const itemData = await withDimensions(sourceURLs.url as string);
|
||||
update(itemData);
|
||||
break;
|
||||
}
|
||||
try {
|
||||
switch (file.metadata.fileType) {
|
||||
case FileType.image: {
|
||||
const sourceURLs =
|
||||
await downloadManager.renderableSourceURLs(file);
|
||||
// TODO(PS):
|
||||
const itemData = await withDimensions(sourceURLs.url as string);
|
||||
update(itemData);
|
||||
break;
|
||||
}
|
||||
|
||||
case FileType.video: {
|
||||
const sourceURLs = await downloadManager.renderableSourceURLs(file);
|
||||
// TODO(PS):
|
||||
update({ videoURL: sourceURLs.url as string });
|
||||
break;
|
||||
}
|
||||
case FileType.video: {
|
||||
const sourceURLs =
|
||||
await downloadManager.renderableSourceURLs(file);
|
||||
// TODO(PS):
|
||||
update({ videoURL: sourceURLs.url as string });
|
||||
break;
|
||||
}
|
||||
|
||||
case FileType.livePhoto: {
|
||||
const sourceURLs = await downloadManager.renderableSourceURLs(file);
|
||||
const livePhotoSourceURLs = sourceURLs.url as LivePhotoSourceURL;
|
||||
const imageURL = await livePhotoSourceURLs.image();
|
||||
// TODO(PS):
|
||||
const imageData = await withDimensions(imageURL!);
|
||||
update(imageData);
|
||||
const livePhotoVideoURL = await livePhotoSourceURLs.video();
|
||||
update({ ...imageData, livePhotoVideoURL });
|
||||
break;
|
||||
case FileType.livePhoto: {
|
||||
const sourceURLs =
|
||||
await downloadManager.renderableSourceURLs(file);
|
||||
const livePhotoSourceURLs =
|
||||
sourceURLs.url as LivePhotoSourceURL;
|
||||
const imageURL = await livePhotoSourceURLs.image();
|
||||
// TODO(PS):
|
||||
const imageData = await withDimensions(imageURL!);
|
||||
update(imageData);
|
||||
const livePhotoVideoURL = await livePhotoSourceURLs.video();
|
||||
update({ ...imageData, livePhotoVideoURL });
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("Failed to show file", e);
|
||||
update({ ...thumbnailData, failureReason: "other" });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ const paths = {
|
||||
// TODO(PS): This transform is temporary, audit later.
|
||||
info: '<path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8" transform="translate(3.5, 3.5)"',
|
||||
// "@mui/icons-material/ErrorOutline"
|
||||
error: '<path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8" transform="translate(10, 5.7) scale(0.85)"',
|
||||
error: '<path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8" transform="translate(7, 5.7) scale(0.85)"',
|
||||
};
|
||||
|
||||
/**
|
||||
@ -41,6 +41,6 @@ const paths = {
|
||||
*/
|
||||
export const createPSRegisterElementIconHTML = (name: "info") => ({
|
||||
isCustomSVG: true,
|
||||
inner: `${paths[name]} id="pswp__icn-${name}"`,
|
||||
inner: `${paths[name]} id="pswp__icn-${name}" />`,
|
||||
outlineID: `pswp__icn-${name}`,
|
||||
});
|
||||
|
@ -4,7 +4,7 @@
|
||||
import log from "@/base/log";
|
||||
import type { EnteFile } from "@/media/file";
|
||||
import { t } from "i18next";
|
||||
import { itemDataForFile } from "./data-source";
|
||||
import { itemDataForFile, resetFailuresForFile } from "./data-source";
|
||||
import type { FileViewerProps } from "./FileViewer";
|
||||
import { createPSRegisterElementIconHTML } from "./icons";
|
||||
|
||||
@ -145,6 +145,11 @@ export class FileViewerPhotoSwipe {
|
||||
mainClass: "pswp-ente",
|
||||
});
|
||||
|
||||
// Helper routines to obtain the file at `currIndex`.
|
||||
const currentFile = () => this.files[pswp.currIndex]!;
|
||||
const withCurrentFile = (cb: (file: EnteFile) => void) => () =>
|
||||
cb(currentFile());
|
||||
|
||||
// Provide data about slides to PhotoSwipe via callbacks
|
||||
// https://photoswipe.com/data-sources/#dynamically-generated-data
|
||||
|
||||
@ -234,15 +239,24 @@ export class FileViewerPhotoSwipe {
|
||||
});
|
||||
|
||||
pswp.on("contentDeactivate", (e) => {
|
||||
// Pause the video element (if any) on a slide when we move away
|
||||
// from it.
|
||||
// Reset failures, if any, for this file so that the fetch is tried
|
||||
// again when we come back to it^.
|
||||
//
|
||||
// ^ Note that because of how the preloading works, this will have
|
||||
// an effect (i.e. the retry will happen) only if the user moves
|
||||
// more than 2 slides and then back, or if they reopen the viewer.
|
||||
resetFailuresForFile(currentFile());
|
||||
|
||||
// Pause the video element, if any, when we move away from the
|
||||
// slide.
|
||||
const video =
|
||||
e.content?.slide?.container?.getElementsByTagName("video")[0];
|
||||
video?.pause();
|
||||
});
|
||||
|
||||
pswp.on("contentActivate", (e) => {
|
||||
// Undo the effect of a previous "contentDeactivate".
|
||||
// Undo the effect of a previous "contentDeactivate" if it was
|
||||
// displaying a live photo.
|
||||
if (e.content?.slide.data?.livePhotoVideoURL) {
|
||||
e.content?.slide?.container
|
||||
?.getElementsByTagName("video")[0]
|
||||
@ -258,9 +272,6 @@ export class FileViewerPhotoSwipe {
|
||||
onClose();
|
||||
});
|
||||
|
||||
const withCurrentFile = (cb: (file: EnteFile) => void) => () =>
|
||||
cb(this.files[this.pswp.currIndex]!);
|
||||
|
||||
// Add our custom UI elements to inside the PhotoSwipe dialog.
|
||||
//
|
||||
// API docs for registerElement:
|
||||
@ -277,35 +288,12 @@ export class FileViewerPhotoSwipe {
|
||||
order: 6,
|
||||
html: createPSRegisterElementIconHTML("error"),
|
||||
onInit: (errorElement, pswp) => {
|
||||
let isVisible = false;
|
||||
|
||||
const toggleIndicatorClass = (className, add) => {
|
||||
pswp.on("change", () => {
|
||||
errorElement.classList.toggle(
|
||||
"pswp__error--" + className,
|
||||
add,
|
||||
"pswp__error--active",
|
||||
!!pswp.currSlide.content.data.failureReason,
|
||||
);
|
||||
};
|
||||
|
||||
const setIndicatorVisibility = (visible) => {
|
||||
if (isVisible !== visible) {
|
||||
isVisible = visible;
|
||||
toggleIndicatorClass("active", visible);
|
||||
}
|
||||
};
|
||||
|
||||
const updateErrorIndicatorVisibility = () => {
|
||||
console.log(
|
||||
"updateErrorIndicatorVisibility",
|
||||
pswp.currSlide.content,
|
||||
);
|
||||
if (!pswp.currSlide.content.data.failureReason) {
|
||||
setIndicatorVisibility(true);
|
||||
} else {
|
||||
setIndicatorVisibility(false);
|
||||
}
|
||||
};
|
||||
|
||||
pswp.on("change", updateErrorIndicatorVisibility);
|
||||
});
|
||||
},
|
||||
});
|
||||
pswp.ui.registerElement({
|
||||
@ -316,23 +304,6 @@ export class FileViewerPhotoSwipe {
|
||||
html: createPSRegisterElementIconHTML("info"),
|
||||
onClick: withCurrentFile(onViewInfo),
|
||||
});
|
||||
// const counterIndicator2 = {
|
||||
// name: "counter-2",
|
||||
// order: 5,
|
||||
// html: '<div><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true" class="xxxpswp__icn"><path d="M20.5 14.3 17.1 18V10h-2.2v7.9l-3.4-3.6L10 16l6 6.1 6-6.1ZM23 23H9v2h14Z" /></svg></div>',
|
||||
|
||||
// onInit: (counterElement, pswp) => {
|
||||
// pswp.on("change", () => {
|
||||
// counterElement.style.fill = "red";
|
||||
// // counterElement.innerText =
|
||||
// // pswp.currIndex +
|
||||
// // 1 +
|
||||
// // pswp.options.indexIndicatorSep +
|
||||
// // pswp.getNumItems();
|
||||
// });
|
||||
// },
|
||||
// };
|
||||
// pswp.ui.registerElement(counterIndicator2);
|
||||
});
|
||||
|
||||
// Modify the default UI elements.
|
||||
|
Loading…
x
Reference in New Issue
Block a user