preview player & content edit preview ok
This commit is contained in:
parent
a142def001
commit
bd4f97335d
File diff suppressed because one or more lines are too long
@ -164,5 +164,13 @@ form {
|
||||
button {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
&.actions-left {
|
||||
justify-content: flex-start;
|
||||
|
||||
button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,8 +14,55 @@
|
||||
margin: 20px 20px 20px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-panel.right-panel {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
|
||||
h3 {
|
||||
color: white;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
|
||||
span {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 2px;
|
||||
padding: 4px 10px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.iframe-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-top: 56.25%; /* 16:9 aspect ratio */
|
||||
overflow: hidden;
|
||||
border-radius: $baseRadius;
|
||||
outline: 4px solid rgba($white, .1);
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,9 @@ $colors: (
|
||||
danger: $danger,
|
||||
purple: $sweetPurple,
|
||||
youtube: $youtube,
|
||||
neutral: $neutralGrey,
|
||||
white: $white,
|
||||
black: $black,
|
||||
);
|
||||
|
||||
// Classes
|
||||
|
||||
@ -15,6 +15,78 @@ from src.model.enum.AnimationSpeed import animation_speed_duration
|
||||
|
||||
class PlayerController(ObController):
|
||||
|
||||
def register(self):
|
||||
self._app.add_url_rule('/', 'player', self.player, methods=['GET'])
|
||||
self._app.add_url_rule('/use/<playlist_slug_or_id>', 'player_use', self.player, methods=['GET'])
|
||||
self._app.add_url_rule('/player/default', 'player_default', self.player_default, methods=['GET'])
|
||||
self._app.add_url_rule('/player/playlist', 'player_playlist', self.player_playlist, methods=['GET'])
|
||||
self._app.add_url_rule('/player/playlist/use/<playlist_slug_or_id>', 'player_playlist_use', self.player_playlist, methods=['GET'])
|
||||
|
||||
def player(self, playlist_slug_or_id: str = ''):
|
||||
preview_content_id = request.args.get('preview_content_id')
|
||||
playlist_slug_or_id = self._get_dynamic_playlist_id(playlist_slug_or_id)
|
||||
|
||||
current_playlist = self._model_store.playlist().get_one_by("slug = ? OR id = ?", {
|
||||
"slug": playlist_slug_or_id,
|
||||
"id": playlist_slug_or_id
|
||||
})
|
||||
|
||||
if playlist_slug_or_id and not current_playlist:
|
||||
return abort(404)
|
||||
|
||||
playlist_id = current_playlist.id if current_playlist else None
|
||||
|
||||
items = self._get_playlist(playlist_id=playlist_id, preview_content_id=preview_content_id)
|
||||
|
||||
return render_template(
|
||||
'player/player.jinja.html',
|
||||
items=items,
|
||||
default_slide_duration=0 if items['preview_mode'] else self._model_store.variable().get_one_by_name('default_slide_duration').eval(),
|
||||
polling_interval=self._model_store.variable().get_one_by_name('polling_interval'),
|
||||
slide_animation_enabled=self._model_store.variable().get_one_by_name('slide_animation_enabled'),
|
||||
slide_animation_entrance_effect=self._model_store.variable().get_one_by_name('slide_animation_entrance_effect'),
|
||||
slide_animation_exit_effect=self._model_store.variable().get_one_by_name('slide_animation_exit_effect'),
|
||||
slide_animation_speed=self._model_store.variable().get_one_by_name('slide_animation_speed'),
|
||||
animation_speed_duration=animation_speed_duration
|
||||
)
|
||||
|
||||
def player_default(self):
|
||||
return render_template(
|
||||
'player/default.jinja.html',
|
||||
ipaddr=get_ip_address(),
|
||||
time_with_seconds=self._model_store.variable().get_one_by_name('default_slide_time_with_seconds')
|
||||
)
|
||||
|
||||
def player_playlist(self, playlist_slug_or_id: str = ''):
|
||||
playlist_slug_or_id = self._get_dynamic_playlist_id(playlist_slug_or_id)
|
||||
|
||||
current_playlist = self._model_store.playlist().get_one_by("slug = ? OR id = ?", {
|
||||
"slug": playlist_slug_or_id,
|
||||
"id": playlist_slug_or_id
|
||||
})
|
||||
playlist_id = current_playlist.id if current_playlist else None
|
||||
|
||||
return jsonify(self._get_playlist(playlist_id=playlist_id))
|
||||
|
||||
def _get_dynamic_playlist_id(self, playlist_slug_or_id: Optional[str]) -> str:
|
||||
if not playlist_slug_or_id and self._model_store.variable().get_one_by_name('fleet_player_enabled'):
|
||||
node_player = self._model_store.node_player().get_one_by("host = '{}' and enabled = {}".format(
|
||||
get_safe_remote_addr(self.get_remote_addr()),
|
||||
True
|
||||
))
|
||||
|
||||
if node_player and node_player.group_id:
|
||||
node_player_group = self._model_store.node_player_group().get(node_player.group_id)
|
||||
playlist_slug_or_id = node_player_group.playlist_id
|
||||
return playlist_slug_or_id
|
||||
|
||||
@staticmethod
|
||||
def get_remote_addr() -> str:
|
||||
if request.headers.get('X-Forwarded-For'):
|
||||
return request.headers['X-Forwarded-For'].split(',')[0].strip()
|
||||
else:
|
||||
return request.remote_addr
|
||||
|
||||
def _get_playlist(self, playlist_id: Optional[int] = 0, preview_content_id: Optional[int] = None) -> dict:
|
||||
enabled_slides = []
|
||||
preview_mode = False
|
||||
@ -83,73 +155,3 @@ class PlayerController(ObController):
|
||||
}
|
||||
|
||||
return playlists
|
||||
|
||||
def register(self):
|
||||
self._app.add_url_rule('/', 'player', self.player, methods=['GET'])
|
||||
self._app.add_url_rule('/use/<playlist_slug_or_id>', 'player_use', self.player, methods=['GET'])
|
||||
self._app.add_url_rule('/player/default', 'player_default', self.player_default, methods=['GET'])
|
||||
self._app.add_url_rule('/player/playlist', 'player_playlist', self.player_playlist, methods=['GET'])
|
||||
self._app.add_url_rule('/player/playlist/use/<playlist_slug_or_id>', 'player_playlist_use', self.player_playlist, methods=['GET'])
|
||||
|
||||
def player(self, playlist_slug_or_id: str = ''):
|
||||
preview_content_id = request.args.get('preview_content_id')
|
||||
playlist_slug_or_id = self._get_dynamic_playlist_id(playlist_slug_or_id)
|
||||
|
||||
current_playlist = self._model_store.playlist().get_one_by("slug = ? OR id = ?", {
|
||||
"slug": playlist_slug_or_id,
|
||||
"id": playlist_slug_or_id
|
||||
})
|
||||
|
||||
if playlist_slug_or_id and not current_playlist:
|
||||
return abort(404)
|
||||
|
||||
playlist_id = current_playlist.id if current_playlist else None
|
||||
|
||||
return render_template(
|
||||
'player/player.jinja.html',
|
||||
items=json.dumps(self._get_playlist(playlist_id=playlist_id, preview_content_id=preview_content_id)),
|
||||
default_slide_duration=self._model_store.variable().get_one_by_name('default_slide_duration'),
|
||||
polling_interval=self._model_store.variable().get_one_by_name('polling_interval'),
|
||||
slide_animation_enabled=self._model_store.variable().get_one_by_name('slide_animation_enabled'),
|
||||
slide_animation_entrance_effect=self._model_store.variable().get_one_by_name('slide_animation_entrance_effect'),
|
||||
slide_animation_exit_effect=self._model_store.variable().get_one_by_name('slide_animation_exit_effect'),
|
||||
slide_animation_speed=self._model_store.variable().get_one_by_name('slide_animation_speed'),
|
||||
animation_speed_duration=animation_speed_duration
|
||||
)
|
||||
|
||||
def player_default(self):
|
||||
return render_template(
|
||||
'player/default.jinja.html',
|
||||
ipaddr=get_ip_address(),
|
||||
time_with_seconds=self._model_store.variable().get_one_by_name('default_slide_time_with_seconds')
|
||||
)
|
||||
|
||||
def player_playlist(self, playlist_slug_or_id: str = ''):
|
||||
playlist_slug_or_id = self._get_dynamic_playlist_id(playlist_slug_or_id)
|
||||
|
||||
current_playlist = self._model_store.playlist().get_one_by("slug = ? OR id = ?", {
|
||||
"slug": playlist_slug_or_id,
|
||||
"id": playlist_slug_or_id
|
||||
})
|
||||
playlist_id = current_playlist.id if current_playlist else None
|
||||
|
||||
return jsonify(self._get_playlist(playlist_id=playlist_id))
|
||||
|
||||
def _get_dynamic_playlist_id(self, playlist_slug_or_id: Optional[str]) -> str:
|
||||
if not playlist_slug_or_id and self._model_store.variable().get_one_by_name('fleet_player_enabled'):
|
||||
node_player = self._model_store.node_player().get_one_by("host = '{}' and enabled = {}".format(
|
||||
get_safe_remote_addr(self.get_remote_addr()),
|
||||
True
|
||||
))
|
||||
|
||||
if node_player and node_player.group_id:
|
||||
node_player_group = self._model_store.node_player_group().get(node_player.group_id)
|
||||
playlist_slug_or_id = node_player_group.playlist_id
|
||||
return playlist_slug_or_id
|
||||
|
||||
@staticmethod
|
||||
def get_remote_addr() -> str:
|
||||
if request.headers.get('X-Forwarded-For'):
|
||||
return request.headers['X-Forwarded-For'].split(',')[0].strip()
|
||||
else:
|
||||
return request.remote_addr
|
||||
|
||||
@ -136,6 +136,9 @@ class ContentManager(ModelManager):
|
||||
|
||||
if content.type == ContentType.YOUTUBE:
|
||||
form['location'] = get_yt_video_id(form['location'])
|
||||
elif content.type == ContentType.URL:
|
||||
if not form['location'].startswith('http'):
|
||||
form['location'] = "https://{}".format(form['location'])
|
||||
|
||||
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form))
|
||||
self.post_update(id)
|
||||
|
||||
@ -44,3 +44,16 @@ class ContentType(Enum):
|
||||
return 'fa-link'
|
||||
|
||||
return 'fa-file'
|
||||
|
||||
@staticmethod
|
||||
def get_color_icon(value: Enum) -> ContentInputType:
|
||||
if value == ContentType.PICTURE:
|
||||
return 'info'
|
||||
elif value == ContentType.VIDEO:
|
||||
return 'success'
|
||||
elif value == ContentType.YOUTUBE:
|
||||
return 'youtube'
|
||||
elif value == ContentType.URL:
|
||||
return 'danger'
|
||||
|
||||
return 'neutral'
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="IntroSlide" class="slide" style="z-index: 10000;">
|
||||
{% if default_slide_duration.eval() > 0 and not items['preview_mode'] %}
|
||||
{% if default_slide_duration > 0 %}
|
||||
<iframe src="/player/default"></iframe>
|
||||
{% endif %}
|
||||
</div>
|
||||
@ -36,8 +36,8 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
// Backend config
|
||||
let items = {{items | safe}};
|
||||
const introDuration = {{ default_slide_duration.eval() * 1000 }};
|
||||
let items = {{ json_dumps(items) | safe}};
|
||||
const introDuration = {{ default_slide_duration * 1000 }};
|
||||
const playlistCheckResolutionMs = {{ polling_interval.eval() * 1000 }};
|
||||
|
||||
// Backend flag updates
|
||||
@ -59,7 +59,7 @@
|
||||
let pauseClockValue = null;
|
||||
|
||||
// Animations
|
||||
const animate = {{ 'true' if slide_animation_enabled.eval() else 'false' }};
|
||||
const animate = {{ 'true' if slide_animation_enabled.eval() and not items.preview_mode else 'false' }};
|
||||
const animate_speed = "animate__{{ slide_animation_speed.eval()|default("normal") }}";
|
||||
const animation_speed_duration = {{ animation_speed_duration[slide_animation_speed.eval()] if slide_animation_enabled.eval() else 0 }};
|
||||
const animate_transitions = [
|
||||
@ -83,6 +83,10 @@
|
||||
|
||||
// Functions
|
||||
const itemCheck = setInterval(function() {
|
||||
if (items['preview_mode']) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/player/playlist' + (items['playlist_id'] ? '/use/'+items['playlist_id'] : '')).then(function(response) {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
|
||||
@ -78,24 +78,31 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="folder-edit btn-info">
|
||||
<i class="fa fa-save icon-left"></i>
|
||||
{{ l.common_save }}
|
||||
</button>
|
||||
<div class="actions actions-left">
|
||||
<button type="submit" class="folder-edit btn-info">
|
||||
<i class="fa fa-save icon-left"></i>
|
||||
{{ l.common_save }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="preview-holder">
|
||||
Hi
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-panel right-panel">
|
||||
{% set icon = enum_content_type.get_fa_icon(content.type) %}
|
||||
{% set color = enum_content_type.get_color_icon(content.type) %}
|
||||
|
||||
|
||||
<h3>
|
||||
<span class="{{ color }} border-{{ color }}">
|
||||
<i class="fa {{ icon }} {{ color }}"></i> {{ t(content.type) }}
|
||||
</span>
|
||||
</h3>
|
||||
<div class="iframe-wrapper">
|
||||
<iframe src="{{ url_for('player', preview_content_id=content.id) }}"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -177,17 +177,7 @@
|
||||
|
||||
|
||||
{% for content in contents[working_folder.id|default(None)]|default([]) %}
|
||||
{% set icon = enum_content_type.get_fa_icon(content.type) %}
|
||||
|
||||
{% if content.type.value == 'picture' %}
|
||||
{% set icon = icon ~ ' info' %}
|
||||
{% elif content.type.value == 'video' %}
|
||||
{% set icon = icon ~ ' success' %}
|
||||
{% elif content.type.value == 'url' %}
|
||||
{% set icon = icon ~ ' danger' %}
|
||||
{% elif content.type.value == 'youtube' %}
|
||||
{% set icon = icon ~ ' youtube' %}
|
||||
{% endif %}
|
||||
{% set icon = enum_content_type.get_fa_icon(content.type) ~ ' ' ~ enum_content_type.get_color_icon(content.type) %}
|
||||
|
||||
<li class="draggable" data-path="{{ working_folder_path }}" data-id="{{ content.id }}" data-folder="0">
|
||||
<a href="{{ url_for('slideshow_content_show', content_id=content.id) }}" target="_blank" class="explr-link explr-item-selectable">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user