Set up thumbnail editing with data plumbing through

pull/302/head
ElementalAlchemist 2 years ago committed by Mike Lang
parent 46ad45bdb9
commit 64f0ac714f

@ -190,6 +190,43 @@
<textarea id="video-info-description"></textarea> <textarea id="video-info-description"></textarea>
<label for="video-info-tags">Tags (comma-separated):</label> <label for="video-info-tags">Tags (comma-separated):</label>
<input type="text" id="video-info-tags" /> <input type="text" id="video-info-tags" />
<label for="video-info-thumbnail-mode">Thumbnail:</label>
<div id="video-info-thumbnail">
<div>
<select id="video-info-thumbnail-mode">
<option value="NONE">No custom thumbnail</option>
<option value="BARE">Use video frame</option>
<option value="TEMPLATE" selected>Use video frame in image template</option>
<option value="CUSTOM">Use a custom thumbnail image</option>
</select>
</div>
<div class="video-info-thumbnail-mode-options" id="video-info-thumbnail-template-options">
<select id="video-info-thumbnail-template">
<!-- TODO Implement options for template selection -->
</select>
</div>
<div class="video-info-thumbnail-mode-options" id="video-info-thumbnail-time-options">
<input type="text" id="video-info-thumbnail-time" />
<img
src="images/pencil.png"
alt="Set video thumbnail frame to current video time"
class="click"
id="video-info-thumbnail-time-set"
/>
<img
src="images/play_to.png"
alt="Set video time to video thumbnail frame"
class="click"
id="video-info-thumbnail-time-play"
/>
</div>
<div
class="hidden video-info-thumbnail-mode-options"
id="video-info-thumbnail-custom-options"
>
<input type="file" id="video-info-thumbnail-custom" accept="image/png" />
</div>
</div>
</div> </div>
<div id="submission"> <div id="submission">

@ -195,6 +195,40 @@ window.addEventListener("DOMContentLoaded", async (event) => {
document.getElementById("video-info-description").addEventListener("input", (_event) => { document.getElementById("video-info-description").addEventListener("input", (_event) => {
validateVideoDescription(); validateVideoDescription();
}); });
document.getElementById("video-info-thumbnail-mode").addEventListener("change", () => {
const newValue = document.getElementById("video-info-thumbnail-mode").value;
const unhideIDs = [];
if (newValue === "BARE") {
unhideIDs.push("video-info-thumbnail-time-options");
} else if (newValue === "TEMPLATE") {
unhideIDs.push("video-info-thumbnail-template-options");
unhideIDs.push("video-info-thumbnail-time-options");
} else if (newValue === "CUSTOM") {
unhideIDs.push("video-info-thumbnail-custom-options");
}
document.getElementsByClassName("video-info-thumbnail-mode-options").classList.add("hidden");
for (elemID of unhideIDs) {
document.getElementById(elemID).classList.remove("hidden");
}
});
document.getElementById("video-info-thumbnail-time-set").addEventListener("click", (_event) => {
const field = document.getElementById("video-info-thumbnail-time");
const videoPlayer = document.getElementById("video");
const videoPlayerTime = videoPlayer.currentTime;
field.value = videoHumanTimeFromVideoPlayerTime(videoPlayerTime);
});
document.getElementById("video-info-thumbnail-time-play").addEventListener("click", (_event) => {
const field = document.getElementById("video-info-thumbnail-time");
const thumbnailTime = videoPlayerTimeFromVideoHumanTime(field.value);
if (thumbnailTime === null) {
addError("Couldn't play from thumbnail frame; failed to parse time");
return;
}
const videoPlayer = document.getElementById("video");
videoPlayer.currentTime = thumbnailTime;
});
document.getElementById("submit-button").addEventListener("click", (_event) => { document.getElementById("submit-button").addEventListener("click", (_event) => {
submitVideo(); submitVideo();
@ -789,6 +823,53 @@ async function sendVideoData(newState, overrideChanges) {
videoDescription = videoDescription + CHAPTER_MARKER_DELIMITER + chapterTextList.join("\n"); videoDescription = videoDescription + CHAPTER_MARKER_DELIMITER + chapterTextList.join("\n");
} }
const thumbnailMode = document.getElementById("video-info-thumbnail-mode").value;
let thumbnailTemplate = null;
let thumbnailTime = null;
let thumbnailImage = null;
if (thumbnailMode === "BARE" || thumbnailMode === "TEMPLATE") {
thumbnailTime = wubloaderTimeFromVideoHumanTime(
document.getElementById("video-info-thumbnail-time").value
);
if (thumbnailTime === null) {
submissionResponseElem.innerText = "The thumbnail time is invalid";
submissionResponseElem.classList.value = ["submission-response-error"];
return;
}
}
if (thumbnailMode === "TEMPLATE") {
thumbnailTemplate = document.getElementById("video-info-thumbnail-template").value;
}
if (thumbnailMode === "CUSTOM") {
const fileInput = document.getElementById("video-info-thumbnail-custom");
if (fileInput.files.length === 0) {
submissionResponseElem.innerText =
"A thumbnail file was not provided for the custom thumbnail";
submissionResponseElem.classList.value = ["submission-response-error"];
return;
}
const fileHandle = fileInput.files[0];
const fileReader = new FileReader();
let loadPromiseResolve;
const loadPromise = new Promise((resolve, _reject) => {
loadPromiseResolve = resolve;
});
fileReader.addEventListener("loadend", (event) => {
loadPromiseResolve(event.target);
});
fileReader.readAsArrayBuffer(fileHandle);
const fileLoadData = await loadPromise;
if (fileLoadData.error) {
submissionResponseElem.innerText = `An error (${fileLoadData.error.name}) occurred loading the custom thumbnail: ${fileLoadData.error.message}`;
submissionResponseElem.classList.value = ["submission-response-error"];
return;
}
const fileData = fileLoadData.result;
const fileBytes = new Uint8Array(fileData);
const fileBinaryString = String.fromCharCode(...fileBytes);
thumbnailImage = btoa(fileBinaryString);
}
const videoTitle = document.getElementById("video-info-title").value; const videoTitle = document.getElementById("video-info-title").value;
const videoTags = document.getElementById("video-info-tags").value.split(","); const videoTags = document.getElementById("video-info-tags").value.split(",");
const allowHoles = document.getElementById("advanced-submission-option-allow-holes").checked; const allowHoles = document.getElementById("advanced-submission-option-allow-holes").checked;
@ -814,6 +895,10 @@ async function sendVideoData(newState, overrideChanges) {
video_quality: videoInfo.video_quality, video_quality: videoInfo.video_quality,
uploader_whitelist: uploaderAllowlist, uploader_whitelist: uploaderAllowlist,
state: newState, state: newState,
thumbnail_mode: thumbnailMode,
thumbnail_template: thumbnailTemplate,
thumbnail_time: thumbnailTime,
thumbnail_image: thumbnailImage,
// We also provide some sheet column values to verify data hasn't changed. // We also provide some sheet column values to verify data hasn't changed.
sheet_name: videoInfo.sheet_name, sheet_name: videoInfo.sheet_name,

Loading…
Cancel
Save