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,423 +1,515 @@
var desertBusStart = new Date("1970-01-01T00:00:00Z");
var timeFormat = 'AGO';
pageSetup = function(isEditor) {
//Get values from ThrimShim
if(isEditor && /id=/.test(document.location.search)) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
fetch("/thrimshim/"+rowId).then(data => data.json()).then(function (data) {
if (!data) {
alert("No video available for stream.");
return;
}
document.data = data
desertBusStart = new Date(data.bustime_start);
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
document.getElementById("StreamName").value = data.video_channel;
document.getElementById("hiddenSubmissionID").value = data.id;
// for editor, switch to bustime since that's the default
timeFormat = 'BUSTIME';
// 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
// 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 end = (data.event_end) ? new Date(fromTimestamp(data.event_end).getTime() + 2*60*1000) : null;
setTimeRange(start, end);
// title and description both default to row description
document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description;
document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description;
// tags default to tags from sheet
document.getElementById("VideoTags").value = tags_list_to_string(data.video_tags ? data.video_tags : data.tags);
// If any edit notes, show them
if (data.notes.length > 0) {
document.getElementById("EditNotes").value = data.notes;
document.getElementById("EditNotesPane").style.display = "block";
}
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
setOptions('uploadLocation', data.upload_locations, data.upload_location);
document.getElementById("AllowHoles").checked = data.allow_holes;
document.getElementById("uploaderWhitelist").value = (!!data.uploader_whitelist) ? data.uploader_whitelist.join(",") : "";
if (
(
data.upload_locations.length > 0
&& data.upload_location != null
&& data.upload_location != data.upload_locations[0]
)
|| data.allow_holes
|| !!data.uploader_whitelist
) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
}
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
});
}
else {
if (isEditor) { document.getElementById('SubmitButton').disabled = true; }
fetch("/thrimshim/defaults").then(data => data.json()).then(function (data) {
if (!data) {
alert("Editor results call failed, is thrimshim running?");
return;
}
desertBusStart = new Date(data.bustime_start);
document.getElementById("StreamName").value = data.video_channel;
if (isEditor) {
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
setOptions('uploadLocation', data.upload_locations);
}
// Default time format changes depending on mode.
// But in both cases the default input value is 10min ago / "",
// it's just for editor we convert it before the user sees.
if (isEditor) {
toggleTimeInput('BUSTIME');
}
loadPlaylist(isEditor);
});
}
var timeFormat = "AGO";
pageSetup = function (isEditor) {
//Get values from ThrimShim
if (isEditor && /id=/.test(document.location.search)) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
fetch("/thrimshim/" + rowId)
.then(data => data.json())
.then(function (data) {
if (!data) {
alert("No video available for stream.");
return;
}
document.data = data;
desertBusStart = new Date(data.bustime_start);
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
document.getElementById("StreamName").value = data.video_channel;
document.getElementById("hiddenSubmissionID").value = data.id;
// for editor, switch to bustime since that's the default
timeFormat = "BUSTIME";
// 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
// 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 end = data.event_end
? new Date(fromTimestamp(data.event_end).getTime() + 2 * 60 * 1000)
: null;
setTimeRange(start, end);
// title and description both default to row description
document.getElementById("VideoTitle").value = data.video_title
? data.video_title
: data.description;
document.getElementById("VideoDescription").value = data.video_description
? data.video_description
: data.description;
// tags default to tags from sheet
document.getElementById("VideoTags").value = tags_list_to_string(
data.video_tags ? data.video_tags : data.tags
);
// If any edit notes, show them
if (data.notes.length > 0) {
document.getElementById("EditNotes").value = data.notes;
document.getElementById("EditNotesPane").style.display = "block";
}
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
setOptions("uploadLocation", data.upload_locations, data.upload_location);
document.getElementById("AllowHoles").checked = data.allow_holes;
document.getElementById("uploaderWhitelist").value = !!data.uploader_whitelist
? data.uploader_whitelist.join(",")
: "";
if (
(data.upload_locations.length > 0 &&
data.upload_location != null &&
data.upload_location != data.upload_locations[0]) ||
data.allow_holes ||
!!data.uploader_whitelist
) {
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
}
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
});
} else {
if (isEditor) {
document.getElementById("SubmitButton").disabled = true;
}
fetch("/thrimshim/defaults")
.then(data => data.json())
.then(function (data) {
if (!data) {
alert("Editor results call failed, is thrimshim running?");
return;
}
desertBusStart = new Date(data.bustime_start);
document.getElementById("StreamName").value = data.video_channel;
if (isEditor) {
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
setOptions("uploadLocation", data.upload_locations);
}
// Default time format changes depending on mode.
// But in both cases the default input value is 10min ago / "",
// it's just for editor we convert it before the user sees.
if (isEditor) {
toggleTimeInput("BUSTIME");
}
loadPlaylist(isEditor);
});
}
};
// Time-formatting functions
parseDuration = function(duration) {
var direction = 1;
if(duration.startsWith("-")) {
duration = duration.slice(1);
direction = -1;
}
var parts = duration.split(':');
return (parseInt(parts[0]) + (parts[1] || "0")/60 + (parts[2] || "0")/3600) * 60 * 60 * direction;
}
toBustime = function(date) {
return (date < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((date - desertBusStart)/1000), 600.01).padStart(7, "0:");
parseDuration = function (duration) {
var direction = 1;
if (duration.startsWith("-")) {
duration = duration.slice(1);
direction = -1;
}
var parts = duration.split(":");
return (
(parseInt(parts[0]) + (parts[1] || "0") / 60 + (parts[2] || "0") / 3600) * 60 * 60 * direction
);
};
toBustime = function (date) {
return (
(date < desertBusStart ? "-" : "") +
videojs.formatTime(Math.abs((date - desertBusStart) / 1000), 600.01).padStart(7, "0:")
);
};
fromBustime = function(bustime) {
return new Date(desertBusStart.getTime() + 1000 * parseDuration(bustime));
fromBustime = function (bustime) {
return new Date(desertBusStart.getTime() + 1000 * parseDuration(bustime));
};
toTimestamp = function(date) {
return date.toISOString().substring(0, 19);
}
toTimestamp = function (date) {
return date.toISOString().substring(0, 19);
};
fromTimestamp = function(ts) {
return new Date(ts + "Z");
}
fromTimestamp = function (ts) {
return new Date(ts + "Z");
};
toAgo = function(date) {
now = new Date()
return (date < now ? "":"-") + videojs.formatTime(Math.abs((date - now)/1000), 600.01).padStart(7, "0:");
}
toAgo = function (date) {
now = new Date();
return (
(date < now ? "" : "-") +
videojs.formatTime(Math.abs((date - now) / 1000), 600.01).padStart(7, "0:")
);
};
fromAgo = function(ago) {
return new Date(new Date().getTime() - 1000 * parseDuration(ago));
}
fromAgo = function (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
// If given null, sets to blank.
setTimeRange = function(start, end) {
var toFunc = {
UTC: toTimestamp,
BUSTIME: toBustime,
AGO: toAgo,
}[timeFormat];
document.getElementById("StreamStart").value = (start) ? toFunc(start) : "";
document.getElementById("StreamEnd").value = (end) ? toFunc(end) : "";
}
setTimeRange = function (start, end) {
var toFunc = {
UTC: toTimestamp,
BUSTIME: toBustime,
AGO: toAgo,
}[timeFormat];
document.getElementById("StreamStart").value = start ? toFunc(start) : "";
document.getElementById("StreamEnd").value = end ? toFunc(end) : "";
};
// Get the current start/end range as Dates using the current format
// Returns an object containing 'start' and 'end' fields.
// If either is empty / invalid, returns null.
getTimeRange = function() {
var fromFunc = {
UTC: fromTimestamp,
BUSTIME: fromBustime,
AGO: fromAgo,
}[timeFormat];
var convert = function(value) {
if (!value) { return null; }
var date = fromFunc(value);
return (isNaN(date)) ? null : date;
};
return {
start: convert(document.getElementById("StreamStart").value),
end: convert(document.getElementById("StreamEnd").value),
};
}
getTimeRangeAsTimestamp = function() {
var range = getTimeRange();
return {
// if not null, format as timestamp
start: range.start && toTimestamp(range.start),
end: range.end && toTimestamp(range.end),
};
}
toggleHiddenPane = function(paneID) {
var pane = document.getElementById(paneID);
pane.style.display = (pane.style.display === "none") ? "block":"none";
}
toggleUltrawide = function() {
var body = document.getElementsByTagName("Body")[0];
body.classList.contains("ultrawide") ? body.classList.remove("ultrawide"):body.classList.add("ultrawide");
}
toggleTimeInput = function(toggleInput) {
// Get times using current format, then change format, then write them back
var range = getTimeRange();
timeFormat = toggleInput;
setTimeRange(range.start, range.end);
}
getTimeRange = function () {
var fromFunc = {
UTC: fromTimestamp,
BUSTIME: fromBustime,
AGO: fromAgo,
}[timeFormat];
var convert = function (value) {
if (!value) {
return null;
}
var date = fromFunc(value);
return isNaN(date) ? null : date;
};
return {
start: convert(document.getElementById("StreamStart").value),
end: convert(document.getElementById("StreamEnd").value),
};
};
getTimeRangeAsTimestamp = function () {
var range = getTimeRange();
return {
// if not null, format as timestamp
start: range.start && toTimestamp(range.start),
end: range.end && toTimestamp(range.end),
};
};
toggleHiddenPane = function (paneID) {
var pane = document.getElementById(paneID);
pane.style.display = pane.style.display === "none" ? "block" : "none";
};
toggleUltrawide = function () {
var body = document.getElementsByTagName("Body")[0];
body.classList.contains("ultrawide")
? body.classList.remove("ultrawide")
: body.classList.add("ultrawide");
};
toggleTimeInput = function (toggleInput) {
// Get times using current format, then change format, then write them back
var range = getTimeRange();
timeFormat = toggleInput;
setTimeRange(range.start, range.end);
};
// 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.
// Otherwise the first one is used.
setOptions = function(element, options, selected) {
if (!selected && options.length > 0) {
selected = options[0]
}
options.forEach(function(option) {
document.getElementById(element).innerHTML += '<option value="'+option+'" '+(option==selected ? 'selected':'')+'>'+option+'</option>';
});
}
buildQuery = function(params) {
return Object.keys(params).filter(key => params[key] !== null).map(key =>
encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
).join('&');
}
loadPlaylist = function(isEditor, startTrim, endTrim, defaultQuality) {
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
var range = getTimeRangeAsTimestamp();
var queryString = buildQuery(range);
setOptions = function (element, options, selected) {
if (!selected && options.length > 0) {
selected = options[0];
}
options.forEach(function (option) {
document.getElementById(element).innerHTML +=
'<option value="' +
option +
'" ' +
(option == selected ? "selected" : "") +
">" +
option +
"</option>";
});
};
buildQuery = function (params) {
return Object.keys(params)
.filter(key => params[key] !== null)
.map(key => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
.join("&");
};
loadPlaylist = function (isEditor, startTrim, endTrim, defaultQuality) {
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
var range = getTimeRangeAsTimestamp();
var queryString = buildQuery(range);
// Preserve existing edit times
if (player && player.trimmingControls && player.vhs.playlists.master) {
var discontinuities = mapDiscontinuities();
if (!startTrim) {
startTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
if (startTrim) {startTrim = startTrim.replace('Z','');}
startTrim = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
if (startTrim) {
startTrim = startTrim.replace("Z", "");
}
}
if (!endTrim) {
endTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
if (endTrim) {endTrim = endTrim.replace('Z','');}
endTrim = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.endTrim
);
if (endTrim) {
endTrim = endTrim.replace("Z", "");
}
}
}
setupPlayer(isEditor, playlist + '?' + queryString, startTrim, endTrim);
//Get quality levels for advanced properties / download
document.getElementById('qualityLevel').innerHTML = "";
fetch('/files/' + document.getElementById('StreamName').value).then(data => data.json()).then(function (data) {
if (!data.length) {
console.log("Could not retrieve quality levels");
return;
}
var qualityLevels = data.sort().reverse();
setOptions('qualityLevel', qualityLevels, defaultQuality);
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
}
});
setupPlayer(isEditor, playlist + "?" + queryString, startTrim, endTrim);
//Get quality levels for advanced properties / download
document.getElementById("qualityLevel").innerHTML = "";
fetch("/files/" + document.getElementById("StreamName").value)
.then(data => data.json())
.then(function (data) {
if (!data.length) {
console.log("Could not retrieve quality levels");
return;
}
var qualityLevels = data.sort().reverse();
setOptions("qualityLevel", qualityLevels, defaultQuality);
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
}
});
};
thrimbletrimmerSubmit = function(state, override_changes=false) {
document.getElementById('SubmitButton').disabled = true;
var discontinuities = mapDiscontinuities();
thrimbletrimmerSubmit = function (state, override_changes = false) {
document.getElementById("SubmitButton").disabled = true;
var discontinuities = mapDiscontinuities();
var start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
if (start) {start = start.replace('Z','');}
var start = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
if (start) {
start = start.replace("Z", "");
}
var end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
if (end) {end = end.replace('Z','');}
var wubData = {
video_start:start,
video_end:end,
video_title:document.getElementById("VideoTitle").value,
video_description:document.getElementById("VideoDescription").value,
video_tags:tags_string_to_list(document.getElementById("VideoTags").value),
allow_holes:document.getElementById('AllowHoles').checked,
upload_location:document.getElementById('uploadLocation').value,
video_channel:document.getElementById("StreamName").value,
video_quality:document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value,
uploader_whitelist:(document.getElementById('uploaderWhitelist').value ? document.getElementById('uploaderWhitelist').value.split(','):null),
state:state,
if (end) {
end = end.replace("Z", "");
}
var wubData = {
video_start: start,
video_end: end,
video_title: document.getElementById("VideoTitle").value,
video_description: document.getElementById("VideoDescription").value,
video_tags: tags_string_to_list(document.getElementById("VideoTags").value),
allow_holes: document.getElementById("AllowHoles").checked,
upload_location: document.getElementById("uploadLocation").value,
video_channel: document.getElementById("StreamName").value,
video_quality:
document.getElementById("qualityLevel").options[
document.getElementById("qualityLevel").options.selectedIndex
].value,
uploader_whitelist: document.getElementById("uploaderWhitelist").value
? document.getElementById("uploaderWhitelist").value.split(",")
: null,
state: state,
//pass back the sheet columns to check if any have changed
sheet_name:document.data.sheet_name,
event_start:document.data.event_start,
event_end:document.data.event_end,
category:document.data.category,
description:document.data.description,
notes:document.data.notes,
tags:document.data.tags,
};
if (!!user) {
wubData.token = user.getAuthResponse().id_token
}
sheet_name: document.data.sheet_name,
event_start: document.data.event_start,
event_end: document.data.event_end,
category: document.data.category,
description: document.data.description,
notes: document.data.notes,
tags: document.data.tags,
};
if (!!user) {
wubData.token = user.getAuthResponse().id_token;
}
if (override_changes) {
wubData["override_changes"] = true;
}
console.log(wubData);
console.log(JSON.stringify(wubData));
console.log(wubData);
console.log(JSON.stringify(wubData));
if (!wubData.video_start) {alert("No start time set"); return;}
if (!wubData.video_end) {alert("No end time set"); return;}
if (!wubData.video_start) {
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];
fetch("/thrimshim/" + rowId, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(wubData)
})
.then(response => response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
if (response.status == 409) {
dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing"
if (confirm(dialogue)) {
thrimbletrimmerSubmit(state, true);
}
} else {
alert(error);
}
} else if (state == 'EDITED') {
alert(`Edit submitted for video from ${start} to ${end}`)
} else {
alert("Draft saved");
}
document.getElementById('SubmitButton').disabled = false;
}));
fetch("/thrimshim/" + rowId, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(wubData),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
if (response.status == 409) {
dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing";
if (confirm(dialogue)) {
thrimbletrimmerSubmit(state, true);
}
} else {
alert(error);
}
} else if (state == "EDITED") {
alert(`Edit submitted for video from ${start} to ${end}`);
} else {
alert("Draft saved");
}
document.getElementById("SubmitButton").disabled = false;
})
);
};
thrimbletrimmerDownload = function(isEditor) {
var range = getTimeRangeAsTimestamp();
if (isEditor) {
if(player.trimmingControls().options.startTrim >= player.trimmingControls().options.endTrim) {
alert("End Time must be greater than Start Time");
return;
}
var discontinuities = mapDiscontinuities();
range.start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
range.end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
}
var targetURL = "/cut/" + document.getElementById("StreamName").value +
"/"+document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value+".ts" +
"?" + buildQuery({
start: range.start,
end: range.end,
thrimbletrimmerDownload = function (isEditor) {
var range = getTimeRangeAsTimestamp();
if (isEditor) {
if (player.trimmingControls().options.startTrim >= player.trimmingControls().options.endTrim) {
alert("End Time must be greater than Start Time");
return;
}
var discontinuities = mapDiscontinuities();
range.start = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
range.end = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.endTrim
);
}
var targetURL =
"/cut/" +
document.getElementById("StreamName").value +
"/" +
document.getElementById("qualityLevel").options[
document.getElementById("qualityLevel").options.selectedIndex
].value +
".ts" +
"?" +
buildQuery({
start: range.start,
end: range.end,
// In non-editor, always use rough cut. They don't have the edit controls to do
// fine time selection anyway.
type: (isEditor) ? (
document.getElementById('DownloadType').options[document.getElementById('DownloadType').options.selectedIndex].value
) : "rough",
// Always allow holes in non-editor, accidentially including holes isn't important
allow_holes: (isEditor) ? String(document.getElementById('AllowHoles').checked) : "true",
});
console.log(targetURL);
document.getElementById('DownloadLink').href = targetURL;
document.getElementById('DownloadLink').style.display = "";
type: isEditor
? document.getElementById("DownloadType").options[
document.getElementById("DownloadType").options.selectedIndex
].value
: "rough",
// Always allow holes in non-editor, accidentially including holes isn't important
allow_holes: isEditor ? String(document.getElementById("AllowHoles").checked) : "true",
});
console.log(targetURL);
document.getElementById("DownloadLink").href = targetURL;
document.getElementById("DownloadLink").style.display = "";
};
thrimbletrimmerManualLink = function() {
document.getElementById("ManualButton").disabled = true;
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
var upload_location = (document.getElementById("ManualYoutube").checked) ? "youtube-manual" : "manual";
var body = {link: document.getElementById("ManualLink").value, upload_location: upload_location};
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/manual-link/"+rowId, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
.then(response => response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
alert(error);
document.getElementById("ManualButton").disabled = false;
} else {
alert("Manual link set to " + body.link);
setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500);
}
}));
thrimbletrimmerManualLink = function () {
document.getElementById("ManualButton").disabled = true;
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
var upload_location = document.getElementById("ManualYoutube").checked
? "youtube-manual"
: "manual";
var body = {
link: document.getElementById("ManualLink").value,
upload_location: upload_location,
};
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/manual-link/" + rowId, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
alert(error);
document.getElementById("ManualButton").disabled = false;
} else {
alert("Manual link set to " + body.link);
setTimeout(() => {
window.location.href = "/thrimbletrimmer/dashboard.html";
}, 500);
}
})
);
};
thrimbletrimmerResetLink = function(force) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
if(force && !confirm(
'Are you sure you want to reset this event? ' +
'This will set the row back to UNEDITED and forget about any video that already may exist. ' +
'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;
}
document.getElementById("ResetButton").disabled = true;
document.getElementById("CancelButton").disabled = true;
var body = {}
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/reset/"+rowId + "?force=" + force, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
.then(response => response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
alert(error);
document.getElementById("ResetButton").disabled = false;
document.getElementById("CancelButton").disabled = true;
} else {
alert("Row has been " + ((force) ? "reset" : "cancelled") +". Reloading...");
setTimeout(() => { window.location.reload(); }, 500);
}
}));
thrimbletrimmerResetLink = function (force) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
if (
force &&
!confirm(
"Are you sure you want to reset this event? " +
"This will set the row back to UNEDITED and forget about any video that already may exist. " +
"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;
}
document.getElementById("ResetButton").disabled = true;
document.getElementById("CancelButton").disabled = true;
var body = {};
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/reset/" + rowId + "?force=" + force, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
alert(error);
document.getElementById("ResetButton").disabled = false;
document.getElementById("CancelButton").disabled = true;
} else {
alert("Row has been " + (force ? "reset" : "cancelled") + ". Reloading...");
setTimeout(() => {
window.location.reload();
}, 500);
}
})
);
};
tags_list_to_string = function(tag_list) {
tags_list_to_string = function (tag_list) {
return tag_list.join(", ");
}
};
tags_string_to_list = function(tag_string) {
return tag_string.split(",").map(tag => tag.trim()).filter(tag => tag.length > 0);
}
tags_string_to_list = function (tag_string) {
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");
element.value = tags_list_to_string(
tags_string_to_list(
element.value
)
);
}
element.value = tags_list_to_string(tags_string_to_list(element.value));
};

@ -8,92 +8,95 @@ function changeSpeed(direction) {
var newIndex = currentIndex + direction;
if (newIndex < 0 || newIndex >= speeds.length) {
// out of range
return
return;
}
player.playbackRate(speeds[newIndex]);
}
document.addEventListener('keypress', (event) => {
//if(event.target.nodeName == "BODY") {
if(event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch(event.key) {
case "j":
player.currentTime(player.currentTime()-10);
break;
case "k":
case " ": // also pause on space
player.paused() ? player.play():player.pause();
break;
case "l":
player.currentTime(player.currentTime()+10);
break;
case ",":
player.currentTime(player.currentTime()-0.1);
break;
case ".":
player.currentTime(player.currentTime()+0.1);
break;
case "i":
player.trimmingControls().updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim);
break;
case "o":
player.trimmingControls().updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime());
break;
document.addEventListener("keypress", event => {
//if(event.target.nodeName == "BODY") {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.key) {
case "j":
player.currentTime(player.currentTime() - 10);
break;
case "k":
case " ": // also pause on space
player.paused() ? player.play() : player.pause();
break;
case "l":
player.currentTime(player.currentTime() + 10);
break;
case ",":
player.currentTime(player.currentTime() - 0.1);
break;
case ".":
player.currentTime(player.currentTime() + 0.1);
break;
case "i":
player
.trimmingControls()
.updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim);
break;
case "o":
player
.trimmingControls()
.updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime());
break;
case "=":
changeSpeed(1);
break
break;
case "-":
changeSpeed(-1);
break
case "0":
player.currentTime(0);
break;
case "1":
player.currentTime(player.duration()*0.1);
break;
case "2":
player.currentTime(player.duration()*0.2);
break;
case "3":
player.currentTime(player.duration()*0.3);
break;
case "4":
player.currentTime(player.duration()*0.4);
break;
case "5":
player.currentTime(player.duration()*0.5);
break;
case "6":
player.currentTime(player.duration()*0.6);
break;
case "7":
player.currentTime(player.duration()*0.7);
break;
case "8":
player.currentTime(player.duration()*0.8);
break;
case "9":
player.currentTime(player.duration()*0.9);
break;
}
}
break;
case "0":
player.currentTime(0);
break;
case "1":
player.currentTime(player.duration() * 0.1);
break;
case "2":
player.currentTime(player.duration() * 0.2);
break;
case "3":
player.currentTime(player.duration() * 0.3);
break;
case "4":
player.currentTime(player.duration() * 0.4);
break;
case "5":
player.currentTime(player.duration() * 0.5);
break;
case "6":
player.currentTime(player.duration() * 0.6);
break;
case "7":
player.currentTime(player.duration() * 0.7);
break;
case "8":
player.currentTime(player.duration() * 0.8);
break;
case "9":
player.currentTime(player.duration() * 0.9);
break;
}
}
// const keyName = event.key;
// console.log('keypress event\n\n' + 'key: ' + keyName);
// console.log(event.target.nodeName);
// const keyName = event.key;
// console.log('keypress event\n\n' + 'key: ' + keyName);
// console.log(event.target.nodeName);
});
//Arrow keys only detected on keydown, keypress only works in "some" browsers
document.addEventListener('keydown', (event) => {
if(event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch(event.keyCode) {
case 37:
player.currentTime(player.currentTime()-5);
break;
case 39:
player.currentTime(player.currentTime()+5);
break;
}
}
document.addEventListener("keydown", event => {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.keyCode) {
case 37:
player.currentTime(player.currentTime() - 5);
break;
case 39:
player.currentTime(player.currentTime() + 5);
break;
}
}
});

@ -1,98 +1,115 @@
var player = null;
function setupPlayer(isEditor, source, startTrim, endTrim) {
document.getElementById("my-player").style.display = "";
//Make poster of DB logo in correct aspect ratio, to control initial size of fluid container.
var options = {
sources: [{ src: source }],
liveui: true,
//fluid:true,
controls:true,
autoplay:false,
width:1280,
height:420,
playbackRates: [0.5, 1, 1.25, 1.5, 2],
inactivityTimeout: 0,
controlBar: {
fullscreenToggle: true,
volumePanel: {
inline: false
}
}
};
if(player) { //Destroy and recreate the player if it already exists.
player.dispose();
document.getElementById("EditorContainer").innerHTML = `
document.getElementById("my-player").style.display = "";
//Make poster of DB logo in correct aspect ratio, to control initial size of fluid container.
var options = {
sources: [{src: source}],
liveui: true,
//fluid:true,
controls: true,
autoplay: false,
width: 1280,
height: 420,
playbackRates: [0.5, 1, 1.25, 1.5, 2],
inactivityTimeout: 0,
controlBar: {
fullscreenToggle: true,
volumePanel: {
inline: false,
},
},
};
if (player) {
//Destroy and recreate the player if it already exists.
player.dispose();
document.getElementById("EditorContainer").innerHTML = `
<video id="my-player" class="video-js" controls disablePictureInPicture preload="auto">
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
</video>
`;
}
player = videojs('my-player', options, function onPlayerReady() {
videojs.log('Your player is ready!');
}
player = videojs("my-player", options, function onPlayerReady() {
videojs.log("Your player is ready!");
// Set player volume to 50% by default
var defaultVolume = 0.5;
this.volume(defaultVolume);
// Set player volume to 50% by default
var defaultVolume = 0.5;
this.volume(defaultVolume);
// In this context, `this` is the player that was created by Video.js.
this.on('ready', function() {
//this.play();
});
// In this context, `this` is the player that was created by Video.js.
this.on("ready", function () {
//this.play();
});
this.vhs.playlists.on('loadedmetadata', function() {
// setTimeout(function() { player.play(); }, 1000);
player.hasStarted(true); //So it displays all the controls.
if (isEditor) {
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;
endTrim = endTrim ? (new Date(endTrim+"Z")-stream_start)/1000:player.duration();
var trimmingControls = player.trimmingControls({ startTrim:startTrim, endTrim:endTrim });
}
});
this.vhs.playlists.on("loadedmetadata", function () {
// setTimeout(function() { player.play(); }, 1000);
player.hasStarted(true); //So it displays all the controls.
if (isEditor) {
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;
endTrim = endTrim ? (new Date(endTrim + "Z") - stream_start) / 1000 : player.duration();
var trimmingControls = player.trimmingControls({startTrim: startTrim, endTrim: endTrim});
}
});
// How about an event listener?
this.on('ended', function() {
videojs.log('Awww...over so soon?!');
});
// How about an event listener?
this.on("ended", function () {
videojs.log("Awww...over so soon?!");
});
this.on('error', function() {
videojs.log("Could not load video stream");
alert("No video available for stream.");
})
});
var hlsQS = player.hlsQualitySelector();
this.on("error", function () {
videojs.log("Could not load video stream");
alert("No video available for stream.");
});
});
var hlsQS = player.hlsQualitySelector();
}
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 discontinuities = playlist.discontinuityStarts.map(segmentIndex => { return {segmentIndex:segmentIndex, segmentTimestamp:playlist.segments[segmentIndex].dateTimeObject, playbackIndex:null}; });
//var lastDiscontinuity = Math.max(...playlist.discontinuityStarts);
var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order.
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 discontinuities = playlist.discontinuityStarts.map(segmentIndex => {
return {
segmentIndex: segmentIndex,
segmentTimestamp: playlist.segments[segmentIndex].dateTimeObject,
playbackIndex: null,
};
});
//var lastDiscontinuity = Math.max(...playlist.discontinuityStarts);
var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order.
var durationMarker = 0;
for (var index = 0; index <= lastDiscontinuity; index++) {
let segment = playlist.segments[index];
if(segment.discontinuity) {
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex = durationMarker;
}
durationMarker += segment.duration;
}
var durationMarker = 0;
for (var index = 0; index <= lastDiscontinuity; index++) {
let segment = playlist.segments[index];
if (segment.discontinuity) {
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex =
durationMarker;
}
durationMarker += segment.duration;
}
return discontinuities;
return discontinuities;
};
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.
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.
//Find last discontinuity before playbackIndex
var lastDiscontinuity = discontinuities.filter(discontinuity => discontinuity.playbackIndex < playbackIndex).slice(-1).pop();
if(lastDiscontinuity) {
streamStart = lastDiscontinuity.segmentTimestamp;
playbackIndex -= lastDiscontinuity.playbackIndex;
}
//Find last discontinuity before playbackIndex
var lastDiscontinuity = discontinuities
.filter(discontinuity => discontinuity.playbackIndex < playbackIndex)
.slice(-1)
.pop();
if (lastDiscontinuity) {
streamStart = lastDiscontinuity.segmentTimestamp;
playbackIndex -= lastDiscontinuity.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