Move Order and Display mode to the Photos tab
Build and push server image / build-and-push (push) Successful in 53s
Build and push server image / build-and-push (push) Successful in 53s
Both are photos-specific settings (rotation order, how a photo's aspect ratio gets reconciled with the panel), not device-wide configuration -- they belonged on the Photos tab next to the album/queue settings, not Configuration. No backend change: both already save through the shared partial-update /config endpoint regardless of which tab's form sends them.
This commit is contained in:
@@ -42,7 +42,10 @@ def _frame_page(request: Request, db: Session, frame_id: int, template: str, tab
|
||||
|
||||
@router.get("/frames/{frame_id}", response_class=HTMLResponse)
|
||||
def frame_photos_page(frame_id: int, request: Request, db: Session = Depends(get_db)):
|
||||
return _frame_page(request, db, frame_id, "frame_photos.html", "photos")
|
||||
return _frame_page(
|
||||
request, db, frame_id, "frame_photos.html", "photos",
|
||||
display_mode_labels=DISPLAY_MODE_LABELS,
|
||||
)
|
||||
|
||||
|
||||
def _user_available_calendars(user: User) -> list[dict]:
|
||||
@@ -122,7 +125,6 @@ def frame_config_page(frame_id: int, request: Request, db: Session = Depends(get
|
||||
palette_labels=PALETTE_LABELS,
|
||||
default_palette_rgb=DEFAULT_PALETTE_RGB,
|
||||
palette_to_hex=palette_to_hex,
|
||||
display_mode_labels=DISPLAY_MODE_LABELS,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// Configuration tab: frame settings + firmware card + take control.
|
||||
// Frame name/mode live in the page header now (frame_header.js) and
|
||||
// Calendar settings have their own tab (frame_calendar.js). window.
|
||||
// FRAME_API is set by the template. Checkboxes are always sent
|
||||
// explicitly as "true"/"false" -- the server treats absent fields as
|
||||
// "leave unchanged", so a checkbox must never be simply omitted.
|
||||
// Frame name/mode live in the page header now (frame_header.js), Calendar
|
||||
// settings have their own tab (frame_calendar.js), and Order/Display mode
|
||||
// live on the Photos tab (frame_photos.js) -- photos-specific settings,
|
||||
// not device-wide configuration. window.FRAME_API is set by the template.
|
||||
// Checkboxes are always sent explicitly as "true"/"false" -- the server
|
||||
// treats absent fields as "leave unchanged", so a checkbox must never be
|
||||
// simply omitted.
|
||||
|
||||
async function saveConfig() {
|
||||
const minutes = parseInt(document.getElementById('refresh_interval_minutes').value, 10) || 60;
|
||||
const body = new URLSearchParams({
|
||||
order: document.getElementById('order').value,
|
||||
orientation: document.getElementById('orientation').value,
|
||||
refresh_interval_s: String(minutes * 60),
|
||||
display_mode: document.getElementById('display_mode').value,
|
||||
quiet_hours_enabled: String(document.getElementById('quiet_hours_enabled').checked),
|
||||
quiet_hours_start: document.getElementById('quiet_hours_start').value || '22:00',
|
||||
quiet_hours_end: document.getElementById('quiet_hours_end').value || '07:00',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Photos tab: now-displaying, album picker, and the upcoming grid
|
||||
// (rendering/drag logic in queue.js). window.FRAME_API is set by the
|
||||
// template.
|
||||
// Photos tab: now-displaying, album picker, order/display-mode settings,
|
||||
// and the upcoming grid (rendering/drag logic in queue.js). window.
|
||||
// FRAME_API is set by the template.
|
||||
|
||||
function renderControlBanner(control) {
|
||||
const banner = document.getElementById('control-banner');
|
||||
@@ -74,6 +74,8 @@ async function savePhotoSettings() {
|
||||
const body = new URLSearchParams({
|
||||
album_id: document.getElementById('album_id').value || '',
|
||||
queue_target_len: document.getElementById('queue_target_len').value,
|
||||
order: document.getElementById('order').value,
|
||||
display_mode: document.getElementById('display_mode').value,
|
||||
});
|
||||
const resp = await fetch(`${window.FRAME_API}/config`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
<section class="card">
|
||||
<h2 class="card-title">Display settings</h2>
|
||||
<form id="config-form">
|
||||
<label>Order
|
||||
<select id="order">
|
||||
<option value="sequential" {% if frame.order == "sequential" %}selected{% endif %}>Sequential</option>
|
||||
<option value="shuffle" {% if frame.order == "shuffle" %}selected{% endif %}>Shuffle</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Orientation
|
||||
<select id="orientation">
|
||||
<option value="landscape" {% if frame.orientation == "landscape" %}selected{% endif %}>Landscape</option>
|
||||
@@ -36,21 +30,6 @@
|
||||
<input type="number" id="refresh_interval_minutes" min="1" max="1440"
|
||||
value="{{ (frame.refresh_interval_s // 60) or 60 }}" required>
|
||||
</label>
|
||||
<label>Display mode
|
||||
<select id="display_mode">
|
||||
{% for mode, label in display_mode_labels.items() %}
|
||||
<option value="{{ mode }}" {% if frame.display_mode == mode %}selected{% endif %}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<p class="sub" style="margin-top: 8px;">How a photo's aspect ratio
|
||||
is reconciled with the panel's: <strong>Crop to fill</strong>
|
||||
trims the excess; <strong>Crop to faces</strong> does the same
|
||||
but shifts the crop to keep people on screen; <strong>Stretch to
|
||||
fill</strong> fills the panel exactly without cropping (photos
|
||||
not matching the panel's aspect ratio look stretched);
|
||||
<strong>Shrink to fit</strong> shows the whole photo, letterboxed
|
||||
if needed.</p>
|
||||
<div class="checkbox-row">
|
||||
<input type="checkbox" id="quiet_hours_enabled" {% if frame.quiet_hours_enabled %}checked{% endif %}>
|
||||
<label for="quiet_hours_enabled">Quiet hours (don't wake overnight)</label>
|
||||
|
||||
@@ -30,6 +30,27 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>Order
|
||||
<select id="order">
|
||||
<option value="sequential" {% if frame.order == "sequential" %}selected{% endif %}>Sequential</option>
|
||||
<option value="shuffle" {% if frame.order == "shuffle" %}selected{% endif %}>Shuffle</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Display mode
|
||||
<select id="display_mode">
|
||||
{% for mode, label in display_mode_labels.items() %}
|
||||
<option value="{{ mode }}" {% if frame.display_mode == mode %}selected{% endif %}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<p class="sub" style="margin-top: 8px;">How a photo's aspect ratio
|
||||
is reconciled with the panel's: <strong>Crop to fill</strong>
|
||||
trims the excess; <strong>Crop to faces</strong> does the same
|
||||
but shifts the crop to keep people on screen; <strong>Stretch to
|
||||
fill</strong> fills the panel exactly without cropping (photos
|
||||
not matching the panel's aspect ratio look stretched);
|
||||
<strong>Shrink to fit</strong> shows the whole photo, letterboxed
|
||||
if needed.</p>
|
||||
<button type="button" class="secondary" id="load-albums">Load Albums</button>
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user