video-privacy-today/plugin-api.js

199 lines
5.5 KiB
JavaScript

const MAX_COUNTDOWN = 60;
var countdown = MAX_COUNTDOWN;
var now = Date.now();
var eventsOnNow = [];
var eventsOnNext = [];
grist.ready({
requiredAccess: 'read table'
});
grist.onRecords(function (records) {
eventsOnNow = [];
eventsOnNext = [];
now = Date.now();
var i = 0;
for (const r of records) {
let privacy = r["video_privacy"];
let videoNeeded = r["Video_team_attending"];
if (privacy == "none" || videoNeeded == true) {
let e = new Event(
i++,
r["title"],
r["venue"],
videoNeeded,
privacy,
r["Comments"],
Date.parse(r["start_date"]),
Date.parse(r["end_date"])
);
if (e.hasStarted() && !e.hasEnded()) {
eventsOnNow.push(e);
} else if (!e.hasStarted() && !e.hasEnded()) {
eventsOnNext.push(e);
}
}
}
eventsOnNow.sort((e1, e2) => {
return (e1.timeUntilEnd() > e2.timeUntilEnd()) ? 1 : ((e2.timeUntilEnd() > e1.timeUntilEnd()) ? -1 : 0)
});
eventsOnNext.sort((e1, e2) => {
return (e1.timeUntilStart() > e2.timeUntilStart()) ? 1 : ((e2.timeUntilStart() > e1.timeUntilStart()) ? -1 : 0)
});
populateList("happeningNow", eventsOnNow, false);
populateList("happeningNext", eventsOnNext, true);
window.setInterval(() => handleCountdown(), 1000);
});
grist.onOptions(function(options, interaction) {
console.info("Options reloaded");
});
class Event {
constructor(id, name, venue, videoNeeded, privacy, comments, startTime, endTime) {
this.id = id;
this.name = name;
this.venue = venue;
this.videoNeeded = videoNeeded;
this.privacy = privacy;
this.comments = comments;
this.startTime = startTime;
this.endTime = endTime;
}
hasStarted() {
return this.startTime < now;
}
hasEnded() {
return this.endTime < now;
}
timeUntilStart() {
return new Date(this.startTime - now);
}
timeUntilEnd() {
return new Date(this.endTime - now);
}
}
function makeTextBold(text) {
return "<b>" + text + "</b>";
}
function convertTimeToString(time) {
// Using getHours() is bullshit for this usage, it won't include any days in the hours
let hours = Math.floor(time / (1000 * 60 * 60));
let minutes = time.getMinutes();
return hours + " hours, " + minutes + " minutes";
}
function populateList(elementName, items, getStartsIn) {
for (const i of items) {
const col = document.createElement("div");
col.setAttribute("class", "col-sm-12 col-md-3")
const card = document.createElement("div");
card.setAttribute("class", "card m-3")
const cardHeader = document.createElement("div");
cardHeader.setAttribute("class", "card-header")
cardHeader.innerHTML = i.name;
const list = document.createElement("ul");
list.setAttribute("class", "list-group list-group-flush")
list.setAttribute("id", i.id);
var venue = document.createElement("ul");
var videoNeeded = document.createElement("ul");
var privacy = document.createElement("ul");
var comments = document.createElement("ul");
var timer = document.createElement("ul");
venue.setAttribute("class", "list-group-item");
videoNeeded.setAttribute("class", "list-group-item");
privacy.setAttribute("class", "list-group-item");
comments.setAttribute("class", "list-group-item");
venue.innerHTML = "Venue: " + i.venue;
videoNeeded.innerHTML = "Video Team Present: " + i.videoNeeded;
privacy.innerHTML = "Privacy: " + i.privacy;
comments.innerHTML = "Comment: " + i.comments;
timer.setAttribute("class", "list-group-item");
timer.setAttribute("id", i.id + "_time");
if (getStartsIn) {
timer.innerHTML = "Starts In: " + convertTimeToString(i.timeUntilStart()) + " (" + new Date(i.startTime).toLocaleString("en-GB", { timeZone: "UTC" }) + ")";
// Red border if show starts in 15 minutes
if (i.timeUntilStart() <= 15 * 60 * 1000){
card.setAttribute("class", "card m-3 border border-5 border-danger");
timer.setAttribute("class", "list-group-item text-danger");
}
} else {
timer.innerHTML = "Ends In: " + convertTimeToString(i.timeUntilEnd()) + " (" + new Date(i.endTime).toLocaleString("en-GB", { timeZone: "UTC" }) + ")";
}
list.appendChild(venue);
list.appendChild(videoNeeded);
list.appendChild(privacy);
if (i.comments) {
list.appendChild(comments);
}
list.appendChild(timer);
// Colour in any rows
if (i.privacy != "public") {
if (i.privacy == "none") {
privacy.setAttribute("class", "list-group-item bg-danger")
privacy.innerHTML = makeTextBold("Privacy: Do not record!");
} else if (i.privacy == "review") {
privacy.setAttribute("class", "list-group-item bg-warning")
privacy.innerHTML = makeTextBold(privacy.innerHTML);
}
}
if (i.comments) {
comments.setAttribute("class", "list-group-item bg-info");
comments.innerHTML = makeTextBold(comments.innerHTML);
}
if (i.videoNeeded == true) {
videoNeeded.setAttribute("class", "list-group-item bg-warning");
videoNeeded.innerHTML = makeTextBold(videoNeeded.innerHTML);
}
card.appendChild(cardHeader);
card.appendChild(list);
col.append(card);
document.getElementById(elementName).appendChild(col);
}
}
function handleCountdown() {
countdown--;
if (countdown == 0) {
countdown = MAX_COUNTDOWN;
window.location.reload();
}
let counterElement = document.getElementById("counter");
counterElement.innerHTML = "Next refresh in " + countdown;
}