Offer explicit retry after media preview loading failures

This commit is contained in:
karl committed 2026-10-13 14:29:49 +02:00
1 parent f7f67afff9
commit 6c34962ced
2 files changed
+28 -23

No files matched your search

+27 -22
View File
@@ -208,6 +208,24 @@ function clearMedia() {
mediaLane.clear(); mediaLane.clear();
unloadMedia(); unloadMedia();
} }
function showMediaFailure(request: PreviewRequest, message: string): void {
if (!previewRevision.accepts(request.revision)) return;
const status = element("media-preview-status");
status.hidden = false;
status.textContent = message;
const retry = document.createElement("button");
retry.type = "button";
retry.textContent = "Retry preview";
retry.addEventListener("click", () => {
const revision = previewRevision.retry(request.revision);
if (revision === undefined) return;
unloadMedia();
status.hidden = false;
status.textContent = "Preparing media preview…";
mediaLane.submit({ revision, result: request.result });
});
status.append(" ", retry);
}
const mediaLane = new LatestLane<PreviewRequest>( const mediaLane = new LatestLane<PreviewRequest>(
async (request) => { async (request) => {
const prepared = await invoke<{ const prepared = await invoke<{
@@ -218,10 +236,10 @@ const mediaLane = new LatestLane<PreviewRequest>(
const host = element("media-preview"); const host = element("media-preview");
const status = element("media-preview-status"); const status = element("media-preview-status");
const failed = () => { const failed = () => {
if (!previewRevision.accepts(request.revision)) return; showMediaFailure(
status.hidden = false; request,
status.textContent = "This preview could not be loaded. Retry or use Open file to view it in your default application.",
"This format cannot be previewed here. Use Open file to view it in your default application."; );
}; };
if (prepared.kind === "image") { if (prepared.kind === "image") {
const image = document.createElement("img"); const image = document.createElement("img");
@@ -262,24 +280,11 @@ const mediaLane = new LatestLane<PreviewRequest>(
status.hidden = true; status.hidden = true;
}, },
(request) => previewRevision.accepts(request.revision), (request) => previewRevision.accepts(request.revision),
(request, error) => { (request, error) =>
if (!previewRevision.accepts(request.revision)) return; showMediaFailure(
const status = element("media-preview-status"); request,
status.hidden = false; `Preview unavailable: ${String(error)}. Use Open file.`,
status.textContent = `Preview unavailable: ${String(error)}. Use Open file.`; ),
const retry = document.createElement("button");
retry.type = "button";
retry.textContent = "Retry preview";
retry.addEventListener("click", () => {
const revision = previewRevision.retry(request.revision);
if (revision === undefined) return;
unloadMedia();
status.hidden = false;
status.textContent = "Preparing media preview…";
mediaLane.submit({ revision, result: request.result });
});
status.append(" ", retry);
},
); );
let displayedRequestId: number | null = null; let displayedRequestId: number | null = null;
let expandedError: string | null = null; let expandedError: string | null = null;
+1 -1
View File
@@ -19,7 +19,7 @@ Arbitrary paths, remote URLs, query strings and traversal are not preview grants
The generic Tauri asset protocol is disabled in the new configuration. The generic Tauri asset protocol is disabled in the new configuration.
Index-change notifications also advance the preview selection identity, so a Index-change notifications also advance the preview selection identity, so a
same-path image/recording reloads rather than retaining previously decoded media. same-path image/recording reloads rather than retaining previously decoded media.
Failed native preview preparation now offers an explicit **Retry preview** Failed native preview preparation and image/audio/video loading now offer an explicit **Retry preview**
button. It invalidates the old request revision and cannot restart a selection button. It invalidates the old request revision and cannot restart a selection
that has since changed. There is no automatic retry loop. The added regression that has since changed. There is no automatic retry loop. The added regression
passed with all 60 frontend tests, formatting and the production frontend build. passed with all 60 frontend tests, formatting and the production frontend build.