add notification to slide

This commit is contained in:
jr-k 2024-06-26 23:22:17 +02:00
parent 55164953df
commit 80691061fc
5 changed files with 52 additions and 32 deletions

View File

@ -122,7 +122,7 @@ jQuery(document).ready(function ($) {
} }
if (flushDuration) { if (flushDuration) {
$targetDuration.val('0'); $targetDuration.val('1');
} }
}; };

View File

@ -1,4 +1,5 @@
import json import json
import logging
from typing import Optional from typing import Optional
from flask import Flask, render_template, redirect, request, url_for, send_from_directory, jsonify, abort from flask import Flask, render_template, redirect, request, url_for, send_from_directory, jsonify, abort
@ -18,12 +19,19 @@ class PlayerController(ObController):
playlist = self._model_store.playlist().get(playlist_id) playlist = self._model_store.playlist().get(playlist_id)
playlist_loop = [] playlist_loop = []
playlist_cron = [] playlist_notifications = []
for slide in slides: for slide in slides:
if 'cron_schedule' in slide and slide['cron_schedule']: has_valid_start_date = 'cron_schedule' in slide and slide['cron_schedule'] and get_safe_cron_descriptor(slide['cron_schedule'])
if get_safe_cron_descriptor(slide['cron_schedule']):
playlist_cron.append(slide) if slide['is_notification']:
if has_valid_start_date:
playlist_notifications.append(slide)
else:
logging.warn('Slide {} is notification but start date is invalid'.format(slide['name']))
else:
if has_valid_start_date:
playlist_loop.append(slide)
else: else:
playlist_loop.append(slide) playlist_loop.append(slide)
@ -31,7 +39,7 @@ class PlayerController(ObController):
'playlist_id': playlist.id if playlist else None, 'playlist_id': playlist.id if playlist else None,
'time_sync': playlist.time_sync if playlist else self._model_store.variable().get_one_by_name("playlist_default_time_sync").as_bool(), 'time_sync': playlist.time_sync if playlist else self._model_store.variable().get_one_by_name("playlist_default_time_sync").as_bool(),
'loop': playlist_loop, 'loop': playlist_loop,
'cron': playlist_cron, 'notifications': playlist_notifications,
'hard_refresh_request': self._model_store.variable().get_one_by_name("refresh_player_request").as_int() 'hard_refresh_request': self._model_store.variable().get_one_by_name("refresh_player_request").as_int()
} }

View File

@ -20,6 +20,7 @@ class SlideManager(ModelManager):
"name CHAR(255)", "name CHAR(255)",
"type CHAR(30)", "type CHAR(30)",
"enabled INTEGER DEFAULT 0", "enabled INTEGER DEFAULT 0",
"is_notification INTEGER DEFAULT 0",
"playlist_id INTEGER", "playlist_id INTEGER",
"duration INTEGER", "duration INTEGER",
"position INTEGER", "position INTEGER",

View File

@ -8,13 +8,14 @@ from src.util.utils import str_to_enum
class Slide: class Slide:
def __init__(self, location: str = '', playlist_id: Optional[int] = None, duration: int = 3, type: Union[SlideType, str] = SlideType.URL, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[int] = None, cron_schedule: Optional[str] = None, cron_schedule_end: Optional[str] = None, created_by: Optional[str] = None, updated_by: Optional[str] = None, created_at: Optional[int] = None, updated_at: Optional[int] = None): def __init__(self, location: str = '', playlist_id: Optional[int] = None, duration: int = 3, type: Union[SlideType, str] = SlideType.URL, is_notification: bool = False, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[int] = None, cron_schedule: Optional[str] = None, cron_schedule_end: Optional[str] = None, created_by: Optional[str] = None, updated_by: Optional[str] = None, created_at: Optional[int] = None, updated_at: Optional[int] = None):
self._id = id if id else None self._id = id if id else None
self._location = location self._location = location
self._playlist_id = playlist_id self._playlist_id = playlist_id
self._duration = duration self._duration = duration
self._type = str_to_enum(type, SlideType) if isinstance(type, str) else type self._type = str_to_enum(type, SlideType) if isinstance(type, str) else type
self._enabled = enabled self._enabled = enabled
self._is_notification = is_notification
self._name = name self._name = name
self._position = position self._position = position
self._cron_schedule = cron_schedule self._cron_schedule = cron_schedule
@ -116,6 +117,14 @@ class Slide:
def enabled(self, value: bool): def enabled(self, value: bool):
self._enabled = bool(value) self._enabled = bool(value)
@property
def is_notification(self) -> bool:
return bool(self._is_notification)
@is_notification.setter
def is_notification(self, value: bool):
self._is_notification = bool(value)
@property @property
def name(self) -> str: def name(self) -> str:
return self._name return self._name
@ -138,6 +147,7 @@ class Slide:
f"name='{self.name}',\n" \ f"name='{self.name}',\n" \
f"type='{self.type}',\n" \ f"type='{self.type}',\n" \
f"enabled='{self.enabled}',\n" \ f"enabled='{self.enabled}',\n" \
f"is_notification='{self.is_notification}',\n" \
f"duration='{self.duration}',\n" \ f"duration='{self.duration}',\n" \
f"position='{self.position}',\n" \ f"position='{self.position}',\n" \
f"location='{self.location}',\n" \ f"location='{self.location}',\n" \
@ -163,6 +173,7 @@ class Slide:
"id": self.id, "id": self.id,
"name": self.name, "name": self.name,
"enabled": self.enabled, "enabled": self.enabled,
"is_notification": self.is_notification,
"position": self.position, "position": self.position,
"type": self.type.value, "type": self.type.value,
"duration": self.duration, "duration": self.duration,

View File

@ -24,7 +24,7 @@
<iframe src="/player/default"></iframe> <iframe src="/player/default"></iframe>
{% endif %} {% endif %}
</div> </div>
<div id="CronSlide" class="slide" style="z-index: 0;"> <div id="NotificationSlide" class="slide" style="z-index: 0;">
</div> </div>
<div id="FirstSlide" class="slide slide-loop" style="z-index: 500;"> <div id="FirstSlide" class="slide slide-loop" style="z-index: 500;">
@ -74,12 +74,12 @@
let curItemIndex = -1; let curItemIndex = -1;
let secondsBeforeNext = 0; let secondsBeforeNext = 0;
const introSlide = document.getElementById('IntroSlide'); const introSlide = document.getElementById('IntroSlide');
const cronSlide = document.getElementById('CronSlide'); const notificationSlide = document.getElementById('NotificationSlide');
const firstSlide = document.getElementById('FirstSlide'); const firstSlide = document.getElementById('FirstSlide');
const secondSlide = document.getElementById('SecondSlide'); const secondSlide = document.getElementById('SecondSlide');
let curSlide = secondSlide; let curSlide = secondSlide;
let nextSlide = firstSlide; let nextSlide = firstSlide;
let cronItemIndex = null; let notificationItemIndex = null;
// Functions // Functions
const itemCheck = setInterval(function() { const itemCheck = setInterval(function() {
@ -189,7 +189,7 @@
}; };
const main = function() { const main = function() {
setInterval(checkAndMoveCron, 1000); setInterval(checkAndMoveNotifications, 1000);
setTimeout(function() { setTimeout(function() {
if (items.loop.length === 0) { if (items.loop.length === 0) {
return setTimeout(main, 5000); return setTimeout(main, 5000);
@ -372,9 +372,9 @@
setTimeout(autoplayLoader, delayNoisyContentJIT); setTimeout(autoplayLoader, delayNoisyContentJIT);
} }
const checkAndMoveCron = function() { const checkAndMoveNotifications = function() {
for (let i = 0; i < items.cron.length; i++) { for (let i = 0; i < items.notifications.length; i++) {
const item = items.cron[i]; const item = items.notifications[i];
const now = new Date(); const now = new Date();
const isFullyElapsedMinute = (new Date()).getSeconds() === 0; const isFullyElapsedMinute = (new Date()).getSeconds() === 0;
@ -383,52 +383,52 @@
const hasDateTime = hasCron && validateCronDateTime(item.cron_schedule); const hasDateTime = hasCron && validateCronDateTime(item.cron_schedule);
const hasDateTimeEnd = hasCronEnd && validateCronDateTime(item.cron_schedule_end); const hasDateTimeEnd = hasCronEnd && validateCronDateTime(item.cron_schedule_end);
if (cronItemIndex !== i && hasDateTime) { if (notificationItemIndex !== i && hasDateTime) {
const startDate = cronToDateTimeObject(item.cron_schedule); const startDate = cronToDateTimeObject(item.cron_schedule);
const endDate = hasDateTimeEnd ? cronToDateTimeObject(item.cron_schedule_end) : modifyDate(startDate, item.duration); const endDate = hasDateTimeEnd ? cronToDateTimeObject(item.cron_schedule_end) : modifyDate(startDate, item.duration);
if (now >= startDate && now < endDate) { if (now >= startDate && now < endDate) {
moveToCronSlide(i); moveToNotificationSlide(i);
} }
} }
if (cronItemIndex === i && hasDateTime) { if (notificationItemIndex === i && hasDateTime) {
const startDate = cronToDateTimeObject(item.cron_schedule); const startDate = cronToDateTimeObject(item.cron_schedule);
const endDate = hasDateTimeEnd ? cronToDateTimeObject(item.cron_schedule_end) : modifyDate(startDate, item.duration); const endDate = hasDateTimeEnd ? cronToDateTimeObject(item.cron_schedule_end) : modifyDate(startDate, item.duration);
if (now >= endDate) { if (now >= endDate) {
stopCronSlide(); stopNotificationSlide();
} }
} }
if (cronItemIndex !== i && isFullyElapsedMinute && hasCron && cron.isActive(item.cron_schedule)) { if (notificationItemIndex !== i && isFullyElapsedMinute && hasCron && cron.isActive(item.cron_schedule)) {
moveToCronSlide(i); moveToNotificationSlide(i);
} }
if (cronItemIndex === i && isFullyElapsedMinute && hasCronEnd && cron.isActive(item.cron_schedule_end)) { if (notificationItemIndex === i && isFullyElapsedMinute && hasCronEnd && cron.isActive(item.cron_schedule_end)) {
stopCronSlide(); stopNotificationSlide();
} }
} }
}; };
const moveToCronSlide = function(cronSlideIndex) { const moveToNotificationSlide = function(notificationSlideIndex) {
const item = items.cron[cronSlideIndex]; const item = items.notifications[notificationSlideIndex];
cronItemIndex = cronSlideIndex; notificationItemIndex = notificationSlideIndex;
pause(); pause();
const callbackReady = function() { const callbackReady = function() {
cronSlide.style.zIndex = '2000'; notificationSlide.style.zIndex = '2000';
if (!item.cron_schedule_end) { if (!item.cron_schedule_end) {
setTimeout(function() { setTimeout(function() {
stopCronSlide(); stopNotificationSlide();
}, safe_duration(item) * 1000); }, safe_duration(item) * 1000);
} }
}; };
loadContent(cronSlide, callbackReady, item); loadContent(notificationSlide, callbackReady, item);
}; };
const stopCronSlide = function() { const stopNotificationSlide = function() {
cronItemIndex = null; notificationItemIndex = null;
cronSlide.style.zIndex = '0'; notificationSlide.style.zIndex = '0';
play(); play();
}; };