diff --git a/create.html b/create.html
index ea0bbfc..d339609 100644
--- a/create.html
+++ b/create.html
@@ -195,6 +195,155 @@ var petSel = document.getElementById("pet");
}).join("");
})();
+// The project id, once step one has created it. Everything in the collateral
+// step hangs off this.
+var PID = new URLSearchParams(location.search).get("id") || "";
+var COL = [], VID = null;
+
+function showCollateral() {
+ document.getElementById("colcard").style.display = "";
+ document.getElementById("go").disabled = true;
+ document.getElementById("go").textContent = "Saved";
+ document.getElementById("colcard").scrollIntoView({ behavior: "smooth", block: "start" });
+ loadCol();
+}
+
+function colHtml(c) {
+ var body = c.kind === "video"
+ ? ''
+ + '
footage · ' + (c.seconds || 0) + 's
'
+ : '
';
+ return '' + body
+ + '
' + esc(c.description || "") + '
'
+ + '
';
+}
+
+async function loadCol() {
+ if (!PID) return;
+ var r = await api("list_project_images", { email: email, project_id: PID });
+ COL = (r.ok && r.images) || [];
+ var el = document.getElementById("pics");
+ el.innerHTML = COL.map(colHtml).join("");
+ [].forEach.call(el.querySelectorAll("[data-rm]"), function (b) {
+ b.onclick = async function () {
+ var d = await api("delete_project_image", { email: email, image_id: b.getAttribute("data-rm") });
+ if (!d.ok) { showMsg("msg", d.error || "Could not remove that."); return; }
+ loadCol();
+ };
+ });
+}
+
+async function addPicture(file) {
+ hideMsg("msg");
+ if (!file || !/^image\//.test(file.type)) { showMsg("msg", "That is not an image."); return; }
+ var desc = prompt("What is in this picture? The writer uses this to decide where it belongs.");
+ if (!desc || desc.trim().length < 3) { showMsg("msg", "It needs a description to be usable."); return; }
+ var drop = document.getElementById("drop");
+ drop.textContent = "Uploading…";
+ var img;
+ try { img = await resizeImage(file, 1600, 0.85); }
+ catch (err) { drop.textContent = "Paste a picture, drop one here, or click to choose"; showMsg("msg", err.message || "Could not read that."); return; }
+ var r = await api("add_project_image", { email: email, project_id: PID,
+ description: desc.trim(), data_b64: img.b64 });
+ drop.textContent = "Paste a picture, drop one here, or click to choose";
+ if (!r.ok) { showMsg("msg", r.error || "That did not upload."); return; }
+ loadCol();
+}
+
+(function wireCollateral() {
+ var drop = document.getElementById("drop"), picker = document.getElementById("picker");
+ drop.onclick = function () { picker.click(); };
+ picker.onchange = function () { [].forEach.call(picker.files || [], addPicture); picker.value = ""; };
+ drop.addEventListener("dragover", function (e) { e.preventDefault(); drop.classList.add("hot"); });
+ drop.addEventListener("dragleave", function () { drop.classList.remove("hot"); });
+ drop.addEventListener("drop", function (e) {
+ e.preventDefault(); drop.classList.remove("hot");
+ [].forEach.call((e.dataTransfer && e.dataTransfer.files) || [], addPicture);
+ });
+ document.addEventListener("paste", function (e) {
+ if (!PID) return;
+ var items = (e.clipboardData && e.clipboardData.items) || [];
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].type && items[i].type.indexOf("image") === 0) {
+ var f = items[i].getAsFile();
+ if (f) { e.preventDefault(); addPicture(f); }
+ return;
+ }
+ }
+ });
+
+ var v = document.getElementById("vprev"),
+ vin = document.getElementById("vin"), vout = document.getElementById("vout");
+
+ function labels() {
+ document.getElementById("inlab").textContent = (+vin.value).toFixed(1) + "s";
+ document.getElementById("outlab").textContent = (+vout.value).toFixed(1) + "s";
+ var len = (+vout.value) - (+vin.value);
+ document.getElementById("vlen").textContent = len > 0
+ ? "That is " + len.toFixed(1) + " seconds of footage."
+ : "The end has to come after the start.";
+ }
+
+ document.getElementById("vload").onclick = function () {
+ hideMsg("msg");
+ var u = document.getElementById("vurl").value.trim();
+ if (!/^https?:\/\//.test(u)) { showMsg("msg", "Paste a link starting http."); return; }
+ v.src = u;
+ v.onloadedmetadata = function () {
+ // Duration is readable cross-origin even when the pixels are not, which
+ // is all the scrubber needs.
+ var d = isFinite(v.duration) ? v.duration : 0;
+ if (!d) { showMsg("msg", "That link did not load as a video file."); return; }
+ vin.max = vout.max = d.toFixed(1);
+ vin.value = 0; vout.value = Math.min(5, d).toFixed(1);
+ labels();
+ document.getElementById("vedit").style.display = "";
+ VID = u;
+ };
+ v.onerror = function () { showMsg("msg", "That link did not load as a video file. It has to be the file itself, not a page."); };
+ };
+
+ vin.oninput = function () { labels(); v.currentTime = +vin.value; };
+ vout.oninput = labels;
+
+ document.getElementById("vplay").onclick = function () {
+ v.currentTime = +vin.value;
+ v.play();
+ var stop = setInterval(function () {
+ if (v.currentTime >= +vout.value) { v.pause(); clearInterval(stop); }
+ }, 80);
+ };
+
+ document.getElementById("vadd").onclick = async function () {
+ hideMsg("msg");
+ var d = document.getElementById("vdesc").value.trim();
+ if (d.length < 3) { showMsg("msg", "Say what is in the clip."); return; }
+ var r = await api("add_project_video", {
+ email: email, project_id: PID, source_url: VID, description: d,
+ in_seconds: +vin.value, out_seconds: +vout.value
+ });
+ if (!r.ok) { showMsg("msg", r.error || "Could not use that clip."); return; }
+ document.getElementById("vedit").style.display = "none";
+ document.getElementById("vurl").value = "";
+ document.getElementById("vdesc").value = "";
+ loadCol();
+ };
+
+ document.getElementById("write").onclick = async function () {
+ var b = this;
+ hideMsg("msg");
+ b.disabled = true; b.textContent = "Writing…";
+ var r = await api("write_script", { email: email, project_id: PID });
+ if (!r.ok) { b.disabled = false; b.textContent = "Write the script"; showMsg("msg", r.error || "That did not start."); return; }
+ location.href = "/script.html?id=" + encodeURIComponent(PID);
+ };
+
+ if (PID) showCollateral();
+})();
+
document.getElementById("form").addEventListener("submit", async function (e) {
e.preventDefault();
hideMsg("msg");
@@ -208,18 +357,22 @@ document.getElementById("form").addEventListener("submit", async function (e) {
if (!url) { showMsg("msg", "Paste a link to whatever you want them to react to."); return; }
if (notes.length < 10) { showMsg("msg", "Tell the director what you think, in a sentence or two."); return; }
- btn.disabled = true; btn.textContent = "Writing…";
+ btn.disabled = true; btn.textContent = "Saving…";
+ // Held, so nothing is written until the collateral is attached.
var r = await api("create_project", {
email: email, pet_id: petSel.value,
pet_name: opt ? opt.getAttribute("data-name") : "",
source_url: url, owner_notes: notes, scene: scene,
format: document.getElementById("format").value,
- stance: stance, segments: segments
+ stance: stance, segments: segments, hold: true
});
- btn.disabled = false; btn.textContent = "Write the script";
- if (!r.ok) { showMsg("msg", r.error || "That did not go through. Please try again."); return; }
- showMsg("msg", "Writing it now…", "ok");
- setTimeout(function () { location.href = "/script.html?id=" + encodeURIComponent(r.project.id); }, 500);
+ if (!r.ok) {
+ btn.disabled = false; btn.textContent = "Next · add pictures and footage";
+ showMsg("msg", r.error || "That did not go through. Please try again."); return;
+ }
+ PID = r.project.id;
+ history.replaceState(null, "", "/create.html?id=" + encodeURIComponent(PID));
+ showCollateral();
});