Auto-format JS files with prettier

Prettier is a tool for formatting JS files.
We add a minimal configuration to suit our purposes, and run it on all our JS files.

The main things this corrects is mixed tab and space indent issues (replacing fully with tabs),
overly long lines, inconsistent quote usage (prefers double-quotes instead), and missing semicolons.
pull/225/head
Mike Lang 3 years ago committed by Mike Lang
parent 6c97bd462e
commit ce73f7b0ea

@ -0,0 +1,11 @@
# Config for auto-formatting of our JS files using prettier
# https://prettier.io/docs/en/configuration.html
# This is NOT a length limit but a hint to the auto-formatter for how long lines should try to be.
printWidth: 100
# Use tabs for indentation, spaces for alignment
useTabs: true
# do {foo: bar} not { foo: bar }. personal preference.
bracketSpacing: false
# prefer "arg => body" over "(arg) => body" when possible
arrowParens: avoid

@ -1,17 +1,18 @@
var desertBusStart = new Date("1970-01-01T00:00:00Z"); var desertBusStart = new Date("1970-01-01T00:00:00Z");
var timeFormat = 'AGO'; var timeFormat = "AGO";
pageSetup = function (isEditor) { pageSetup = function (isEditor) {
//Get values from ThrimShim //Get values from ThrimShim
if (isEditor && /id=/.test(document.location.search)) { if (isEditor && /id=/.test(document.location.search)) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1]; var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
fetch("/thrimshim/"+rowId).then(data => data.json()).then(function (data) { fetch("/thrimshim/" + rowId)
.then(data => data.json())
.then(function (data) {
if (!data) { if (!data) {
alert("No video available for stream."); alert("No video available for stream.");
return; return;
} }
document.data = data document.data = data;
desertBusStart = new Date(data.bustime_start); desertBusStart = new Date(data.bustime_start);
document.getElementById("VideoTitlePrefix").value = data.title_prefix; document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
@ -19,18 +20,28 @@ pageSetup = function(isEditor) {
document.getElementById("StreamName").value = data.video_channel; document.getElementById("StreamName").value = data.video_channel;
document.getElementById("hiddenSubmissionID").value = data.id; document.getElementById("hiddenSubmissionID").value = data.id;
// for editor, switch to bustime since that's the default // for editor, switch to bustime since that's the default
timeFormat = 'BUSTIME'; timeFormat = "BUSTIME";
// Apply padding - start 1min early, finish 2min late because these times are generally // Apply padding - start 1min early, finish 2min late because these times are generally
// rounded down to the minute, so if something ends at "00:10" it might actually end // rounded down to the minute, so if something ends at "00:10" it might actually end
// at 00:10:59 so we should pad to 00:12:00. // at 00:10:59 so we should pad to 00:12:00.
var start = (data.event_start) ? new Date(fromTimestamp(data.event_start).getTime() - 60*1000) : null; var start = data.event_start
var end = (data.event_end) ? new Date(fromTimestamp(data.event_end).getTime() + 2*60*1000) : null; ? new Date(fromTimestamp(data.event_start).getTime() - 60 * 1000)
: null;
var end = data.event_end
? new Date(fromTimestamp(data.event_end).getTime() + 2 * 60 * 1000)
: null;
setTimeRange(start, end); setTimeRange(start, end);
// title and description both default to row description // title and description both default to row description
document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description; document.getElementById("VideoTitle").value = data.video_title
document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description; ? data.video_title
: data.description;
document.getElementById("VideoDescription").value = data.video_description
? data.video_description
: data.description;
// tags default to tags from sheet // tags default to tags from sheet
document.getElementById("VideoTags").value = tags_list_to_string(data.video_tags ? data.video_tags : data.tags); document.getElementById("VideoTags").value = tags_list_to_string(
data.video_tags ? data.video_tags : data.tags
);
// If any edit notes, show them // If any edit notes, show them
if (data.notes.length > 0) { if (data.notes.length > 0) {
@ -39,28 +50,31 @@ pageSetup = function(isEditor) {
} }
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane. // Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
setOptions('uploadLocation', data.upload_locations, data.upload_location); setOptions("uploadLocation", data.upload_locations, data.upload_location);
document.getElementById("AllowHoles").checked = data.allow_holes; document.getElementById("AllowHoles").checked = data.allow_holes;
document.getElementById("uploaderWhitelist").value = (!!data.uploader_whitelist) ? data.uploader_whitelist.join(",") : ""; document.getElementById("uploaderWhitelist").value = !!data.uploader_whitelist
? data.uploader_whitelist.join(",")
: "";
if ( if (
( (data.upload_locations.length > 0 &&
data.upload_locations.length > 0 data.upload_location != null &&
&& data.upload_location != null data.upload_location != data.upload_locations[0]) ||
&& data.upload_location != data.upload_locations[0] data.allow_holes ||
) !!data.uploader_whitelist
|| data.allow_holes
|| !!data.uploader_whitelist
) { ) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block"; document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
} }
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality); loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
}); });
} else {
if (isEditor) {
document.getElementById("SubmitButton").disabled = true;
} }
else {
if (isEditor) { document.getElementById('SubmitButton').disabled = true; }
fetch("/thrimshim/defaults").then(data => data.json()).then(function (data) { fetch("/thrimshim/defaults")
.then(data => data.json())
.then(function (data) {
if (!data) { if (!data) {
alert("Editor results call failed, is thrimshim running?"); alert("Editor results call failed, is thrimshim running?");
return; return;
@ -70,19 +84,18 @@ pageSetup = function(isEditor) {
if (isEditor) { if (isEditor) {
document.getElementById("VideoTitlePrefix").value = data.title_prefix; document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
setOptions('uploadLocation', data.upload_locations); setOptions("uploadLocation", data.upload_locations);
} }
// Default time format changes depending on mode. // Default time format changes depending on mode.
// But in both cases the default input value is 10min ago / "", // But in both cases the default input value is 10min ago / "",
// it's just for editor we convert it before the user sees. // it's just for editor we convert it before the user sees.
if (isEditor) { if (isEditor) {
toggleTimeInput('BUSTIME'); toggleTimeInput("BUSTIME");
} }
loadPlaylist(isEditor); loadPlaylist(isEditor);
}); });
} }
}; };
@ -94,12 +107,17 @@ parseDuration = function(duration) {
duration = duration.slice(1); duration = duration.slice(1);
direction = -1; direction = -1;
} }
var parts = duration.split(':'); var parts = duration.split(":");
return (parseInt(parts[0]) + (parts[1] || "0")/60 + (parts[2] || "0")/3600) * 60 * 60 * direction; return (
} (parseInt(parts[0]) + (parts[1] || "0") / 60 + (parts[2] || "0") / 3600) * 60 * 60 * direction
);
};
toBustime = function (date) { toBustime = function (date) {
return (date < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((date - desertBusStart)/1000), 600.01).padStart(7, "0:"); return (
(date < desertBusStart ? "-" : "") +
videojs.formatTime(Math.abs((date - desertBusStart) / 1000), 600.01).padStart(7, "0:")
);
}; };
fromBustime = function (bustime) { fromBustime = function (bustime) {
@ -108,20 +126,23 @@ fromBustime = function(bustime) {
toTimestamp = function (date) { toTimestamp = function (date) {
return date.toISOString().substring(0, 19); return date.toISOString().substring(0, 19);
} };
fromTimestamp = function (ts) { fromTimestamp = function (ts) {
return new Date(ts + "Z"); return new Date(ts + "Z");
} };
toAgo = function (date) { toAgo = function (date) {
now = new Date() now = new Date();
return (date < now ? "":"-") + videojs.formatTime(Math.abs((date - now)/1000), 600.01).padStart(7, "0:"); return (
} (date < now ? "" : "-") +
videojs.formatTime(Math.abs((date - now) / 1000), 600.01).padStart(7, "0:")
);
};
fromAgo = function (ago) { fromAgo = function (ago) {
return new Date(new Date().getTime() - 1000 * parseDuration(ago)); return new Date(new Date().getTime() - 1000 * parseDuration(ago));
} };
// Set the stream start/end range from a pair of Dates using the current format // Set the stream start/end range from a pair of Dates using the current format
// If given null, sets to blank. // If given null, sets to blank.
@ -131,9 +152,9 @@ setTimeRange = function(start, end) {
BUSTIME: toBustime, BUSTIME: toBustime,
AGO: toAgo, AGO: toAgo,
}[timeFormat]; }[timeFormat];
document.getElementById("StreamStart").value = (start) ? toFunc(start) : ""; document.getElementById("StreamStart").value = start ? toFunc(start) : "";
document.getElementById("StreamEnd").value = (end) ? toFunc(end) : ""; document.getElementById("StreamEnd").value = end ? toFunc(end) : "";
} };
// Get the current start/end range as Dates using the current format // Get the current start/end range as Dates using the current format
// Returns an object containing 'start' and 'end' fields. // Returns an object containing 'start' and 'end' fields.
@ -145,15 +166,17 @@ getTimeRange = function() {
AGO: fromAgo, AGO: fromAgo,
}[timeFormat]; }[timeFormat];
var convert = function (value) { var convert = function (value) {
if (!value) { return null; } if (!value) {
return null;
}
var date = fromFunc(value); var date = fromFunc(value);
return (isNaN(date)) ? null : date; return isNaN(date) ? null : date;
}; };
return { return {
start: convert(document.getElementById("StreamStart").value), start: convert(document.getElementById("StreamStart").value),
end: convert(document.getElementById("StreamEnd").value), end: convert(document.getElementById("StreamEnd").value),
}; };
} };
getTimeRangeAsTimestamp = function () { getTimeRangeAsTimestamp = function () {
var range = getTimeRange(); var range = getTimeRange();
@ -162,42 +185,52 @@ getTimeRangeAsTimestamp = function() {
start: range.start && toTimestamp(range.start), start: range.start && toTimestamp(range.start),
end: range.end && toTimestamp(range.end), end: range.end && toTimestamp(range.end),
}; };
} };
toggleHiddenPane = function (paneID) { toggleHiddenPane = function (paneID) {
var pane = document.getElementById(paneID); var pane = document.getElementById(paneID);
pane.style.display = (pane.style.display === "none") ? "block":"none"; pane.style.display = pane.style.display === "none" ? "block" : "none";
} };
toggleUltrawide = function () { toggleUltrawide = function () {
var body = document.getElementsByTagName("Body")[0]; var body = document.getElementsByTagName("Body")[0];
body.classList.contains("ultrawide") ? body.classList.remove("ultrawide"):body.classList.add("ultrawide"); body.classList.contains("ultrawide")
} ? body.classList.remove("ultrawide")
: body.classList.add("ultrawide");
};
toggleTimeInput = function (toggleInput) { toggleTimeInput = function (toggleInput) {
// Get times using current format, then change format, then write them back // Get times using current format, then change format, then write them back
var range = getTimeRange(); var range = getTimeRange();
timeFormat = toggleInput; timeFormat = toggleInput;
setTimeRange(range.start, range.end); setTimeRange(range.start, range.end);
} };
// For a given select input element id, add the given list of options. // For a given select input element id, add the given list of options.
// If selected is given, it should be the name of an option to select. // If selected is given, it should be the name of an option to select.
// Otherwise the first one is used. // Otherwise the first one is used.
setOptions = function (element, options, selected) { setOptions = function (element, options, selected) {
if (!selected && options.length > 0) { if (!selected && options.length > 0) {
selected = options[0] selected = options[0];
} }
options.forEach(function (option) { options.forEach(function (option) {
document.getElementById(element).innerHTML += '<option value="'+option+'" '+(option==selected ? 'selected':'')+'>'+option+'</option>'; document.getElementById(element).innerHTML +=
'<option value="' +
option +
'" ' +
(option == selected ? "selected" : "") +
">" +
option +
"</option>";
}); });
} };
buildQuery = function (params) { buildQuery = function (params) {
return Object.keys(params).filter(key => params[key] !== null).map(key => return Object.keys(params)
encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) .filter(key => params[key] !== null)
).join('&'); .map(key => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
} .join("&");
};
loadPlaylist = function (isEditor, startTrim, endTrim, defaultQuality) { loadPlaylist = function (isEditor, startTrim, endTrim, defaultQuality) {
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8"; var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
@ -209,40 +242,59 @@ loadPlaylist = function(isEditor, startTrim, endTrim, defaultQuality) {
if (player && player.trimmingControls && player.vhs.playlists.master) { if (player && player.trimmingControls && player.vhs.playlists.master) {
var discontinuities = mapDiscontinuities(); var discontinuities = mapDiscontinuities();
if (!startTrim) { if (!startTrim) {
startTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim); startTrim = getRealTimeForPlayerTime(
if (startTrim) {startTrim = startTrim.replace('Z','');} discontinuities,
player.trimmingControls().options.startTrim
);
if (startTrim) {
startTrim = startTrim.replace("Z", "");
}
} }
if (!endTrim) { if (!endTrim) {
endTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim); endTrim = getRealTimeForPlayerTime(
if (endTrim) {endTrim = endTrim.replace('Z','');} discontinuities,
player.trimmingControls().options.endTrim
);
if (endTrim) {
endTrim = endTrim.replace("Z", "");
}
} }
} }
setupPlayer(isEditor, playlist + '?' + queryString, startTrim, endTrim); setupPlayer(isEditor, playlist + "?" + queryString, startTrim, endTrim);
//Get quality levels for advanced properties / download //Get quality levels for advanced properties / download
document.getElementById('qualityLevel').innerHTML = ""; document.getElementById("qualityLevel").innerHTML = "";
fetch('/files/' + document.getElementById('StreamName').value).then(data => data.json()).then(function (data) { fetch("/files/" + document.getElementById("StreamName").value)
.then(data => data.json())
.then(function (data) {
if (!data.length) { if (!data.length) {
console.log("Could not retrieve quality levels"); console.log("Could not retrieve quality levels");
return; return;
} }
var qualityLevels = data.sort().reverse(); var qualityLevels = data.sort().reverse();
setOptions('qualityLevel', qualityLevels, defaultQuality); setOptions("qualityLevel", qualityLevels, defaultQuality);
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) { if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block"; document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
} }
}); });
}; };
thrimbletrimmerSubmit = function (state, override_changes = false) { thrimbletrimmerSubmit = function (state, override_changes = false) {
document.getElementById('SubmitButton').disabled = true; document.getElementById("SubmitButton").disabled = true;
var discontinuities = mapDiscontinuities(); var discontinuities = mapDiscontinuities();
var start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim); var start = getRealTimeForPlayerTime(
if (start) {start = start.replace('Z','');} discontinuities,
player.trimmingControls().options.startTrim
);
if (start) {
start = start.replace("Z", "");
}
var end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim); var end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
if (end) {end = end.replace('Z','');} if (end) {
end = end.replace("Z", "");
}
var wubData = { var wubData = {
video_start: start, video_start: start,
@ -250,11 +302,16 @@ thrimbletrimmerSubmit = function(state, override_changes=false) {
video_title: document.getElementById("VideoTitle").value, video_title: document.getElementById("VideoTitle").value,
video_description: document.getElementById("VideoDescription").value, video_description: document.getElementById("VideoDescription").value,
video_tags: tags_string_to_list(document.getElementById("VideoTags").value), video_tags: tags_string_to_list(document.getElementById("VideoTags").value),
allow_holes:document.getElementById('AllowHoles').checked, allow_holes: document.getElementById("AllowHoles").checked,
upload_location:document.getElementById('uploadLocation').value, upload_location: document.getElementById("uploadLocation").value,
video_channel: document.getElementById("StreamName").value, video_channel: document.getElementById("StreamName").value,
video_quality:document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value, video_quality:
uploader_whitelist:(document.getElementById('uploaderWhitelist').value ? document.getElementById('uploaderWhitelist').value.split(','):null), document.getElementById("qualityLevel").options[
document.getElementById("qualityLevel").options.selectedIndex
].value,
uploader_whitelist: document.getElementById("uploaderWhitelist").value
? document.getElementById("uploaderWhitelist").value.split(",")
: null,
state: state, state: state,
//pass back the sheet columns to check if any have changed //pass back the sheet columns to check if any have changed
sheet_name: document.data.sheet_name, sheet_name: document.data.sheet_name,
@ -266,7 +323,7 @@ thrimbletrimmerSubmit = function(state, override_changes=false) {
tags: document.data.tags, tags: document.data.tags,
}; };
if (!!user) { if (!!user) {
wubData.token = user.getAuthResponse().id_token wubData.token = user.getAuthResponse().id_token;
} }
if (override_changes) { if (override_changes) {
wubData["override_changes"] = true; wubData["override_changes"] = true;
@ -274,37 +331,44 @@ thrimbletrimmerSubmit = function(state, override_changes=false) {
console.log(wubData); console.log(wubData);
console.log(JSON.stringify(wubData)); console.log(JSON.stringify(wubData));
if (!wubData.video_start) {alert("No start time set"); return;} if (!wubData.video_start) {
if (!wubData.video_end) {alert("No end time set"); return;} alert("No start time set");
return;
}
if (!wubData.video_end) {
alert("No end time set");
return;
}
//Submit to thrimshim //Submit to thrimshim
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1]; var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
fetch("/thrimshim/" + rowId, { fetch("/thrimshim/" + rowId, {
method: 'POST', method: "POST",
headers: { headers: {
'Accept': 'application/json', Accept: "application/json",
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify(wubData) body: JSON.stringify(wubData),
}) }).then(response =>
.then(response => response.text().then(text => { response.text().then(text => {
if (!response.ok) { if (!response.ok) {
var error = response.statusText + ": " + text; var error = response.statusText + ": " + text;
if (response.status == 409) { if (response.status == 409) {
dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing" dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing";
if (confirm(dialogue)) { if (confirm(dialogue)) {
thrimbletrimmerSubmit(state, true); thrimbletrimmerSubmit(state, true);
} }
} else { } else {
alert(error); alert(error);
} }
} else if (state == 'EDITED') { } else if (state == "EDITED") {
alert(`Edit submitted for video from ${start} to ${end}`) alert(`Edit submitted for video from ${start} to ${end}`);
} else { } else {
alert("Draft saved"); alert("Draft saved");
} }
document.getElementById('SubmitButton').disabled = false; document.getElementById("SubmitButton").disabled = false;
})); })
);
}; };
thrimbletrimmerDownload = function (isEditor) { thrimbletrimmerDownload = function (isEditor) {
@ -315,45 +379,65 @@ thrimbletrimmerDownload = function(isEditor) {
return; return;
} }
var discontinuities = mapDiscontinuities(); var discontinuities = mapDiscontinuities();
range.start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim); range.start = getRealTimeForPlayerTime(
range.end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim); discontinuities,
player.trimmingControls().options.startTrim
);
range.end = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.endTrim
);
} }
var targetURL = "/cut/" + document.getElementById("StreamName").value + var targetURL =
"/"+document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value+".ts" + "/cut/" +
"?" + buildQuery({ document.getElementById("StreamName").value +
"/" +
document.getElementById("qualityLevel").options[
document.getElementById("qualityLevel").options.selectedIndex
].value +
".ts" +
"?" +
buildQuery({
start: range.start, start: range.start,
end: range.end, end: range.end,
// In non-editor, always use rough cut. They don't have the edit controls to do // In non-editor, always use rough cut. They don't have the edit controls to do
// fine time selection anyway. // fine time selection anyway.
type: (isEditor) ? ( type: isEditor
document.getElementById('DownloadType').options[document.getElementById('DownloadType').options.selectedIndex].value ? document.getElementById("DownloadType").options[
) : "rough", document.getElementById("DownloadType").options.selectedIndex
].value
: "rough",
// Always allow holes in non-editor, accidentially including holes isn't important // Always allow holes in non-editor, accidentially including holes isn't important
allow_holes: (isEditor) ? String(document.getElementById('AllowHoles').checked) : "true", allow_holes: isEditor ? String(document.getElementById("AllowHoles").checked) : "true",
}); });
console.log(targetURL); console.log(targetURL);
document.getElementById('DownloadLink').href = targetURL; document.getElementById("DownloadLink").href = targetURL;
document.getElementById('DownloadLink').style.display = ""; document.getElementById("DownloadLink").style.display = "";
}; };
thrimbletrimmerManualLink = function () { thrimbletrimmerManualLink = function () {
document.getElementById("ManualButton").disabled = true; document.getElementById("ManualButton").disabled = true;
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1]; var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
var upload_location = (document.getElementById("ManualYoutube").checked) ? "youtube-manual" : "manual"; var upload_location = document.getElementById("ManualYoutube").checked
var body = {link: document.getElementById("ManualLink").value, upload_location: upload_location}; ? "youtube-manual"
: "manual";
var body = {
link: document.getElementById("ManualLink").value,
upload_location: upload_location,
};
if (!!user) { if (!!user) {
body.token = user.getAuthResponse().id_token; body.token = user.getAuthResponse().id_token;
} }
fetch("/thrimshim/manual-link/" + rowId, { fetch("/thrimshim/manual-link/" + rowId, {
method: 'POST', method: "POST",
headers: { headers: {
'Accept': 'application/json', Accept: "application/json",
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify(body) body: JSON.stringify(body),
}) }).then(response =>
.then(response => response.text().then(text => { response.text().then(text => {
if (!response.ok) { if (!response.ok) {
var error = response.statusText + ": " + text; var error = response.statusText + ": " + text;
console.log(error); console.log(error);
@ -361,37 +445,43 @@ thrimbletrimmerManualLink = function() {
document.getElementById("ManualButton").disabled = false; document.getElementById("ManualButton").disabled = false;
} else { } else {
alert("Manual link set to " + body.link); alert("Manual link set to " + body.link);
setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); setTimeout(() => {
window.location.href = "/thrimbletrimmer/dashboard.html";
}, 500);
} }
})); })
);
}; };
thrimbletrimmerResetLink = function (force) { thrimbletrimmerResetLink = function (force) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1]; var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
if(force && !confirm( if (
'Are you sure you want to reset this event? ' + force &&
'This will set the row back to UNEDITED and forget about any video that already may exist. ' + !confirm(
'It is intended as a last-ditch command to clear a malfunctioning cutter, ' + "Are you sure you want to reset this event? " +
'or if a video needs to be re-edited and replaced. ' + "This will set the row back to UNEDITED and forget about any video that already may exist. " +
'IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. ' "It is intended as a last-ditch command to clear a malfunctioning cutter, " +
)) { "or if a video needs to be re-edited and replaced. " +
"IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. "
)
) {
return; return;
} }
document.getElementById("ResetButton").disabled = true; document.getElementById("ResetButton").disabled = true;
document.getElementById("CancelButton").disabled = true; document.getElementById("CancelButton").disabled = true;
var body = {} var body = {};
if (!!user) { if (!!user) {
body.token = user.getAuthResponse().id_token; body.token = user.getAuthResponse().id_token;
} }
fetch("/thrimshim/reset/" + rowId + "?force=" + force, { fetch("/thrimshim/reset/" + rowId + "?force=" + force, {
method: 'POST', method: "POST",
headers: { headers: {
'Accept': 'application/json', Accept: "application/json",
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify(body) body: JSON.stringify(body),
}) }).then(response =>
.then(response => response.text().then(text => { response.text().then(text => {
if (!response.ok) { if (!response.ok) {
var error = response.statusText + ": " + text; var error = response.statusText + ": " + text;
console.log(error); console.log(error);
@ -399,25 +489,27 @@ thrimbletrimmerResetLink = function(force) {
document.getElementById("ResetButton").disabled = false; document.getElementById("ResetButton").disabled = false;
document.getElementById("CancelButton").disabled = true; document.getElementById("CancelButton").disabled = true;
} else { } else {
alert("Row has been " + ((force) ? "reset" : "cancelled") +". Reloading..."); alert("Row has been " + (force ? "reset" : "cancelled") + ". Reloading...");
setTimeout(() => { window.location.reload(); }, 500); setTimeout(() => {
window.location.reload();
}, 500);
} }
})); })
);
}; };
tags_list_to_string = function (tag_list) { tags_list_to_string = function (tag_list) {
return tag_list.join(", "); return tag_list.join(", ");
} };
tags_string_to_list = function (tag_string) { tags_string_to_list = function (tag_string) {
return tag_string.split(",").map(tag => tag.trim()).filter(tag => tag.length > 0); return tag_string
} .split(",")
.map(tag => tag.trim())
.filter(tag => tag.length > 0);
};
round_trip_tag_string = function () { round_trip_tag_string = function () {
var element = document.getElementById("VideoTags"); var element = document.getElementById("VideoTags");
element.value = tags_list_to_string( element.value = tags_list_to_string(tags_string_to_list(element.value));
tags_string_to_list( };
element.value
)
);
}

@ -8,12 +8,12 @@ function changeSpeed(direction) {
var newIndex = currentIndex + direction; var newIndex = currentIndex + direction;
if (newIndex < 0 || newIndex >= speeds.length) { if (newIndex < 0 || newIndex >= speeds.length) {
// out of range // out of range
return return;
} }
player.playbackRate(speeds[newIndex]); player.playbackRate(speeds[newIndex]);
} }
document.addEventListener('keypress', (event) => { document.addEventListener("keypress", event => {
//if(event.target.nodeName == "BODY") { //if(event.target.nodeName == "BODY") {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") { if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.key) { switch (event.key) {
@ -34,17 +34,21 @@ document.addEventListener('keypress', (event) => {
player.currentTime(player.currentTime() + 0.1); player.currentTime(player.currentTime() + 0.1);
break; break;
case "i": case "i":
player.trimmingControls().updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim); player
.trimmingControls()
.updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim);
break; break;
case "o": case "o":
player.trimmingControls().updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime()); player
.trimmingControls()
.updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime());
break; break;
case "=": case "=":
changeSpeed(1); changeSpeed(1);
break break;
case "-": case "-":
changeSpeed(-1); changeSpeed(-1);
break break;
case "0": case "0":
player.currentTime(0); player.currentTime(0);
break; break;
@ -84,7 +88,7 @@ document.addEventListener('keypress', (event) => {
}); });
//Arrow keys only detected on keydown, keypress only works in "some" browsers //Arrow keys only detected on keydown, keypress only works in "some" browsers
document.addEventListener('keydown', (event) => { document.addEventListener("keydown", event => {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") { if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.keyCode) { switch (event.keyCode) {
case 37: case 37:
@ -93,7 +97,6 @@ document.addEventListener('keydown', (event) => {
case 39: case 39:
player.currentTime(player.currentTime() + 5); player.currentTime(player.currentTime() + 5);
break; break;
} }
} }
}); });

@ -16,11 +16,12 @@ function setupPlayer(isEditor, source, startTrim, endTrim) {
controlBar: { controlBar: {
fullscreenToggle: true, fullscreenToggle: true,
volumePanel: { volumePanel: {
inline: false inline: false,
} },
} },
}; };
if(player) { //Destroy and recreate the player if it already exists. if (player) {
//Destroy and recreate the player if it already exists.
player.dispose(); player.dispose();
document.getElementById("EditorContainer").innerHTML = ` document.getElementById("EditorContainer").innerHTML = `
<video id="my-player" class="video-js" controls disablePictureInPicture preload="auto"> <video id="my-player" class="video-js" controls disablePictureInPicture preload="auto">
@ -28,23 +29,25 @@ function setupPlayer(isEditor, source, startTrim, endTrim) {
</video> </video>
`; `;
} }
player = videojs('my-player', options, function onPlayerReady() { player = videojs("my-player", options, function onPlayerReady() {
videojs.log('Your player is ready!'); videojs.log("Your player is ready!");
// Set player volume to 50% by default // Set player volume to 50% by default
var defaultVolume = 0.5; var defaultVolume = 0.5;
this.volume(defaultVolume); this.volume(defaultVolume);
// In this context, `this` is the player that was created by Video.js. // In this context, `this` is the player that was created by Video.js.
this.on('ready', function() { this.on("ready", function () {
//this.play(); //this.play();
}); });
this.vhs.playlists.on('loadedmetadata', function() { this.vhs.playlists.on("loadedmetadata", function () {
// setTimeout(function() { player.play(); }, 1000); // setTimeout(function() { player.play(); }, 1000);
player.hasStarted(true); //So it displays all the controls. player.hasStarted(true); //So it displays all the controls.
if (isEditor) { if (isEditor) {
var stream_start = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.discontinuityStarts !== "undefined")[0].dateTimeObject; var stream_start = player.vhs.playlists.master.playlists.filter(
playlist => typeof playlist.discontinuityStarts !== "undefined"
)[0].dateTimeObject;
startTrim = startTrim ? (new Date(startTrim + "Z") - stream_start) / 1000 : 0; startTrim = startTrim ? (new Date(startTrim + "Z") - stream_start) / 1000 : 0;
endTrim = endTrim ? (new Date(endTrim + "Z") - stream_start) / 1000 : player.duration(); endTrim = endTrim ? (new Date(endTrim + "Z") - stream_start) / 1000 : player.duration();
var trimmingControls = player.trimmingControls({startTrim: startTrim, endTrim: endTrim}); var trimmingControls = player.trimmingControls({startTrim: startTrim, endTrim: endTrim});
@ -52,21 +55,29 @@ function setupPlayer(isEditor, source, startTrim, endTrim) {
}); });
// How about an event listener? // How about an event listener?
this.on('ended', function() { this.on("ended", function () {
videojs.log('Awww...over so soon?!'); videojs.log("Awww...over so soon?!");
}); });
this.on('error', function() { this.on("error", function () {
videojs.log("Could not load video stream"); videojs.log("Could not load video stream");
alert("No video available for stream."); alert("No video available for stream.");
}) });
}); });
var hlsQS = player.hlsQualitySelector(); var hlsQS = player.hlsQualitySelector();
} }
mapDiscontinuities = function () { mapDiscontinuities = function () {
var playlist = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.discontinuityStarts !== "undefined")[0]; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one. var playlist = player.vhs.playlists.master.playlists.filter(
var discontinuities = playlist.discontinuityStarts.map(segmentIndex => { return {segmentIndex:segmentIndex, segmentTimestamp:playlist.segments[segmentIndex].dateTimeObject, playbackIndex:null}; }); playlist => typeof playlist.discontinuityStarts !== "undefined"
)[0]; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
var discontinuities = playlist.discontinuityStarts.map(segmentIndex => {
return {
segmentIndex: segmentIndex,
segmentTimestamp: playlist.segments[segmentIndex].dateTimeObject,
playbackIndex: null,
};
});
//var lastDiscontinuity = Math.max(...playlist.discontinuityStarts); //var lastDiscontinuity = Math.max(...playlist.discontinuityStarts);
var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order. var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order.
@ -74,7 +85,8 @@ mapDiscontinuities = function() {
for (var index = 0; index <= lastDiscontinuity; index++) { for (var index = 0; index <= lastDiscontinuity; index++) {
let segment = playlist.segments[index]; let segment = playlist.segments[index];
if (segment.discontinuity) { if (segment.discontinuity) {
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex = durationMarker; discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex =
durationMarker;
} }
durationMarker += segment.duration; durationMarker += segment.duration;
} }
@ -83,10 +95,15 @@ mapDiscontinuities = function() {
}; };
getRealTimeForPlayerTime = function (discontinuities, playbackIndex) { getRealTimeForPlayerTime = function (discontinuities, playbackIndex) {
var streamStart = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.dateTimeObject !== "undefined")[0].dateTimeObject; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one. var streamStart = player.vhs.playlists.master.playlists.filter(
playlist => typeof playlist.dateTimeObject !== "undefined"
)[0].dateTimeObject; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
//Find last discontinuity before playbackIndex //Find last discontinuity before playbackIndex
var lastDiscontinuity = discontinuities.filter(discontinuity => discontinuity.playbackIndex < playbackIndex).slice(-1).pop(); var lastDiscontinuity = discontinuities
.filter(discontinuity => discontinuity.playbackIndex < playbackIndex)
.slice(-1)
.pop();
if (lastDiscontinuity) { if (lastDiscontinuity) {
streamStart = lastDiscontinuity.segmentTimestamp; streamStart = lastDiscontinuity.segmentTimestamp;
playbackIndex -= lastDiscontinuity.playbackIndex; playbackIndex -= lastDiscontinuity.playbackIndex;
@ -94,5 +111,5 @@ getRealTimeForPlayerTime = function(discontinuities, playbackIndex) {
var realTime = streamStart.getTime() + playbackIndex * 1000; var realTime = streamStart.getTime() + playbackIndex * 1000;
return (isFinite(realTime)) ? new Date(realTime).toISOString() : null; return isFinite(realTime) ? new Date(realTime).toISOString() : null;
}; };

Loading…
Cancel
Save