diff --git a/src/channel/opts.js b/src/channel/opts.js index cc5c1fce..e776df1e 100644 --- a/src/channel/opts.js +++ b/src/channel/opts.js @@ -24,6 +24,7 @@ function OptionsModule(_channel) { cooldown: 4 // Number of seconds with no messages before burst is reset }, show_public: false, // List the channel on the index page + show_schedule: true, // Show the schedule UI and nav toggle enable_link_regex: true, // Use the built-in link filter password: false, // Channel password (false -> no password required for entry) allow_dupes: false, // Allow duplicate videos on the playlist @@ -322,6 +323,11 @@ OptionsModule.prototype.handleSetOptions = function (user, data) { sendUpdate = true; } + if ("show_schedule" in data && user.account.effectiveRank >= 3) { + this.opts.show_schedule = Boolean(data.show_schedule); + sendUpdate = true; + } + if ("enable_link_regex" in data) { this.opts.enable_link_regex = Boolean(data.enable_link_regex); sendUpdate = true; diff --git a/templates/channeloptions.pug b/templates/channeloptions.pug index 9859adb4..5422573b 100644 --- a/templates/channeloptions.pug +++ b/templates/channeloptions.pug @@ -92,6 +92,7 @@ mixin adminoptions +textbox-auto("cs-externalcss", "External CSS", "Stylesheet URL") +textbox-auto("cs-externaljs", "External Javascript", "Script URL") +rcheckbox-auto("cs-show_public", "List channel publicly") + +rcheckbox-auto("cs-show_schedule", "Show channel schedule") +rcheckbox-auto("cs-torbanned", "Block connections from Tor") +rcheckbox-auto("cs-block_anonymous_users", "Block anonymous users") +rcheckbox-auto("cs-allow_ascii_control", "Allow ASCII control characters (e.g. newlines)") diff --git a/www/css/cytube.css b/www/css/cytube.css index 6fbc0b33..102b85e1 100644 --- a/www/css/cytube.css +++ b/www/css/cytube.css @@ -270,7 +270,6 @@ li.ui-sortable-helper, li.ui-sortable-placeholder + li.queue_entry { .showschedule-notes { margin-top: 2px; - max-height: 72px; overflow: hidden; line-height: 1.2; color: rgba(255, 255, 255, 0.95); diff --git a/www/js/ui.js b/www/js/ui.js index ac654747..c9b95426 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -34,6 +34,20 @@ function updateScheduleToggleLabel() { $("#toggleschedule").text(row.is(":visible") ? "Hide Schedule" : "Show Schedule"); } +function applyScheduleVisibility() { + var enabled = true; + if (window.CHANNEL && CHANNEL.opts && CHANNEL.opts.show_schedule === false) { + enabled = false; + } + + if (!enabled) { + $("#showschedule-row").hide(); + } + + $("#toggleschedule").css("display", enabled ? "" : "none"); + updateScheduleToggleLabel(); +} + $("#toggleschedule").on('click', function () { var row = $("#showschedule-row"); if (!row.length) return; @@ -44,7 +58,8 @@ $("#toggleschedule").on('click', function () { } updateScheduleToggleLabel(); }); -updateScheduleToggleLabel(); +window.applyScheduleVisibility = applyScheduleVisibility; +applyScheduleVisibility(); /* chatbox */ @@ -1437,6 +1452,8 @@ var CSTShows = (function () { var weekOffset = 0; var cachedShows = []; var notesEditorMode = 'edit'; + var REFRESH_MS = 15000; + var scheduleRefreshTimer = null; function apiBase() { return '/api/v1/channels/' + CHANNEL.name + '/shows'; @@ -1919,17 +1936,7 @@ var CSTShows = (function () { } var blocksByStart = {}; - var covered = {}; var firstSegmentPlaced = {}; - function ensureDayMap(dayIdx) { - if (!covered[dayIdx]) covered[dayIdx] = {}; - } - function markCovered(dayIdx, startHour, span) { - ensureDayMap(dayIdx); - for (var h = startHour + 1; h < startHour + span; h++) { - covered[dayIdx][h] = true; - } - } function dayIndexFor(date) { var midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate()); var weekMidnight = new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate()); @@ -1969,15 +1976,13 @@ var CSTShows = (function () { isStart: isFirstVisibleSegment }); if (isFirstVisibleSegment) firstSegmentPlaced[show.id] = true; - if (span > 1) { - markCovered(dayIdx, startHour, span); - } } cursor = dayEnd; } }); var isAdmin = CLIENT.rank >= 2; + var rowspanRemaining = [0, 0, 0, 0, 0, 0, 0]; var table = $(''); var thead = $('').appendTo(table); var hrow = thead.find('tr'); @@ -1995,7 +2000,8 @@ var CSTShows = (function () { var cellDate = new Date(weekStart.getTime()); cellDate.setDate(weekStart.getDate() + col); cellDate.setHours(hour, 0, 0, 0); - if (covered[col] && covered[col][hour]) { + if (rowspanRemaining[col] > 0) { + rowspanRemaining[col] -= 1; continue; } var cell = $('
Time
').appendTo(tr); @@ -2015,6 +2021,7 @@ var CSTShows = (function () { items.sort(function (a, b) { return a.date - b.date; }); if (items.length === 1 && items[0].span > 1) { cell.attr('rowspan', String(items[0].span)); + rowspanRemaining[col] = items[0].span - 1; cell .addClass('showschedule-block-cell') .css('background-color', getShowBlockColor(items[0].show)); @@ -2034,7 +2041,7 @@ var CSTShows = (function () { $('') .addClass('status-' + (item.show.status || 'scheduled')) .text(label) - .css('background', items.length === 1 ? 'transparent' : (item.show.color || '')) + .css('background-color', item.show.color || getShowBlockColor(item.show)) .css('opacity', item.isStart ? '1' : '0.85') .attr('title', notesPreview || label) .on('click', function () { @@ -2047,15 +2054,34 @@ var CSTShows = (function () { }) .appendTo(cell); if (item.isStart) { + var notesEl = null; if (item.show.notes_html) { - $('
') + notesEl = $('
') .html(item.show.notes_html) .appendTo(cell); } else if (notesPreview) { - $('
') + notesEl = $('
') .text(notesPreview) .appendTo(cell); } + + if (notesEl && items.length > 1) { + notesEl + .css('background-color', item.show.color || getShowBlockColor(item.show)) + .css('color', '#ffffff') + .css('border-radius', '3px') + .css('padding', '4px 6px') + .css('margin-top', '0') + .css('margin-bottom', '2px'); + } + + if (items.length > 1) { + cell.find('.showschedule-show:last').css({ + 'margin-bottom': '0', + 'border-bottom-left-radius': '0', + 'border-bottom-right-radius': '0' + }); + } } }); } @@ -2172,6 +2198,31 @@ var CSTShows = (function () { }); } + function shouldAutoRefreshSchedule() { + if (document.hidden) return false; + if (window.CHANNEL && CHANNEL.opts && CHANNEL.opts.show_schedule === false) return false; + var row = $('#showschedule-row'); + return row.length > 0 && row.is(':visible'); + } + + function setupScheduleAutoRefresh() { + if (scheduleRefreshTimer) { + clearInterval(scheduleRefreshTimer); + } + + scheduleRefreshTimer = setInterval(function () { + if (shouldAutoRefreshSchedule()) { + load(); + } + }, REFRESH_MS); + + document.addEventListener('visibilitychange', function () { + if (shouldAutoRefreshSchedule()) { + load(); + } + }); + } + $('#cs-shows-create').on('click', function () { var payload = readFormPayload(); @@ -2259,6 +2310,7 @@ var CSTShows = (function () { renderDraftPlaylist(); clearForm(); setNotesEditorMode('edit'); + setupScheduleAutoRefresh(); load(); return { load: load, selectShow: selectShow, prefillScheduledDate: prefillScheduledDate }; diff --git a/www/js/util.js b/www/js/util.js index 6f602ad4..00c86260 100644 --- a/www/js/util.js +++ b/www/js/util.js @@ -985,6 +985,8 @@ function handleModPermissions() { } $("#cs-show_public").prop("checked", CHANNEL.opts.show_public); $("#cs-show_public").attr("disabled", CLIENT.rank < 3); + $("#cs-show_schedule").prop("checked", CHANNEL.opts.show_schedule !== false); + $("#cs-show_schedule").attr("disabled", CLIENT.rank < 3); $("#cs-password").val(CHANNEL.opts.password || ""); $("#cs-password").attr("disabled", CLIENT.rank < 3); $("#cs-enable_link_regex").prop("checked", CHANNEL.opts.enable_link_regex); @@ -1026,6 +1028,9 @@ function handlePermissionChange() { $("#qlockbtn").attr("disabled", !hasPermission("playlistlock")); setVisible("#showchansettings", CLIENT.rank >= 2); + if (typeof window.applyScheduleVisibility === "function") { + window.applyScheduleVisibility(); + } setVisible("#playlistmanagerwrap", CLIENT.rank >= 1); setVisible("#modflair", CLIENT.rank >= 2); setVisible("#guestlogin", CLIENT.rank < 0);