diff --git a/data/www/js/slideshow/slides.js b/data/www/js/slideshow/slides.js index addbdb7..7fb7e91 100644 --- a/data/www/js/slideshow/slides.js +++ b/data/www/js/slideshow/slides.js @@ -18,23 +18,26 @@ jQuery(document).ready(function ($) { return `${d.getFullYear()}-${String(d.getMonth()).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')} ` } - const loadDateTimePicker = function($el) { - $el.val(''); - const pickr = $el.flatpickr({ - enableTime: true, - time_24hr: true, - allowInput: false, - allowInvalidPreload: false, - dateFormat: 'Y-m-d H:i', - onChange: function(selectedDates, dateStr, instance) { - const d = selectedDates[0]; - const $target = $el.parents('.widget:eq(0)').find('.target'); - $target.val( - d ? `${d.getMinutes()} ${d.getHours()} ${d.getDate()} ${(d.getMonth() + 1)} * ${d.getFullYear()}` : '' - ); - } - }); - $el.addClass('hidden'); + const loadDateTimePicker = function($els) { + $els.each(function() { + var $el = $(this); + $el.val(''); + const pickr = $el.flatpickr({ + enableTime: true, + time_24hr: true, + allowInput: false, + allowInvalidPreload: false, + dateFormat: 'Y-m-d H:i', + onChange: function(selectedDates, dateStr, instance) { + const d = selectedDates[0]; + const $target = $el.parents('.widget:eq(0)').find('.target'); + $target.val( + d ? `${d.getMinutes()} ${d.getHours()} ${d.getDate()} ${(d.getMonth() + 1)} * ${d.getFullYear()}` : '' + ); + } + }); + $el.addClass('hidden'); + }) }; const getId = function ($el) { @@ -90,7 +93,51 @@ jQuery(document).ready(function ($) { .removeClass('hidden') .prop('disabled', false) ; - } + }; + + const inputSchedulerUpdate = function() { + const $modal = $('.modal-slide:visible'); + const $scheduleStartGroup = $modal.find('.slide-schedule-group'); + const $scheduleEndGroup = $modal.find('.slide-schedule-end-group'); + const $durationGroup = $modal.find('.slide-duration-group'); + + const $triggerStart = $scheduleStartGroup.find('.trigger'); + const $triggerEnd = $scheduleEndGroup.find('.trigger'); + const $targetCronFieldStart = $scheduleStartGroup.find('.target'); + const $targetCronFieldEnd = $scheduleEndGroup.find('.target'); + + const $datetimepickerStart = $scheduleStartGroup.find('.datetimepicker'); + const $datetimepickerEnd = $scheduleEndGroup.find('.datetimepicker'); + + const isCronStart = $triggerStart.val() === 'cron'; + const isCronEnd = $triggerEnd.val() === 'cron'; + const isDatetimeStart = $triggerStart.val() === 'datetime'; + const isDatetimeEnd = $triggerEnd.val() === 'datetime'; + const isLoopStart = $triggerStart.val() === 'loop'; + const isDurationEnd = $triggerEnd.val() === 'duration'; + const flushValueStart = isLoopStart; + const flushValueEnd = isDurationEnd; + + $targetCronFieldStart.toggleClass('hidden', !isCronStart); + $targetCronFieldEnd.toggleClass('hidden', !isCronEnd); + $datetimepickerStart.toggleClass('hidden', !isDatetimeStart); + $datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd); + + $durationGroup.toggleClass('hidden', !isLoopStart && !isDurationEnd); + $scheduleEndGroup.toggleClass('hidden', isLoopStart); + + $durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible')); + + if (flushValueStart) { + $targetCronFieldStart.val(''); + $datetimepickerStart.val(''); + } + + if (flushValueEnd) { + $targetCronFieldEnd.val(''); + $datetimepickerEnd.val(''); + } + }; const main = function () { $("table").tableDnD({ @@ -119,28 +166,7 @@ jQuery(document).ready(function ($) { }); $(document).on('change', '.modal-slide select.trigger', function () { - const $modal = $(this).parents('.modal-slide:eq(0)'); - const $target = $(this).parents('.widget:eq(0)').find('.target'); - const $datetimepicker = $(this).parents('.widget:eq(0)').find('.datetimepicker'); - const $durationGroup = $modal.find('.slide-duration-group'); - const $scheduleEndGroup = $modal.find('.slide-schedule-end-group'); - - const isDateTime = $(this).val() === 'datetime'; - const isLoop = $(this).val() === 'loop'; - const flushValue = isLoop; - - const hideCronField = isLoop || isDateTime; - const hideDateTimeField = !isDateTime; - - $target.toggleClass('hidden', hideCronField); - $datetimepicker.toggleClass('hidden', hideDateTimeField); - // $durationGroup.toggleClass('hidden', !isLoop); - // $scheduleEndGroup.toggleClass('hidden', isLoop); - - if (flushValue) { - $target.val(''); - $datetimepicker.val(''); - } + inputSchedulerUpdate(); }); $(document).on('change', '#slide-add-type', inputTypeUpdate); @@ -153,6 +179,7 @@ jQuery(document).ready(function ($) { showModal('modal-slide-add'); loadDateTimePicker($('.modal-slide-add .datetimepicker')) inputTypeUpdate(); + inputSchedulerUpdate(); $('.modal-slide-add input:eq(0)').focus().select(); }); @@ -192,7 +219,7 @@ jQuery(document).ready(function ($) { $('#slide-edit-cron-schedule-trigger').val(hasDateTime ? 'datetime' : (hasCron ? 'cron' : 'loop')); $('#slide-edit-cron-schedule-end').val(slide.cron_schedule_end).toggleClass('hidden', !hasCronEnd || hasDateTimeEnd); - $('#slide-edit-cron-schedule-end-trigger').val(hasDateTimeEnd ? 'datetime' : (hasCronEnd ? 'cron' : 'loop')); + $('#slide-edit-cron-schedule-end-trigger').val(hasDateTimeEnd ? 'datetime' : (hasCronEnd ? 'cron' : 'duration')); $('#slide-edit-cron-schedule-datetimepicker').toggleClass('hidden', !hasDateTime).val( hasDateTime ? getCronDateTime(slide.cron_schedule) : '' @@ -202,6 +229,7 @@ jQuery(document).ready(function ($) { hasDateTimeEnd ? getCronDateTime(slide.cron_schedule_end) : '' ); $('#slide-edit-id').val(slide.id); + inputSchedulerUpdate(); }); $(document).on('click', '.slide-delete', function () { diff --git a/lang/en.json b/lang/en.json index 2313d58..f831705 100644 --- a/lang/en.json +++ b/lang/en.json @@ -32,6 +32,8 @@ "slideshow_slide_form_label_cron_scheduled": "Start", "slideshow_slide_form_label_cron_scheduled_end": "End", "slideshow_slide_form_label_cron_scheduled_loop": "In the loop", + "slideshow_slide_form_label_cron_scheduled_duration": "Duration", + "slideshow_slide_form_label_cron_scheduled_duration_unit": "seconds", "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Time", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Set a date and time", "slideshow_slide_form_label_cron_scheduled_cron": "Cron", diff --git a/lang/fr.json b/lang/fr.json index 561abbf..8c0534e 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -32,6 +32,8 @@ "slideshow_slide_form_label_cron_scheduled": "Début", "slideshow_slide_form_label_cron_scheduled_end": "Fin", "slideshow_slide_form_label_cron_scheduled_loop": "Dans la boucle", + "slideshow_slide_form_label_cron_scheduled_duration": "Durée", + "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes", "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure", "slideshow_slide_form_label_cron_scheduled_cron": "Cron", diff --git a/src/manager/DatabaseManager.py b/src/manager/DatabaseManager.py index 263a477..4cd4200 100644 --- a/src/manager/DatabaseManager.py +++ b/src/manager/DatabaseManager.py @@ -78,6 +78,8 @@ class DatabaseManager: except sqlite3.Error as e: logging.error("SQL query execution error while writing '{}': {}".format(query, e)) self._conn.rollback() + except sqlite3.OperationalError: + pass finally: if cur is not None: cur.close() diff --git a/views/player/player.jinja.html b/views/player/player.jinja.html index d7ce512..68e0262 100755 --- a/views/player/player.jinja.html +++ b/views/player/player.jinja.html @@ -43,7 +43,7 @@ var needHardRefresh = null; // Frontend config - var syncedWithTime = true; + var syncedWithTime = false; var tickRefreshResolutionMs = 100; // Frontend flag updates @@ -132,7 +132,7 @@ } if (syncedWithTime) { - return console.warn('You can\'t call seek with synced playlists'); + return console.warn('You can\'t seek with synced playlists'); } var maxDuration = getLoopDuration(); @@ -188,7 +188,7 @@ setTimeout(function() { introSlide.remove(); setInterval(checkAndMoveSlide, tickRefreshResolutionMs); - setInterval(cronTick, 1000); + setInterval(checkAndMoveCron, 1000); }, introDuration); }; @@ -260,21 +260,22 @@ //console.log("curSlide", curSlide.attributes['id'].value, curSlide.style.zIndex, "to", "next", nextSlide.attributes['id'].value, nextSlide.style.zIndex); //console.log("###"); + var loadingNextSlide = function () { + if (forcePreload) { + forcePreload = false; + play(); + } + + if (isPaused() && !syncedWithTime) { + return setTimeout(loadingNextSlide, 500); + } + + refreshSlidesOrder(); + preloadSlide(nextSlide.attributes['id'].value, lookupNextItem()); + }; + if (animate) { nextSlide.classList.add('animate__animated', animate_transitions[0], animate_speed); - var loadingNextSlide = function () { - if (forcePreload) { - forcePreload = false; - play(); - } - - if (isPaused() && !syncedWithTime) { - return setTimeout(loadingNextSlide, 500); - } - - refreshSlidesOrder(); - preloadSlide(nextSlide.attributes['id'].value, lookupNextItem()); - }; nextSlide.onanimationend = function() { nextSlide.classList.remove(animate_transitions[0], animate_speed); loadingNextSlide(); @@ -285,18 +286,6 @@ curSlide.classList.remove(animate_transitions[1], animate_speed); }; } else { - var loadingNextSlide = function () { - if (forcePreload) { - forcePreload = false; - play(); - } - - if (isPaused() && !syncedWithTime) { - return setTimeout(loadingNextSlide, 500); - } - refreshSlidesOrder(); - preloadSlide(nextSlide.attributes['id'].value, lookupNextItem()); - }; loadingNextSlide(); } } @@ -378,7 +367,7 @@ setTimeout(autoplayLoader, delayNoisyContentJIT); } - var cronTick = function() { + var checkAndMoveCron = function() { if ((new Date()).getSeconds() != 0) { return; } @@ -387,31 +376,34 @@ var item = items.cron[i]; if (cron.isActive(item.cron_schedule) && cronItemIndex !== i) { - setTimeout(function() { - moveToCronSlide(i); - }, 100); + moveToCronSlide(i); + } + + if (cron.isActive(item.cron_schedule_end) && cronItemIndex === i) { + stopCronSlide(); } } }; function moveToCronSlide(cronSlideIndex) { var item = items.cron[cronSlideIndex]; - var savedSlide = curSlide.innerHTML; cronItemIndex = cronSlideIndex; pause(); var callbackReady = function() { cronSlide.style.zIndex = '2000'; setTimeout(function() { - cronItemIndex = null; - curSlide.innerHTML = savedSlide; - cronSlide.style.zIndex = '0'; - play(); + stopCronSlide(); }, safe_duration(item) * 1000); }; - loadContent(cronSlide, callbackReady, item); } + function stopCronSlide() { + cronItemIndex = null; + cronSlide.style.zIndex = '0'; + play(); + } + main(); diff --git a/views/slideshow/modal/add.jinja.html b/views/slideshow/modal/add.jinja.html index 4f848a5..dfadb6a 100644 --- a/views/slideshow/modal/add.jinja.html +++ b/views/slideshow/modal/add.jinja.html @@ -45,7 +45,7 @@ {{ l.slideshow_slide_form_section_scheduling }} -
+
+ diff --git a/views/slideshow/modal/edit.jinja.html b/views/slideshow/modal/edit.jinja.html index 0692f5b..6d47db0 100644 --- a/views/slideshow/modal/edit.jinja.html +++ b/views/slideshow/modal/edit.jinja.html @@ -43,7 +43,7 @@ {{ l.slideshow_slide_form_section_scheduling }} -
+
- +