Deduplicate media across scrapes and polish the viewer controls

This commit is contained in:
Fisto
2026-09-16 13:05:31 +02:00
parent 1b5fcfed2f
commit d3f9d20190
12 changed files with 198 additions and 85 deletions
+1
View File
@@ -4,6 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>veskslop debug</title>
<link rel="icon" href="data:," />
<link rel="stylesheet" href="nocturne.css" />
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="media.css" />
+7
View File
@@ -179,6 +179,7 @@
}
.vk-media-viewer-media {
position: relative;
display: flex;
flex: 1;
flex-direction: column;
@@ -188,6 +189,12 @@
min-height: 0;
}
.vk-media-play-big {
top: 12px;
right: 14px;
font-size: 44px;
}
.vk-media-viewer-media img,
.vk-media-viewer-media video {
max-width: 100%;
+26 -19
View File
@@ -417,6 +417,13 @@
return play;
}
function viewerPlayIcon(item) {
const play = el("span", "vk-media-play vk-media-play-big", "▶");
play.title = "Play";
play.addEventListener("click", () => openViewer(item, true));
return play;
}
function renderCard(item) {
const figure = el("figure", "vk-media-figure");
const media = el("div", "vk-media-media");
@@ -1074,33 +1081,33 @@
media.replaceChildren();
const source = item.localUrl || item.thumbUrl || item.url;
const embed = play ? embedUrlFor(item) : null;
const direct = item.localUrl || (item.source !== "embed" ? item.url : null);
const playableFile = !!direct && /\.(mp4|webm|m4v)(\?|$)/i.test(direct);
const embed = embedUrlFor(item);
const canPlay = !!embed || playableFile;
if (embed) {
// A play request on something we cannot embed falls back to the external page.
if (play && !canPlay) openLinkWarning(item.url);
if (play && embed) {
const frame = document.createElement("iframe");
frame.src = embed;
frame.allow = "autoplay; fullscreen; picture-in-picture";
frame.allowFullscreen = true;
media.append(frame);
} else if (item.kind === "video" && /^(https?:|\/)/.test(source)) {
if (play) {
const video = document.createElement("video");
video.controls = true;
video.autoplay = true;
video.src = source;
media.append(video);
} else {
const img = document.createElement("img");
img.src = source;
img.alt = item.kind;
media.append(img);
media.append(button("Play", () => openViewer(item, true)));
}
} else if (play && playableFile && direct) {
const video = document.createElement("video");
video.controls = true;
video.autoplay = true;
video.src = direct;
media.append(video);
} else if (/^(https?:|\/)/.test(source)) {
const img = document.createElement("img");
img.src = source;
img.alt = item.kind;
media.append(img);
if (item.kind === "video") media.append(viewerPlayIcon(item));
} else {
media.append(el("span", "vk-media-card-kind", item.kind.toUpperCase()));
}
@@ -1120,9 +1127,9 @@
link.addEventListener("click", () => openLinkWarning(item.url));
meta.append(link);
meta.append(
button("View full", () => window.open(item.localUrl || item.url, "_blank", "noreferrer"))
);
// "View full" opens the embedded media (player, local file, or preview) in a new tab.
const fullUrl = embedUrlFor(item) ?? item.localUrl ?? item.thumbUrl ?? item.url;
meta.append(button("View full", () => window.open(fullUrl, "_blank", "noreferrer")));
viewerModal.hidden = false;
}