Watch a run of shots (from/to) as one link; share buttons retry a timed-out request

This commit is contained in:
gator 2026-09-25 19:21:43 +00:00
parent 1d8896e8c4
commit d25d596214

View file

@ -1084,7 +1084,7 @@
+ fold("views", "Master pictures for each set-up", "", viewsHtml(draft)) + fold("views", "Master pictures for each set-up", "", viewsHtml(draft))
+ fold("cast", "The cast", cast.length + " characters - faces, looks, voices", castHtml) + fold("cast", "The cast", cast.length + " characters - faces, looks, voices", castHtml)
+ fold("props", "Things that must look the same in every shot", ((PKG.props || []).length || "no") + " tracked", propsHtml()) + fold("props", "Things that must look the same in every shot", ((PKG.props || []).length || "no") + " tracked", propsHtml())
+ body; + rangeHtml() + body;
} }
// FOLDS. The cast, the props, the story notes and the master pictures are // FOLDS. The cast, the props, the story notes and the master pictures are
@ -1746,6 +1746,26 @@
+ '</div></div>'; + '</div></div>';
} }
// A link of many clips can take longer than the proxy's 5 s; it is made
// anyway, and asking again returns the same link at once.
async function shareRetry(payload) {
var r1 = await api("share_clips", payload);
if (!r1.ok && /timed out/i.test(r1.error || "")) r1 = await api("share_clips", payload);
if (!r1.ok) { showMsg("msg", r1.error || "That did not work."); return null; }
hideMsg("msg");
return r1;
}
var RANGE = { from: "", to: "" };
document.addEventListener("input", function (e) {
if (e.target && e.target.id === "rgfrom") RANGE.from = e.target.value;
if (e.target && e.target.id === "rgto") RANGE.to = e.target.value;
});
function rangeHtml() {
return '<div class="sceneshare" style="margin:10px 0"><b style="color:var(--ink)">Watch a run of shots</b> from shot '
+ '<input id="rgfrom" size="4" placeholder="010" value="' + esc(RANGE.from) + '" style="font:inherit;width:56px"> to '
+ '<input id="rgto" size="4" placeholder="055" value="' + esc(RANGE.to) + '" style="font:inherit;width:56px"> '
+ '<button type="button" class="btn small" data-rangeplay="1">Play them in order</button> <span id="rglink"></span></div>';
}
async function act(name, payload) { async function act(name, payload) {
var r = await api(name, payload); var r = await api(name, payload);
if (!r.ok) { showMsg("msg", r.error || "That did not work."); return null; } if (!r.ok) { showMsg("msg", r.error || "That did not work."); return null; }
@ -1821,10 +1841,27 @@
else el.disabled = false; else el.disabled = false;
return; return;
} }
if ((el = hit("data-rangeplay"))) {
// A RUN OF SHOTS: every filmed shot from one number to another, off
// the cutting room floor, as one link that plays them in order.
var rf = String((document.getElementById("rgfrom") || {}).value || "").trim(), rt = String((document.getElementById("rgto") || {}).value || "").trim();
var pad = function (x) { return /^\d+$/.test(x) ? ("000" + x).slice(-3) : x; };
rf = pad(rf); rt = pad(rt);
var run = (PKG.shots || []).slice().sort(function (a, b) { return String(a.id).localeCompare(String(b.id)); })
.filter(function (x) { var id = String(x.id); return x.clip_url && !x.floor && (!rf || id >= rf) && (!rt || id <= rt || id.indexOf(rt) === 0); })
.map(function (x) { return x.id; });
if (run.length < 2) { showMsg("msg", "There are fewer than two filmed shots in that range."); return; }
if (run.length > 80) { showMsg("msg", "That is " + run.length + " shots; a link holds at most 80. Choose a shorter range."); return; }
el.disabled = true;
r = await shareRetry({ draft_id: CUR, shot_ids: run, label: "Shots " + run[0] + " to " + run[run.length - 1] });
el.disabled = false;
if (r) { var lk = document.getElementById("rglink"); if (lk) lk.innerHTML = '<a class="sharelink" href="' + esc(r.url) + '" target="_blank">' + esc(r.url) + '</a>'; showMsg("msg", r.clips + " shots, played in order: " + r.url, "ok"); }
return;
}
if ((el = hit("data-sharescene"))) { if ((el = hit("data-sharescene"))) {
var sids = el.getAttribute("data-sharescene").split(","); var sids = el.getAttribute("data-sharescene").split(",");
el.disabled = true; el.disabled = true;
r = await act("share_clips", { draft_id: CUR, shot_ids: sids, label: el.getAttribute("data-scenelabel") }); r = await shareRetry({ draft_id: CUR, shot_ids: sids, label: el.getAttribute("data-scenelabel") });
if (r) { SHARES["scene:" + sids.join(",")] = r.url; showMsg("msg", r.clips + " clips, played in order: " + r.url, "ok"); openTab(CUR); } if (r) { SHARES["scene:" + sids.join(",")] = r.url; showMsg("msg", r.clips + " clips, played in order: " + r.url, "ok"); openTab(CUR); }
else el.disabled = false; else el.disabled = false;
return; return;