A 'what to do next' guide, and the picture checker's findings with a Fix button
The page never said what the next step was, and finding faulty pictures was left to the author although every frame is already checked by a model.
This commit is contained in:
parent
39c41c689d
commit
3d34667b35
1 changed files with 144 additions and 1 deletions
145
trailer.html
145
trailer.html
|
|
@ -50,6 +50,23 @@
|
|||
.whoin .p input{width:100%;box-sizing:border-box;font:inherit;padding:5px 7px;
|
||||
border:1px solid var(--line);border-radius:6px;background:transparent;color:inherit}
|
||||
.whoin .p .go{margin-top:5px;font-size:12px;padding:3px 9px}
|
||||
.guide{border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin:0 0 18px}
|
||||
.guide h4{margin:0 0 10px;font-size:15px}
|
||||
.guide ol{list-style:none;margin:0;padding:0;display:grid;gap:7px}
|
||||
.guide li{display:flex;gap:10px;align-items:baseline;font-size:13px;color:var(--muted)}
|
||||
.guide li .n{flex:none;width:20px;height:20px;border-radius:50%;border:1px solid var(--line);
|
||||
display:inline-flex;align-items:center;justify-content:center;font-size:11px}
|
||||
.guide li.done .n{background:#1f7a3a;border-color:#1f7a3a;color:#fff}
|
||||
.guide li.now{color:inherit;font-weight:600}
|
||||
.guide li.now .n{background:#4B8BF5;border-color:#4B8BF5;color:#fff}
|
||||
.guide li .d{font-weight:400;color:var(--muted);display:block;margin-top:2px}
|
||||
.guide li .btn{margin-left:4px}
|
||||
.fchk{font-size:12px;margin:0 0 10px;padding:7px 10px;border-radius:8px;border:1px solid var(--line)}
|
||||
.fchk.ok{color:#1f7a3a;border-color:transparent;padding-left:0}
|
||||
.fchk.bad{border-color:#b4531f}
|
||||
.fchk .w{display:block;margin:3px 0}
|
||||
.fchk .w.serious{color:#b4531f;font-weight:600}
|
||||
.fchk .go{font-size:12px;padding:2px 9px;margin-left:6px}
|
||||
.ffault{display:flex;gap:8px;margin:0 0 10px}
|
||||
.ffault input{flex:1;min-width:0;font:inherit;font-size:12px;padding:5px 8px;
|
||||
border:1px solid var(--line);border-radius:6px;background:transparent;color:inherit}
|
||||
|
|
@ -224,7 +241,12 @@
|
|||
return (Date.now() - t) < 25 * 60 * 1000;
|
||||
}
|
||||
|
||||
var DRAFTNOW = null;
|
||||
|
||||
function busyShots() {
|
||||
var ps = String(PKG.pics_state || "");
|
||||
if (ps && ps !== "ready"
|
||||
&& (Date.now() - (Date.parse(PKG.pics_started || "") || 0)) < 15 * 60 * 1000) return true;
|
||||
if (String(PKG.look_state || "")
|
||||
&& (Date.now() - (Date.parse(PKG.look_started || "") || 0)) < 15 * 60 * 1000) return true;
|
||||
return (PKG.shots || []).some(function (s) {
|
||||
|
|
@ -821,7 +843,8 @@
|
|||
var body = insertHtml("start");
|
||||
shots.forEach(function (s) { body += shotHtml(s, voice) + insertHtml(s.id); });
|
||||
|
||||
return head + probs + '<div class="bar">' + barHtml(meta) + '</div>'
|
||||
DRAFTNOW = draft;
|
||||
return head + guideHtml(meta) + probs + '<div class="bar">' + barHtml(meta) + '</div>'
|
||||
+ '<div id="reelhost">' + reelHtml() + '</div>'
|
||||
+ spineHtml() + cutsHtml(meta) + reviewsHtml(meta) + wholeHtml() + castHtml + body;
|
||||
}
|
||||
|
|
@ -849,6 +872,103 @@
|
|||
}).join("");
|
||||
}
|
||||
|
||||
// WHAT TO DO NEXT. The steps of making a trailer, in order, with the one
|
||||
// button that matters now. Everything else on the page is still there for
|
||||
// anyone who wants it; nobody has to understand it to get a film made.
|
||||
function guideHtml(meta) {
|
||||
var shots = PKG.shots || [];
|
||||
if (!shots.length || meta.writer !== RUN.lead_writer) return "";
|
||||
var ds = String(meta.draw_state || "");
|
||||
var drawing = ds && !/^(drawn|failed)/.test(ds);
|
||||
var toDraw = Number(PKG.pictures_to_draw || 0);
|
||||
var drawn = shots.filter(function (x) { return x.opening_url; });
|
||||
var unchecked = drawn.filter(function (x) {
|
||||
return !x.clip_url && !((x.frame_check || {}).verdict); }).length;
|
||||
var faulty = drawn.filter(function (x) {
|
||||
return !x.clip_url && (x.frame_check || {}).verdict === "broken"; });
|
||||
var ps = String(PKG.pics_state || "");
|
||||
var checking = ps && ps !== "ready";
|
||||
var reelReady = String(PKG.reel_state || "") === "ready";
|
||||
var unfilmed = shots.filter(function (x) { return !x.clip_url; }).length;
|
||||
var objections = String((DRAFTNOW || {}).problems || "").split("\n").filter(Boolean).length;
|
||||
var price = function (n) { return "$" + n.toFixed(2); };
|
||||
|
||||
var steps = [];
|
||||
steps.push({ t: "Read the script", done: true,
|
||||
d: objections ? "The checker has " + objections + " objection" + (objections === 1 ? "" : "s")
|
||||
+ " - they are listed just below." : "" });
|
||||
steps.push({ t: "Tell the writer what to change", done: true, optional: true,
|
||||
d: "Write in the box \u201cYour notes on the script as a whole\u201d, or under any shot, then press "
|
||||
+ "\u201cRevise the whole script\u201d. Skip this if you are happy." });
|
||||
|
||||
var s3 = { t: "Draw the pictures", done: toDraw === 0 && drawn.length > 0 };
|
||||
if (drawing) s3.d = "Drawing now\u2026 " + esc(ds) + ". You can leave this page open.";
|
||||
else if (!s3.done) s3.btn = '<button type="button" class="btn primary" data-draw="' + esc(meta.id)
|
||||
+ '">Draw ' + toDraw + ' picture' + (toDraw === 1 ? '' : 's') + ' \u00b7 ' + price(toDraw * 0.068) + '</button>';
|
||||
steps.push(s3);
|
||||
|
||||
var s4 = { t: "Check the pictures", done: s3.done && !unchecked && !faulty.length };
|
||||
if (checking) s4.d = "Looking at every picture for mistakes\u2026 " + esc(ps);
|
||||
else if (s3.done && unchecked) {
|
||||
s4.d = "A second model looks at every picture for the mistakes these tools make - the wrong time "
|
||||
+ "of day, the wrong clothes, extra people, six fingers - and redraws any that are broken.";
|
||||
s4.btn = '<button type="button" class="btn primary" data-chkpics="1">Check ' + unchecked
|
||||
+ ' picture' + (unchecked === 1 ? '' : 's') + ' \u00b7 ' + price(unchecked * 0.02) + '</button>';
|
||||
} else if (s3.done && faulty.length)
|
||||
s4.d = faulty.length + " picture" + (faulty.length === 1 ? " still has" : "s still have")
|
||||
+ " a problem: shot" + (faulty.length === 1 ? " " : "s ")
|
||||
+ faulty.map(function (x) { return x.id; }).join(", ")
|
||||
+ ". Scroll to " + (faulty.length === 1 ? "it" : "them") + " and press \u201cFix this\u201d, "
|
||||
+ "or carry on if you think the checker is being fussy.";
|
||||
steps.push(s4);
|
||||
|
||||
var s5 = { t: "Listen to the storyboard", done: reelReady };
|
||||
if (s3.done && !reelReady)
|
||||
s5.btn = '<button type="button" class="btn' + (s4.done ? ' primary' : '')
|
||||
+ '" data-reelgo="1">Play it with the voices</button>';
|
||||
steps.push(s5);
|
||||
|
||||
var s6 = { t: "Film it", done: unfilmed === 0 };
|
||||
if (s3.done && unfilmed)
|
||||
s6.btn = '<button type="button" class="btn' + (s4.done && reelReady ? ' primary' : '')
|
||||
+ '" data-film="' + esc(meta.id) + '">Film ' + unfilmed + ' shot' + (unfilmed === 1 ? '' : 's')
|
||||
+ ' \u00b7 ' + price(unfilmed * 0.75) + '</button>';
|
||||
steps.push(s6);
|
||||
|
||||
var nowSet = false;
|
||||
return '<div class="guide"><h4>What to do next</h4><ol>' + steps.map(function (st, i) {
|
||||
var isNow = !nowSet && !st.done && !st.optional;
|
||||
if (isNow) nowSet = true;
|
||||
return '<li class="' + (st.done ? 'done' : '') + (isNow ? ' now' : '') + '">'
|
||||
+ '<span class="n">' + (st.done && !st.optional ? '\u2713' : (i + 1)) + '</span>'
|
||||
+ '<span>' + esc(st.t) + (st.optional ? ' <i>(if you want)</i>' : '')
|
||||
+ ((isNow || (st.btn && /primary/.test(st.btn))) && st.btn ? ' ' + st.btn : '')
|
||||
+ (st.d && (isNow || st.optional || i === 0) ? '<span class="d">' + st.d + '</span>' : '')
|
||||
+ '</span></li>';
|
||||
}).join("") + '</ol></div>';
|
||||
}
|
||||
|
||||
// What the checker saw in this shot's opening picture, in its own sentence.
|
||||
function frameCheckHtml(s) {
|
||||
var fc = s.frame_check || {};
|
||||
if (!s.opening_url || s.clip_url || !fc.verdict || s.fixing || s.drawing) return "";
|
||||
var faults = (fc.faults || []).filter(function (f) { return f && f.what; });
|
||||
var dup = (fc.duplicated || []).filter(Boolean);
|
||||
var retried = s.frame_retried ? ' <i>(' + esc(s.frame_retried) + ')</i>' : '';
|
||||
if (!faults.length && !dup.length)
|
||||
return '<div class="fchk ok">\u2713 picture checked - nothing wrong' + retried + '</div>';
|
||||
var rows = dup.map(function (d) {
|
||||
return { what: "The same person appears twice: " + d, serious: true }; })
|
||||
.concat(faults.map(function (f) { return { what: f.what, serious: f.severity === "serious" }; }));
|
||||
return '<div class="fchk ' + (fc.verdict === "broken" ? 'bad' : '') + '">'
|
||||
+ '<b>The checker looked at this picture and sees:</b>' + retried
|
||||
+ rows.map(function (r, i) {
|
||||
return '<span class="w' + (r.serious ? ' serious' : '') + '">' + esc(r.what)
|
||||
+ ' <button type="button" class="btn go" data-fixfault="' + esc(s.id) + '|' + i + '">Fix this</button></span>';
|
||||
}).join("")
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
// "That is not right" - about the PICTURE, in the author's own words. The
|
||||
// picture is what the shot is filmed from, so a fault here is inherited by
|
||||
// the film and cannot be fixed by filming again.
|
||||
|
|
@ -1037,6 +1157,7 @@
|
|||
+ (s.day ? ' · <span class="scene">' + esc(s.day) + '</span>' : '')
|
||||
+ '</div>'
|
||||
+ media
|
||||
+ frameCheckHtml(s)
|
||||
+ frameFaultHtml(s)
|
||||
+ whoInHtml(s)
|
||||
+ '<p class="act">' + esc(s.action || "") + '</p>'
|
||||
|
|
@ -1225,6 +1346,28 @@
|
|||
z.classList.add("on");
|
||||
return;
|
||||
}
|
||||
if ((el = hit("data-chkpics"))) {
|
||||
el.disabled = true; el.textContent = "starting\u2026";
|
||||
r = await act("check_pictures", { draft_id: CUR });
|
||||
if (r) { showMsg("msg", r.shots ? "Checking " + r.shots + " pictures. Broken ones are redrawn "
|
||||
+ "automatically. This takes a few minutes." : (r.note || "Already checked."), "ok"); await refresh(); }
|
||||
return;
|
||||
}
|
||||
if ((el = hit("data-fixfault"))) {
|
||||
var ff = el.getAttribute("data-fixfault").split("|");
|
||||
var fs = (PKG.shots || []).filter(function (x) { return String(x.id) === ff[0]; })[0] || {};
|
||||
var fcx = fs.frame_check || {};
|
||||
var all = (fcx.duplicated || []).filter(Boolean).map(function (d) {
|
||||
return "The same person appears twice: " + d + ". Each person appears once only."; })
|
||||
.concat((fcx.faults || []).filter(function (f) { return f && f.what; })
|
||||
.map(function (f) { return f.what; }));
|
||||
var say = all[Number(ff[1])] || "";
|
||||
if (!say) return;
|
||||
el.disabled = true; el.textContent = "working\u2026";
|
||||
r = await act("report_frame_fault", { draft_id: CUR, shot_id: ff[0], note: say });
|
||||
if (r) { showMsg("msg", "Redrawing shot " + ff[0] + " to fix that. About a minute.", "ok"); await refresh(); }
|
||||
return;
|
||||
}
|
||||
if ((el = hit("data-ffgo"))) {
|
||||
var fsid = el.getAttribute("data-ffgo");
|
||||
var fbox = document.getElementById("ff-" + fsid);
|
||||
|
|
|
|||
Loading…
Reference in a new issue