Add presets system and convert back to Flask

- Convert from Microdot back to Flask
- Add presets system with CRUD operations
- Store presets in presets.json file
- Replace patterns section with presets grid
- Add preset editor with full configuration
- Add collapse/expand functionality to left panel
- Always show on/off presets in presets list
- Highlight active preset matching current tab settings
- Add 'Create from Current' button in preset editor
This commit is contained in:
2026-01-08 21:45:55 +13:00
parent ce3b9f4ea5
commit 90be198483
10 changed files with 1758 additions and 71 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lighting Controller</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="app-container">
@@ -15,6 +15,7 @@
<button id="edit-tab-btn" class="btn btn-secondary">Edit Tab</button>
<button id="delete-tab-btn" class="btn btn-danger">Delete Tab</button>
<button id="color-palette-btn" class="btn btn-secondary">Color Palette</button>
<button id="presets-btn" class="btn btn-secondary">Presets</button>
<button id="profiles-btn" class="btn btn-secondary">Profiles</button>
</div>
</header>
@@ -26,60 +27,65 @@
<div id="tab-content" class="tab-content">
<div class="left-panel">
<div class="ids-display">
<label>IDs: </label>
<span id="current-ids"></span>
<div class="left-panel-header">
<div class="ids-display">
<label>IDs: </label>
<span id="current-ids"></span>
</div>
<button id="toggle-left-panel" class="btn btn-small left-panel-toggle" title="Collapse/expand controls"></button>
</div>
<div class="color-palette-section">
<h3>Color Palette</h3>
<div id="color-palette" class="color-palette"></div>
<div class="palette-actions">
<button id="add-color-btn" class="btn btn-small">Add Color</button>
<button id="remove-color-btn" class="btn btn-small">Remove Selected</button>
<div class="left-panel-body">
<div class="color-palette-section">
<h3>Color Palette</h3>
<div id="color-palette" class="color-palette"></div>
<div class="palette-actions">
<button id="add-color-btn" class="btn btn-small">Add Color</button>
<button id="remove-color-btn" class="btn btn-small">Remove Selected</button>
</div>
</div>
</div>
<div class="controls-section">
<div class="control-group">
<label for="brightness-slider">Brightness:</label>
<input type="range" id="brightness-slider" min="0" max="255" value="127" class="slider">
<span id="brightness-value" class="slider-value">127</span>
<div class="controls-section">
<div class="control-group">
<label for="brightness-slider">Brightness:</label>
<input type="range" id="brightness-slider" min="0" max="255" value="127" class="slider">
<span id="brightness-value" class="slider-value">127</span>
</div>
<div class="control-group">
<label for="delay-slider">Delay:</label>
<input type="range" id="delay-slider" min="0" max="1000" value="0" class="slider">
<span id="delay-value" class="slider-value">100 ms</span>
</div>
</div>
<div class="control-group">
<label for="delay-slider">Delay:</label>
<input type="range" id="delay-slider" min="0" max="1000" value="0" class="slider">
<span id="delay-value" class="slider-value">100 ms</span>
</div>
</div>
<div class="n-params-section">
<h3>N Parameters</h3>
<div class="n-params-grid">
<div class="n-param-group">
<label for="n1-input">n1:</label>
<input type="number" id="n1-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n2-input">n2:</label>
<input type="number" id="n2-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n3-input">n3:</label>
<input type="number" id="n3-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n4-input">n4:</label>
<input type="number" id="n4-input" min="0" max="255" value="10" class="n-input">
<div class="n-params-section">
<h3>N Parameters</h3>
<div class="n-params-grid">
<div class="n-param-group">
<label for="n1-input">n1:</label>
<input type="number" id="n1-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n2-input">n2:</label>
<input type="number" id="n2-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n3-input">n3:</label>
<input type="number" id="n3-input" min="0" max="255" value="10" class="n-input">
</div>
<div class="n-param-group">
<label for="n4-input">n4:</label>
<input type="number" id="n4-input" min="0" max="255" value="10" class="n-input">
</div>
</div>
</div>
</div>
</div>
<div class="right-panel">
<div class="patterns-section">
<h3>Patterns</h3>
<div id="patterns-list" class="patterns-list"></div>
<div class="presets-section">
<h3>Presets</h3>
<div id="presets-list-tab" class="presets-list"></div>
</div>
</div>
</div>
@@ -188,7 +194,86 @@
</div>
</div>
<script src="{{ url_for('static', filename='app.js') }}"></script>
<div id="presets-modal" class="modal">
<div class="modal-content" style="min-width: 600px; max-width: 800px;">
<h2>Presets</h2>
<div id="presets-list-container" style="margin: 1rem 0; max-height: 400px; overflow-y: auto;">
<div id="presets-list"></div>
</div>
<div class="modal-actions">
<button id="create-preset-btn" class="btn btn-primary">Create Preset</button>
<button id="presets-close-btn" class="btn btn-secondary">Close</button>
</div>
</div>
</div>
<div id="preset-editor-modal" class="modal">
<div class="modal-content" style="min-width: 600px; max-width: 800px; max-height: 90vh; overflow-y: auto;">
<h2 id="preset-editor-title">Create Preset</h2>
<div style="display: flex; flex-direction: column; gap: 1rem;">
<div>
<label>Preset Name:</label>
<input type="text" id="preset-name-input" placeholder="Enter preset name" style="width: 100%; padding: 0.5rem; margin-top: 0.5rem;">
</div>
<div>
<label>Pattern:</label>
<select id="preset-pattern-select" style="width: 100%; padding: 0.5rem; margin-top: 0.5rem;">
<!-- Patterns will be populated dynamically -->
</select>
</div>
<div>
<label>Brightness:</label>
<div style="display: flex; align-items: center; gap: 1rem; margin-top: 0.5rem;">
<input type="range" id="preset-brightness-slider" min="0" max="255" value="127" class="slider" style="flex: 1;">
<span id="preset-brightness-value" class="slider-value">127</span>
</div>
</div>
<div>
<label>Delay (ms):</label>
<input type="number" id="preset-delay-input" min="10" max="10000" value="100" style="width: 100%; padding: 0.5rem; margin-top: 0.5rem;">
</div>
<div>
<label>N Parameters:</label>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; margin-top: 0.5rem;">
<div>
<label for="preset-n1-input">n1:</label>
<input type="number" id="preset-n1-input" min="0" max="255" value="10" style="width: 100%; padding: 0.5rem;">
</div>
<div>
<label for="preset-n2-input">n2:</label>
<input type="number" id="preset-n2-input" min="0" max="255" value="10" style="width: 100%; padding: 0.5rem;">
</div>
<div>
<label for="preset-n3-input">n3:</label>
<input type="number" id="preset-n3-input" min="0" max="255" value="10" style="width: 100%; padding: 0.5rem;">
</div>
<div>
<label for="preset-n4-input">n4:</label>
<input type="number" id="preset-n4-input" min="0" max="255" value="10" style="width: 100%; padding: 0.5rem;">
</div>
</div>
</div>
<div>
<label>Colors:</label>
<div id="preset-colors-container" style="margin-top: 0.5rem; display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.5rem; background-color: #3a3a3a; border-radius: 4px; min-height: 60px;">
<!-- Colors will be rendered here -->
</div>
<div style="display: flex; gap: 0.5rem; margin-top: 0.5rem;">
<input type="color" id="preset-new-color" value="#000000" style="width: 60px; height: 40px; border: 1px solid #4a4a4a; border-radius: 4px; cursor: pointer;">
<button id="preset-add-color-btn" class="btn btn-small">Add Color</button>
<button id="preset-remove-color-btn" class="btn btn-small">Remove Selected</button>
</div>
</div>
<div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
<button id="preset-editor-from-current-btn" class="btn btn-secondary" style="flex: 1;">Create from Current</button>
<button id="preset-editor-save-btn" class="btn btn-primary" style="flex: 1;">Save Preset</button>
<button id="preset-editor-cancel-btn" class="btn btn-secondary" style="flex: 1;">Cancel</button>
</div>
</div>
</div>
</div>
<script src="/static/app.js"></script>
</body>
</html>