Release v2.4.2

This commit is contained in:
2026-08-03 12:45:27 +01:00
parent 2b9cabdab2
commit e95928f31c
141 changed files with 7694 additions and 5078 deletions
+102 -9
View File
@@ -5,6 +5,70 @@
</div>
</div>
{{#if (hasPermission currentUser 'clients.allow')}}
<div class="card card-outline card-secondary mb-4 screen-command-card">
<div class="card-header">
<div class="dashboard-card-heading">
<h3 class="card-title">Screen-level controls</h3>
</div>
</div>
<div class="card-body">
{{#if screens.length}}
<div class="screen-command-panel">
<div class="screen-command-panel-left">
<div class="screen-command-selector-field">
<label class="screen-command-selector-label" for="screen-command-select">Target screen</label>
<div class="input-group input-group-sm">
<span class="input-group-text" aria-hidden="true"><i class="bi bi-broadcast"></i></span>
<select
id="screen-command-select"
class="form-select"
aria-label="Target screen"
data-screen-command-select
>
{{#each screens}}
<option
value="{{slug}}"
data-screen-name="{{name}}"
data-player-connection-count="{{player_connection_count}}"
data-playlist-name="{{playlist_name}}"
>{{name}}</option>
{{/each}}
</select>
</div>
</div>
<div class="screen-command-actions">
<form method="post" action="#" class="inline-form" data-confirm-message="Reload selected screen?" data-async-command data-screen-command-form data-screen-command-action="reload">
<input type="hidden" name="command" value="reload" />
<button type="submit" class="btn btn-sm btn-danger"><i class="bi bi-arrow-repeat me-1" aria-hidden="true"></i>Reload screen</button>
</form>
<form method="post" action="#" class="inline-form" data-confirm-message="Pause selected screen?" data-async-command data-screen-command-form data-screen-command-action="pause">
<input type="hidden" name="command" value="pause" />
<input type="hidden" name="paused" value="true" />
<button type="submit" class="btn btn-sm btn-info"><i class="bi bi-pause-fill me-1" aria-hidden="true"></i>Pause screen</button>
</form>
<form method="post" action="#" class="inline-form" data-confirm-message="Blackout selected screen?" data-async-command data-screen-command-form data-screen-command-action="blackout">
<input type="hidden" name="command" value="blackout" />
<input type="hidden" name="blackout" value="true" />
<button type="submit" class="btn btn-sm btn-secondary"><i class="bi bi-eye-slash me-1" aria-hidden="true"></i>Blackout screen</button>
</form>
</div>
</div>
<div class="screen-command-panel-right">
<div class="screen-command-summary">
<span class="screen-command-pill is-live" data-screen-command-pill>Choose a screen</span>
<strong data-screen-command-name>Select a target screen</strong>
<span class="screen-command-summary-meta" data-screen-command-meta>Commands update automatically for the selected screen.</span>
</div>
</div>
</div>
{{else}}
<div class="empty">No screens are available to target yet.</div>
{{/if}}
</div>
</div>
{{/if}}
<div class="card card-outline card-primary" data-table-search-container data-table-pagination-card>
<div class="card-header">
<h3 class="card-title">Active connections</h3>
@@ -69,31 +133,28 @@
<form method="post" action="/clients/{{screen_slug}}/commands" class="inline-form" data-confirm-message="Reloading will restart the player page. Continue?" data-async-command>
<input type="hidden" name="command" value="reload" />
<input type="hidden" name="connectionId" value="{{id}}" />
<button type="submit" class="btn btn-sm btn-danger">Reload</button>
<button type="submit" class="btn btn-sm btn-danger" aria-label="Reload client" title="Reload client"><i class="bi bi-arrow-repeat" aria-hidden="true"></i></button>
</form>
<button type="button" class="btn btn-sm btn-danger" data-action="move-screen" data-bs-toggle="modal" data-bs-target="#client-move-screen-modal" aria-label="Move client to another screen" title="Move client to another screen"><i class="bi bi-display" aria-hidden="true"></i></button>
<form method="post" action="/clients/{{screen_slug}}/commands" class="inline-form" data-async-command>
<input type="hidden" name="command" value="previous" />
<input type="hidden" name="connectionId" value="{{id}}" />
<button type="submit" class="btn btn-sm btn-warning" aria-label="Previous slide"></button>
<button type="submit" class="btn btn-sm btn-warning" aria-label="Previous slide" title="Previous slide"><i class="bi bi-skip-backward-fill" aria-hidden="true"></i></button>
</form>
<form method="post" action="/clients/{{screen_slug}}/commands" class="inline-form" data-async-command>
<input type="hidden" name="command" value="next" />
<input type="hidden" name="connectionId" value="{{id}}" />
<button type="submit" class="btn btn-sm btn-warning" aria-label="Next slide"></button>
<button type="submit" class="btn btn-sm btn-warning" aria-label="Next slide" title="Next slide"><i class="bi bi-skip-forward-fill" aria-hidden="true"></i></button>
</form>
<form method="post" action="/clients/{{screen_slug}}/commands" class="inline-form" data-async-command>
<input type="hidden" name="command" value="pause" />
<input type="hidden" name="connectionId" value="{{id}}" />
<button type="submit" class="btn btn-sm btn-info">
<i class="bi bi-pause-fill me-1" aria-hidden="false"></i>Pause
</button>
<button type="submit" class="btn btn-sm btn-info" aria-label="Pause client" title="Pause client"><i class="bi bi-pause-fill me-1" aria-hidden="true"></i>Pause</button>
</form>
<form method="post" action="/clients/{{screen_slug}}/commands" class="inline-form" data-async-command>
<input type="hidden" name="command" value="blackout" />
<input type="hidden" name="connectionId" value="{{id}}" />
<button type="submit" class="btn btn-sm {{#if blackout}}btn-success{{else}}btn-secondary{{/if}}">
<i class="bi bi-eye-slash me-1" aria-hidden="false"></i>Blackout
</button>
<button type="submit" class="btn btn-sm {{#if blackout}}btn-success{{else}}btn-secondary{{/if}}" aria-label="{{#if blackout}}Restore client{{else}}Blackout client{{/if}}" title="{{#if blackout}}Restore client{{else}}Blackout client{{/if}}"><i class="bi {{#if blackout}}bi-eye{{else}}bi-eye-slash{{/if}} me-1" aria-hidden="true"></i>{{#if blackout}}Restore{{else}}Blackout{{/if}}</button>
</form>
</div>
</td>
@@ -108,3 +169,35 @@
</div>
{{> table-pagination pagination=pagination basePath="/clients" alwaysShow=true}}
</div>
{{#> modal-shell modalId="client-move-screen-modal" modalLabelId="client-move-screen-modal-label" modalDialogClass="modal-dialog-centered modal-dialog-scrollable modal-lg" modalBackdropStatic=true modalKeyboardDisabled=true}}
<form id="client-move-screen-form" method="post" action="#" class="d-flex flex-column">
<div class="modal-header">
<div>
<h2 class="modal-title fs-5" id="client-move-screen-modal-label">Move client to another screen</h2>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" name="command" value="moveclient" />
<input type="hidden" name="connectionId" value="" data-client-move-connection-id />
<input type="hidden" name="deviceId" value="" data-client-move-device-id />
<input type="hidden" name="clientName" value="" data-client-move-client-name />
<label class="form-label" for="client-move-screen-target">Target screen</label>
<select class="form-select" id="client-move-screen-target" name="targetScreenSlug" data-client-move-target required>
{{#if screens.length}}
<option value="">Select a screen</option>
{{#each screens}}
<option value="{{slug}}">{{name}}</option>
{{/each}}
{{else}}
<option value="">No screens available</option>
{{/if}}
</select>
</div>
<div class="modal-footer justify-content-end gap-2">
<button type="submit" class="btn btn-primary">Move client</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Close</button>
</div>
</form>
{{/modal-shell}}