better delegate duration
This commit is contained in:
parent
3c31ccf6fe
commit
3ca566dfee
@ -54,7 +54,7 @@ jQuery(document).ready(function ($) {
|
||||
const $scheduleStartGroup = $modal.find('.slide-schedule-group');
|
||||
const $scheduleEndGroup = $modal.find('.slide-schedule-end-group');
|
||||
const $durationGroup = $modal.find('.slide-duration-group');
|
||||
const $autoDurationGroup = $modal.find('.slide-auto-duration-group');
|
||||
const $delegateDurationGroup = $modal.find('.slide-delegate-duration-group');
|
||||
const $contentGroup = $modal.find('.slide-content-id-group');
|
||||
|
||||
const $triggerStart = $scheduleStartGroup.find('.trigger');
|
||||
@ -62,7 +62,7 @@ jQuery(document).ready(function ($) {
|
||||
const $targetCronFieldStart = $scheduleStartGroup.find('.target');
|
||||
const $targetCronFieldEnd = $scheduleEndGroup.find('.target');
|
||||
const $targetDuration = $durationGroup.find('input');
|
||||
const $targetAutoDuration = $autoDurationGroup.find('input');
|
||||
const $targetDelegateDuration = $delegateDurationGroup.find('input')
|
||||
|
||||
const $datetimepickerStart = $scheduleStartGroup.find('.datetimepicker');
|
||||
const $datetimepickerEnd = $scheduleEndGroup.find('.datetimepicker');
|
||||
@ -101,12 +101,13 @@ jQuery(document).ready(function ($) {
|
||||
$datetimepickerStart.toggleClass('hidden', !isDatetimeStart);
|
||||
$datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd);
|
||||
|
||||
// $targetAutoDuration
|
||||
$autoDurationGroup.toggleClass('hidden', (isNotification && isDatetimeEnd) || !isVideo);
|
||||
$durationGroup.toggleClass('hidden', (isNotification && isDatetimeEnd) || $targetAutoDuration.prop('checked'));
|
||||
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
||||
$delegateDurationGroup.toggleClass('hidden', (isNotification && isDatetimeEnd) || !isVideo);
|
||||
$durationGroup.toggleClass('hidden', (isNotification && isDatetimeEnd) || $targetDelegateDuration.prop('checked'));
|
||||
|
||||
$durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible'));
|
||||
$targetDuration.prop('required', $durationGroup.is(':visible'));
|
||||
$targetDelegateDuration.prop('disabled', !$delegateDurationGroup.is(':visible'));
|
||||
|
||||
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
||||
}
|
||||
|
||||
function flushValues() {
|
||||
@ -178,17 +179,7 @@ jQuery(document).ready(function ($) {
|
||||
$actionShow.removeClass('hidden');
|
||||
};
|
||||
|
||||
$(document).on('change', '.slide-auto-duration', function () {
|
||||
const $modal = $(this).parents('.modal:eq(0)');
|
||||
const $durationGroup = $modal.find('.slide-duration-group');
|
||||
const $durationInput = $durationGroup.find('input');
|
||||
|
||||
if ($(this).prop('checked')) {
|
||||
$durationInput.val(auto_duration_cheatcode);
|
||||
} else {
|
||||
$durationInput.val(3);
|
||||
}
|
||||
|
||||
$(document).on('change', '.slide-delegate-duration', function () {
|
||||
inputSchedulerUpdate();
|
||||
});
|
||||
|
||||
@ -217,7 +208,7 @@ jQuery(document).ready(function ($) {
|
||||
|
||||
inputCallbacks();
|
||||
|
||||
$modal.find(tclass + '-auto-duration').prop('checked', slide.duration === auto_duration_cheatcode);
|
||||
$modal.find(tclass + '-delegate-duration').prop('checked', slide.delegate_duration);
|
||||
|
||||
$modal.find('input[type=text]:visible:eq(0)').focus().select();
|
||||
$modal.find(tclass + '-duration').val(slide.duration);
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
"slideshow_slide_panel_th_content": "Content",
|
||||
"slideshow_slide_panel_th_duration": "Ends after",
|
||||
"slideshow_slide_panel_th_duration_unit": "sec",
|
||||
"slideshow_slide_panel_th_auto_duration_video": "Video's duration",
|
||||
"slideshow_slide_panel_th_delegate_duration_video": "Video's duration",
|
||||
"slideshow_slide_panel_th_enabled": "Enabled",
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Scheduled Start",
|
||||
"slideshow_slide_panel_th_activity": "Options",
|
||||
@ -34,7 +34,7 @@
|
||||
"slideshow_slide_form_section_scheduling": "Scheduling",
|
||||
"slideshow_slide_form_label_name": "Name",
|
||||
"slideshow_slide_form_label_enabled": "Enable/Disable",
|
||||
"slideshow_slide_form_label_auto_duration": "Use video's duration as timer",
|
||||
"slideshow_slide_form_label_delegate_duration": "Use video's duration as timer",
|
||||
"slideshow_slide_form_label_add_content": "Upload to library",
|
||||
"slideshow_slide_form_label_from_library": "From library",
|
||||
"slideshow_slide_form_label_content_id": "Content",
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
"slideshow_slide_panel_th_content": "Contenido",
|
||||
"slideshow_slide_panel_th_duration": "Termina después",
|
||||
"slideshow_slide_panel_th_duration_unit": "seg",
|
||||
"slideshow_slide_panel_th_auto_duration_video": "Duración del vídeo",
|
||||
"slideshow_slide_panel_th_delegate_duration_video": "Duración del vídeo",
|
||||
"slideshow_slide_panel_th_enabled": "Habilitado",
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Inicio Programado",
|
||||
"slideshow_slide_panel_th_activity": "Opciones",
|
||||
@ -35,7 +35,7 @@
|
||||
"slideshow_slide_form_label_name": "Nombre",
|
||||
"slideshow_slide_form_label_add_content": "Upload a la biblioteca",
|
||||
"slideshow_slide_form_label_enabled": "Activar/Desactivar",
|
||||
"slideshow_slide_form_label_auto_duration": "Utilizar la duración del vídeo",
|
||||
"slideshow_slide_form_label_delegate_duration": "Utilizar la duración del vídeo",
|
||||
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
||||
"slideshow_slide_form_label_content_id": "Contenido",
|
||||
"slideshow_slide_form_label_location": "Ubicación",
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
"slideshow_slide_panel_th_content": "Contenu",
|
||||
"slideshow_slide_panel_th_duration": "Fin après",
|
||||
"slideshow_slide_panel_th_duration_unit": "sec",
|
||||
"slideshow_slide_panel_th_auto_duration_video": "Durée de la vidéo",
|
||||
"slideshow_slide_panel_th_delegate_duration_video": "Durée de la vidéo",
|
||||
"slideshow_slide_panel_th_enabled": "Activé",
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Programmation",
|
||||
"slideshow_slide_panel_th_activity": "Options",
|
||||
@ -34,7 +34,7 @@
|
||||
"slideshow_slide_form_section_scheduling": "Programmation",
|
||||
"slideshow_slide_form_label_name": "Nom",
|
||||
"slideshow_slide_form_label_enabled": "Activer/Désactiver",
|
||||
"slideshow_slide_form_label_auto_duration": "Utiliser la durée de la vidéo",
|
||||
"slideshow_slide_form_label_delegate_duration": "Utiliser la durée de la vidéo",
|
||||
"slideshow_slide_form_label_add_content": "Upload à la bibliothèque",
|
||||
"slideshow_slide_form_label_from_library": "Depuis la bibliothèque",
|
||||
"slideshow_slide_form_label_content_id": "Contenu",
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
"slideshow_slide_panel_th_content": "Contenuti",
|
||||
"slideshow_slide_panel_th_duration": "Finito in",
|
||||
"slideshow_slide_panel_th_duration_unit": "sec",
|
||||
"slideshow_slide_panel_th_auto_duration_video": "Durata del video",
|
||||
"slideshow_slide_panel_th_delegate_duration_video": "Durata del video",
|
||||
"slideshow_slide_panel_th_enabled": "Abilitato",
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione",
|
||||
"slideshow_slide_panel_th_activity": "Opzioni",
|
||||
@ -34,7 +34,7 @@
|
||||
"slideshow_slide_form_section_scheduling": "Programmazione",
|
||||
"slideshow_slide_form_label_name": "Nome",
|
||||
"slideshow_slide_form_label_enabled": "Abilita/Disabilita",
|
||||
"slideshow_slide_form_label_auto_duration": "Utilizza la durata del video",
|
||||
"slideshow_slide_form_label_delegate_duration": "Utilizza la durata del video",
|
||||
"slideshow_slide_form_label_add_content": "Upload alla biblioteca",
|
||||
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
||||
"slideshow_slide_form_label_content_id": "Contenuti",
|
||||
|
||||
@ -5,3 +5,4 @@ waitress
|
||||
flask-login
|
||||
pysqlite3
|
||||
psutil
|
||||
moviepy
|
||||
|
||||
@ -8,7 +8,7 @@ from flask import Flask, render_template, redirect, request, url_for, send_from_
|
||||
from pathlib import Path
|
||||
|
||||
from src.model.entity.Slide import Slide
|
||||
from src.model.enum.ContentType import ContentType, AUTO_DURATION_CHEATCODE
|
||||
from src.model.enum.ContentType import ContentType
|
||||
from src.exceptions.NoFallbackPlaylistException import NoFallbackPlaylistException
|
||||
from src.service.ModelStore import ModelStore
|
||||
from src.interface.ObController import ObController
|
||||
@ -61,7 +61,6 @@ class PlayerController(ObController):
|
||||
slide_animation_entrance_effect=slide_animation_entrance_effect,
|
||||
slide_animation_speed=slide_animation_speed,
|
||||
animation_speed_duration=animation_speed_duration,
|
||||
auto_duration_cheatcode=AUTO_DURATION_CHEATCODE
|
||||
)
|
||||
|
||||
def player_default(self):
|
||||
|
||||
@ -4,7 +4,7 @@ from flask import Flask, render_template, redirect, request, url_for, jsonify, a
|
||||
from src.service.ModelStore import ModelStore
|
||||
from src.model.entity.Playlist import Playlist
|
||||
from src.model.enum.FolderEntity import FolderEntity
|
||||
from src.model.enum.ContentType import ContentType, AUTO_DURATION_CHEATCODE
|
||||
from src.model.enum.ContentType import ContentType
|
||||
from src.interface.ObController import ObController
|
||||
|
||||
|
||||
@ -49,7 +49,6 @@ class PlaylistController(ObController):
|
||||
folders_tree=self._model_store.folder().get_folder_tree(FolderEntity.CONTENT),
|
||||
enum_content_type=ContentType,
|
||||
enum_folder_entity=FolderEntity,
|
||||
auto_duration_cheatcode=AUTO_DURATION_CHEATCODE,
|
||||
)
|
||||
|
||||
def playlist_add(self):
|
||||
|
||||
@ -62,7 +62,8 @@ class SlideController(ObController):
|
||||
slide = self._model_store.slide().update_form(
|
||||
id=request.form['id'],
|
||||
content_id=request.form['content_id'],
|
||||
enabled='enabled' in request.form and request.form['enabled'],
|
||||
enabled='enabled' in request.form and request.form['enabled'] == '1',
|
||||
delegate_duration='delegate_duration' in request.form and request.form['delegate_duration'] == '1',
|
||||
duration=request.form['duration'],
|
||||
is_notification=True if 'is_notification' in request.form and request.form['is_notification'] == '1' else False,
|
||||
cron_schedule=request.form['cron_schedule'],
|
||||
|
||||
@ -2,6 +2,7 @@ import os
|
||||
|
||||
from typing import Dict, Optional, List, Tuple, Union
|
||||
from werkzeug.datastructures import FileStorage
|
||||
from moviepy.editor import VideoFileClip
|
||||
|
||||
from src.model.entity.Content import Content
|
||||
from src.model.entity.Playlist import Playlist
|
||||
@ -25,6 +26,7 @@ class ContentManager(ModelManager):
|
||||
"name CHAR(255)",
|
||||
"type CHAR(30)",
|
||||
"location TEXT",
|
||||
"duration INTEGER",
|
||||
"folder_id INTEGER",
|
||||
"created_by CHAR(255)",
|
||||
"updated_by CHAR(255)",
|
||||
@ -125,7 +127,7 @@ class ContentManager(ModelManager):
|
||||
def post_delete(self, content_id: str) -> str:
|
||||
return content_id
|
||||
|
||||
def update_form(self, id: int, name: str, location: Optional[str] = None) -> Content:
|
||||
def update_form(self, id: int, name: str, location: Optional[str] = None) -> Optional[Content]:
|
||||
content = self.get(id)
|
||||
|
||||
if not content:
|
||||
@ -191,6 +193,11 @@ class ContentManager(ModelManager):
|
||||
object_path = os.path.join(upload_dir, object_name)
|
||||
object.save(object_path)
|
||||
content.location = object_path
|
||||
|
||||
if type == ContentType.VIDEO:
|
||||
with VideoFileClip(content.location) as video:
|
||||
content.duration = int(video.duration)
|
||||
|
||||
else:
|
||||
content.location = location
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ class NodePlayerGroupManager(ModelManager):
|
||||
|
||||
form = {
|
||||
"name": name,
|
||||
"playlist_id": playlist_id if playlist_id else None
|
||||
"playlist_id": playlist_id if playlist_id else node_player_group.playlist_id
|
||||
}
|
||||
|
||||
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form))
|
||||
|
||||
@ -6,6 +6,7 @@ from src.model.entity.Playlist import Playlist
|
||||
from src.util.utils import get_optional_string, get_yt_video_id, slugify, slugify_next
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
from src.manager.SlideManager import SlideManager
|
||||
from src.manager.ContentManager import ContentManager
|
||||
from src.manager.LangManager import LangManager
|
||||
from src.manager.UserManager import UserManager
|
||||
from src.manager.VariableManager import VariableManager
|
||||
@ -65,8 +66,20 @@ class PlaylistManager(ModelManager):
|
||||
return self.hydrate_object(object)
|
||||
|
||||
def get_durations_by_playlists(self, playlist_id: Optional[int] = None):
|
||||
durations = self._db.execute_read_query("select playlist_id, sum(duration) as total_duration from {} where cron_schedule is null {} group by playlist_id".format(
|
||||
durations = self._db.execute_read_query("""
|
||||
SELECT
|
||||
playlist_id,
|
||||
SUM(CASE
|
||||
WHEN s.delegate_duration = 1 THEN c.duration
|
||||
ELSE s.duration
|
||||
END) AS total_duration
|
||||
FROM {} s
|
||||
LEFT JOIN {} c ON c.id = s.content_id
|
||||
WHERE cron_schedule IS NULL {}
|
||||
GROUP BY playlist_id;
|
||||
""".format(
|
||||
SlideManager.TABLE_NAME,
|
||||
ContentManager.TABLE_NAME,
|
||||
"{}".format(
|
||||
" AND playlist_id = {}".format(playlist_id) if playlist_id else ""
|
||||
)
|
||||
@ -145,7 +158,7 @@ class PlaylistManager(ModelManager):
|
||||
def post_delete(self, playlist_id: str) -> str:
|
||||
return playlist_id
|
||||
|
||||
def update_form(self, id: int, name: str, time_sync: bool, enabled: bool) -> None:
|
||||
def update_form(self, id: int, name: Optional[str] = None, time_sync: Optional[bool] = None, enabled: Optional[bool] = None) -> None:
|
||||
playlist = self.get(id)
|
||||
|
||||
if not playlist:
|
||||
@ -153,8 +166,8 @@ class PlaylistManager(ModelManager):
|
||||
|
||||
form = {
|
||||
"name": name,
|
||||
"time_sync": time_sync,
|
||||
"enabled": enabled
|
||||
"time_sync": time_sync if isinstance(time_sync, bool) else slide.time_sync,
|
||||
"enabled": enabled if isinstance(enabled, bool) else slide.enabled,
|
||||
}
|
||||
|
||||
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form))
|
||||
|
||||
@ -17,6 +17,7 @@ class SlideManager(ModelManager):
|
||||
TABLE_NAME = "slides"
|
||||
TABLE_MODEL = [
|
||||
"enabled INTEGER DEFAULT 0",
|
||||
"delegate_duration INTEGER DEFAULT 0",
|
||||
"is_notification INTEGER DEFAULT 0",
|
||||
"playlist_id INTEGER",
|
||||
"content_id INTEGER",
|
||||
@ -135,16 +136,17 @@ class SlideManager(ModelManager):
|
||||
for slide_id, slide_position in positions.items():
|
||||
self._db.update_by_id(self.TABLE_NAME, slide_id, {"position": slide_position})
|
||||
|
||||
def update_form(self, id: int, duration: int, content_id: Optional[int] = None, is_notification: bool = False, cron_schedule: Optional[str] = '', cron_schedule_end: Optional[str] = '', enabled: bool = True) -> Slide:
|
||||
def update_form(self, id: int, duration: Optional[int] = None, content_id: Optional[int] = None, delegate_duration: Optional[bool] = None, is_notification: bool = False, cron_schedule: Optional[str] = '', cron_schedule_end: Optional[str] = '', enabled: Optional[bool] = None) -> Optional[Slide]:
|
||||
slide = self.get(id)
|
||||
|
||||
if not slide:
|
||||
return
|
||||
|
||||
form = {
|
||||
"duration": duration,
|
||||
"content_id": content_id,
|
||||
"enabled": enabled,
|
||||
"duration": duration if duration else slide.duration,
|
||||
"content_id": content_id if content_id else slide.content_id,
|
||||
"enabled": enabled if isinstance(enabled, bool) else slide.enabled,
|
||||
"delegate_duration": delegate_duration if isinstance(delegate_duration, bool) else slide.delegate_duration,
|
||||
"is_notification": True if is_notification else False,
|
||||
"cron_schedule": get_optional_string(cron_schedule),
|
||||
"cron_schedule_end": get_optional_string(cron_schedule_end)
|
||||
|
||||
@ -164,7 +164,7 @@ class UserManager:
|
||||
|
||||
form = {
|
||||
"username": username if user else user.username,
|
||||
"enabled": enabled if enabled is not None else user.enabled
|
||||
"enabled": enabled if isinstance(enabled, bool) else user.enabled
|
||||
}
|
||||
|
||||
if password is not None and password:
|
||||
|
||||
@ -9,13 +9,14 @@ from src.util.utils import str_to_enum
|
||||
|
||||
class Content:
|
||||
|
||||
def __init__(self, uuid: str = '', location: str = '', type: Union[ContentType, str] = ContentType.URL, name: str = 'Untitled', id: Optional[int] = None, created_by: Optional[str] = None, updated_by: Optional[str] = None, created_at: Optional[int] = None, updated_at: Optional[int] = None, folder_id: Optional[int] = None):
|
||||
def __init__(self, uuid: str = '', location: str = '', type: Union[ContentType, str] = ContentType.URL, name: str = 'Untitled', id: Optional[int] = None, duration: Optional[int] = None, created_by: Optional[str] = None, updated_by: Optional[str] = None, created_at: Optional[int] = None, updated_at: Optional[int] = None, folder_id: Optional[int] = None):
|
||||
self._uuid = uuid if uuid else self.generate_and_set_uuid()
|
||||
self._id = id if id else None
|
||||
self._location = location
|
||||
self._type = str_to_enum(type, ContentType) if isinstance(type, str) else type
|
||||
self._name = name
|
||||
self._folder_id = folder_id
|
||||
self._duration = duration
|
||||
self._created_by = created_by if created_by else None
|
||||
self._updated_by = updated_by if updated_by else None
|
||||
self._created_at = int(created_at if created_at else time.time())
|
||||
@ -86,6 +87,14 @@ class Content:
|
||||
def folder_id(self, value: Optional[int]):
|
||||
self._folder_id = value
|
||||
|
||||
@property
|
||||
def duration(self) -> Optional[int]:
|
||||
return self._duration
|
||||
|
||||
@duration.setter
|
||||
def duration(self, value: Optional[int]):
|
||||
self._duration = value
|
||||
|
||||
@property
|
||||
def type(self) -> ContentType:
|
||||
return self._type
|
||||
@ -114,6 +123,7 @@ class Content:
|
||||
f"created_at='{self.created_at}',\n" \
|
||||
f"updated_at='{self.updated_at}',\n" \
|
||||
f"folder_id='{self.folder_id}',\n" \
|
||||
f"duration='{self.duration}',\n" \
|
||||
f")"
|
||||
|
||||
def to_json(self, edits: dict = {}) -> str:
|
||||
@ -136,6 +146,7 @@ class Content:
|
||||
"created_at": self.created_at,
|
||||
"updated_at": self.updated_at,
|
||||
"folder_id": self.folder_id,
|
||||
"duration": self.duration,
|
||||
}
|
||||
|
||||
if with_virtual:
|
||||
|
||||
@ -3,16 +3,16 @@ import time
|
||||
|
||||
from typing import Optional, Union
|
||||
from src.util.utils import str_to_enum
|
||||
from src.model.enum.ContentType import AUTO_DURATION_CHEATCODE
|
||||
|
||||
|
||||
class Slide:
|
||||
|
||||
def __init__(self, playlist_id: Optional[int] = None, content_id: Optional[int] = None, duration: int = 3, is_notification: bool = False, enabled: bool = False, 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, playlist_id: Optional[int] = None, content_id: Optional[int] = None, delegate_duration=False, duration: int = 3, is_notification: bool = False, enabled: bool = False, 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._playlist_id = playlist_id
|
||||
self._content_id = content_id
|
||||
self._duration = duration
|
||||
self._delegate_duration = delegate_duration
|
||||
self._enabled = enabled
|
||||
self._is_notification = is_notification
|
||||
self._position = position
|
||||
@ -91,6 +91,14 @@ class Slide:
|
||||
def cron_schedule_end(self, value: Optional[str]):
|
||||
self._cron_schedule_end = value
|
||||
|
||||
@property
|
||||
def delegate_duration(self) -> bool:
|
||||
return self._delegate_duration
|
||||
|
||||
@delegate_duration.setter
|
||||
def delegate_duration(self, value: bool):
|
||||
self._delegate_duration = value
|
||||
|
||||
@property
|
||||
def duration(self) -> int:
|
||||
return self._duration
|
||||
@ -129,6 +137,7 @@ class Slide:
|
||||
f"enabled='{self.enabled}',\n" \
|
||||
f"is_notification='{self.is_notification}',\n" \
|
||||
f"duration='{self.duration}',\n" \
|
||||
f"delegate_duration='{self.delegate_duration}',\n" \
|
||||
f"position='{self.position}',\n" \
|
||||
f"created_by='{self.created_by}',\n" \
|
||||
f"updated_by='{self.updated_by}',\n" \
|
||||
@ -155,6 +164,7 @@ class Slide:
|
||||
"is_notification": self.is_notification,
|
||||
"position": self.position,
|
||||
"duration": self.duration,
|
||||
"delegate_duration": self.delegate_duration,
|
||||
"created_by": self.created_by,
|
||||
"updated_by": self.updated_by,
|
||||
"created_at": self.created_at,
|
||||
@ -166,6 +176,3 @@ class Slide:
|
||||
}
|
||||
|
||||
return slide
|
||||
|
||||
def has_auto_duration(self) -> bool:
|
||||
return self.duration == AUTO_DURATION_CHEATCODE
|
||||
|
||||
@ -5,8 +5,6 @@ from typing import Union, List, Optional
|
||||
|
||||
from src.util.utils import str_to_enum
|
||||
|
||||
AUTO_DURATION_CHEATCODE = 98769876
|
||||
|
||||
|
||||
class ContentInputType(Enum):
|
||||
|
||||
@ -26,11 +24,11 @@ class ContentInputType(Enum):
|
||||
|
||||
class ContentType(Enum):
|
||||
|
||||
EXTERNAL_STORAGE = 'external_storage'
|
||||
PICTURE = 'picture'
|
||||
URL = 'url'
|
||||
YOUTUBE = 'youtube'
|
||||
VIDEO = 'video'
|
||||
EXTERNAL_STORAGE = 'external_storage'
|
||||
|
||||
@staticmethod
|
||||
def guess_content_type_file(filename: str):
|
||||
|
||||
@ -158,10 +158,6 @@
|
||||
pause();
|
||||
};
|
||||
|
||||
const isDurationAuto = function(duration) {
|
||||
return duration === {{ auto_duration_cheatcode }};
|
||||
} ;
|
||||
|
||||
const lookupPreviousItem = function() {
|
||||
return (curItemIndex - 1 < 0) ? items.loop[items.loop.length - 1] : items.loop[curItemIndex - 1];
|
||||
};
|
||||
@ -245,7 +241,7 @@
|
||||
|
||||
if (i === curItemIndex) {
|
||||
secondsBeforeNext = accumulatedTime + safe_duration(item) - timeInCurrentLoop;
|
||||
//console.log("remaining:", secondsBeforeNext, "clock:",clockValue, curItemIndex);
|
||||
console.log("remaining:", secondsBeforeNext, "clock:",clockValue, curItemIndex);
|
||||
}
|
||||
|
||||
if (timeInCurrentLoop < accumulatedTime + safe_duration(item)) {
|
||||
@ -375,7 +371,7 @@
|
||||
delayNoisyContentJIT = lookupCurrentItem().id !== item.id ? delayNoisyContentJIT : 0;
|
||||
|
||||
video.addEventListener('loadedmetadata', function() {
|
||||
if (item.duration !== video.duration && isDurationAuto(item.duration)) {
|
||||
if (item.duration !== video.duration && item.delegate_duration) {
|
||||
durationsOverride[item.id] = video.duration;
|
||||
console.warn('Given duration ' + item.duration + 's is different from video file ' + Math.ceil(video.duration) + 's');
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
{% block add_js %}
|
||||
<script type="text/javascript">
|
||||
|
||||
var auto_duration_cheatcode = {{ auto_duration_cheatcode }};
|
||||
var route_slide_position = '{{ url_for('slideshow_slide_position') }}';
|
||||
|
||||
var choices_translations = {
|
||||
|
||||
@ -63,8 +63,8 @@
|
||||
<span class="error"><i class="fa fa-warning danger"></i>️ {{ l.slideshow_slide_panel_td_cron_scheduled_bad_cron }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if slide.has_auto_duration() %}
|
||||
<i class="fa {{ icon }}"></i> <span class="prefix">{{ l.slideshow_slide_panel_th_auto_duration_video }}</span>
|
||||
{% if slide.delegate_duration %}
|
||||
<i class="fa {{ icon }}"></i> <span class="prefix">{{ l.slideshow_slide_panel_th_delegate_duration_video }}</span>
|
||||
{% else %}
|
||||
⏱️ <span class="prefix">{{ slide.duration }} {{ l.slideshow_slide_panel_th_duration_unit }}</span>
|
||||
{% endif %}
|
||||
|
||||
@ -74,12 +74,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-horizontal slide-auto-duration-group">
|
||||
<label for="">{{ l.slideshow_slide_form_label_auto_duration }}</label>
|
||||
<div class="form-group form-group-horizontal slide-delegate-duration-group">
|
||||
<label for="">{{ l.slideshow_slide_form_label_delegate_duration }}</label>
|
||||
<div class="widget">
|
||||
<div class="toggle">
|
||||
<input type="checkbox" class="slide-auto-duration" id="{{ tclass }}-auto-duration" />
|
||||
<label for="{{ tclass }}-auto-duration"></label>
|
||||
<input type="checkbox" name="delegate_duration" class="slide-delegate-duration" id="{{ tclass }}-delegate-duration" value="1" disabled />
|
||||
<label for="{{ tclass }}-delegate-duration"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -72,12 +72,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-horizontal slide-auto-duration-group">
|
||||
<label for="">{{ l.slideshow_slide_form_label_auto_duration }}</label>
|
||||
<div class="form-group form-group-horizontal slide-delegate-duration-group">
|
||||
<label for="">{{ l.slideshow_slide_form_label_delegate_duration }}</label>
|
||||
<div class="widget">
|
||||
<div class="toggle">
|
||||
<input type="checkbox" class="slide-auto-duration" id="{{ tclass }}-auto-duration" />
|
||||
<label for="{{ tclass }}-auto-duration"></label>
|
||||
<input type="checkbox" name="delegate_duration" class="slide-delegate-duration" id="{{ tclass }}-delegate-duration" value="1" disabled />
|
||||
<label for="{{ tclass }}-delegate-duration"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user