$(function() { var SLOT_REFRESH_INTERVAL = 60 * 1000; var haveScrolledToCurrentSlot = false; /* Schedule display localisation */ var showCurrentTab = function() { var fragment = window.location.hash.toLowerCase().substring(1); var dayTabs = $('#schedule-tabs .schedule-day'); if (dayTabs.length === 0) return; if (fragment) { var fragmentId = "#schedule_day_" + fragment + "-tab"; $(fragmentId).tab('show'); } else { // Show tab based on current time. var now = luxon.DateTime.local(); for (var i = 0; i < dayTabs.length; ++i) { var dayTab = $(dayTabs[i]); var tabDate = dayTab.data('date'); var scheduleDate = luxon.DateTime.fromISO(tabDate, { zone: CONF_TZ }); var startOfDay = scheduleDate.startOf('day'); var endOfDay = scheduleDate.endOf('day'); if (now >= startOfDay && now < endOfDay) { tabShown = true; dayTab.tab('show'); break; } } } } var updateScheduleGrid = function() { var rowHeaders = $('.calendar-row th.time'); for (var i = 0; i < rowHeaders.length; ++i) { var rowHeader = $(rowHeaders[i]); var rowTime = rowHeader.data('time'); var scheduleDate = luxon.DateTime.fromISO(rowTime, { zone: CONF_TZ }); var localDate = scheduleDate.toLocal(); // If the schedule date is already in the user's TZ, skip it. if (scheduleDate.offset === localDate.offset) break; var confFormatted = scheduleDate.toLocaleString({ weekday: scheduleDate.weekday === localDate.weekday ? undefined : 'short', hour: 'numeric', minute: 'numeric', timeZoneName: 'short', }); var localFormatted = localDate.toLocaleString({ weekday: scheduleDate.weekday === localDate.weekday ? undefined : 'short', hour: 'numeric', minute: 'numeric', timeZoneName: 'short', }); var timeText = rowHeader.find('p').text(); rowHeader.find('p').html(confFormatted + '
(' + localFormatted + ')'); } } var updatePresentationTimes = function() { var presentationTimes = $('span.presentation-time'); for (var i = 0; i < presentationTimes.length; ++i) { var presentationTime = $(presentationTimes[i]); var startTime = presentationTime.data('starttime'); var endTime = presentationTime.data('endtime'); var confStartTime = luxon.DateTime.fromISO(startTime, { zone: CONF_TZ }); var confEndTime = luxon.DateTime.fromISO(endTime, { zone: CONF_TZ }); var localStartTime = confStartTime.toLocal(); var localEndTime = confEndTime.toLocal(); // If the conf date is already in the user's TZ, skip it. if (confStartTime.offset === localStartTime.offset) break; var confStartTimeFormatted = confStartTime.toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: 'numeric', minute: 'numeric', }); var confEndTimeFormatted = confEndTime.toLocaleString({ hour: 'numeric', minute: 'numeric', timeZoneName: 'short', }); var localStartTimeFormatted = localStartTime.toLocaleString({ weekday: confStartTime.weekday === localStartTime.weekday ? undefined : 'short', month: confStartTime.weekday === localStartTime.weekday ? undefined : 'short', day: confStartTime.weekday === localStartTime.weekday ? undefined : '2-digit', hour: 'numeric', minute: 'numeric', }); var localEndTimeFormatted = localEndTime.toLocaleString({ weekday: localStartTime.weekday === localEndTime.weekday ? undefined : 'short', month: localStartTime.weekday === localEndTime.weekday ? undefined : 'short', day: localStartTime.weekday === localEndTime.weekday ? undefined : '2-digit', hour: 'numeric', minute: 'numeric', timeZoneName: 'short', }); presentationTime.html(confStartTimeFormatted + ' - ' + confEndTimeFormatted + ' (' + localStartTimeFormatted + ' - ' + localEndTimeFormatted + ')'); } } var highlightCurrentSlots = function() { var now = luxon.DateTime.local(); var slots = $('td.slot'); for (var i = 0; i < slots.length; ++i) { var slot = $(slots[i]); var startTime = slot.data('starttime'); var endTime = slot.data('endtime'); var confStartTime = luxon.DateTime.fromISO(startTime, { zone: CONF_TZ }); var confEndTime = luxon.DateTime.fromISO(endTime, { zone: CONF_TZ }); if (confStartTime <= now && confEndTime > now) { slot.addClass("slot-active"); if (!haveScrolledToCurrentSlot) { haveScrolledToCurrentSlot = true; slot[0].scrollIntoView(); } } else { slot.removeClass("slot-active"); } } } var updateClock = function() { var clock = $('div.conf-clock'); if (clock.length === 0) { var template = document.createElement('template'); template.innerHTML = '
'; var clockDiv = template.content.firstChild; document.body.appendChild(clockDiv); clock = $(clockDiv); } var now = luxon.DateTime.local(); var confFormatted = now.setZone(CONF_TZ).toLocaleString({ weekday: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZoneName: 'short', hour12: false, }); clock.html('Conf Time:
' + confFormatted + ''); } var embeddedView = function() { var urlParams = new URLSearchParams(window.location.search); if (urlParams.has('embed')) { $('header').remove(); $('footer').remove(); $('a').each(function() { var anchor = $(this); var path = anchor.attr('href'); if (path.startsWith('/')) { var separator = path.indexOf('?') === -1 ? '?' : '&'; anchor.attr('href', path + separator + 'embed') } else if (path.startsWith('http')) { anchor.attr('target', '_blank'); } }); return true; } return false; } /* Schedule Editing */ $("a.edit-slot").click(function(e) { $("#slotEditModal").load($(this).data("action"), function() { $("#slotEditModal").modal("show"); }); e.preventDefault(); }); $("form#schedule-builder :submit").click(function(e) { var name = this.name; if(name == 'delete') { if (!confirm("Are you sure you want to delete the schedule?")) { e.preventDefault(); return; } } }); /* Update schedule display */ var embedded = embeddedView(); showCurrentTab(); updateScheduleGrid(); updatePresentationTimes(); highlightCurrentSlots(); var slotRefresh = setInterval(highlightCurrentSlots, SLOT_REFRESH_INTERVAL); if (!embedded) { updateClock(); var clockRefresh = setInterval(updateClock, 5000); } });