mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 16:58:06 +00:00
fix(web): Rotation & Durations page lists every enabled plugin's screens
The durations grid looped over display.display_durations, which nothing has
ever populated (verified {} on a real production install) - so the page
rendered no duration fields at all. Worse, its inputs posted bare mode
names, which save_main_config's endswith('_duration') filter silently
dropped: the page was broken in both directions, unnoticed because it was
also unreachable (previous commit).
- pages_v3._load_durations_partial now builds one entry per display mode of
every ENABLED plugin via plugin_manager.get_plugin_display_modes()
(falling back to the plugin id), overlaid with saved values, defaulting
to the display controller's 30s. Grouped per plugin, sorted by name.
Saved keys not owned by any enabled plugin stay visible under "Other
saved entries" instead of vanishing.
- durations.html renders the grouped inputs, named duration__<mode_key>
(mode keys are arbitrary, so they can't use the *_duration suffix
convention), with an explanatory empty state when no plugins are enabled.
- api_v3.save_main_config accepts the new duration__<mode> fields and
writes them into display.display_durations under the bare mode key -
exactly what the display controller reads
(display_durations.get(mode_key, 30)).
Validation: py_compile both blueprints; Jinja render with 3 groups asserts
grouped inputs, saved-value overlay, stale-entry group, empty state, and
div balance.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KEZK1P1Q1fu5pcuVrkrCFZ
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
3ab6a731c3
commit
05aee74147
@@ -989,6 +989,25 @@ def save_main_config():
|
||||
if field in data:
|
||||
current_config['display']['display_durations'][field] = int(data[field])
|
||||
|
||||
# Per-mode durations from the Rotation & Durations page, posted as
|
||||
# duration__<mode_key> (mode keys are arbitrary plugin mode names, so
|
||||
# they can't use the suffix convention above)
|
||||
mode_duration_fields = [k for k in data.keys() if k.startswith('duration__')]
|
||||
if mode_duration_fields:
|
||||
if 'display' not in current_config:
|
||||
current_config['display'] = {}
|
||||
if 'display_durations' not in current_config['display']:
|
||||
current_config['display']['display_durations'] = {}
|
||||
|
||||
for field in mode_duration_fields:
|
||||
mode_key = field[len('duration__'):]
|
||||
if not mode_key:
|
||||
continue
|
||||
try:
|
||||
current_config['display']['display_durations'][mode_key] = int(data[field])
|
||||
except (ValueError, TypeError):
|
||||
logger.warning("Ignoring non-integer duration for %s", mode_key)
|
||||
|
||||
# Handle plugin configurations dynamically
|
||||
# Any key that matches a plugin ID should be saved as plugin config
|
||||
# This includes proper secret field handling from schema
|
||||
|
||||
Reference in New Issue
Block a user