1c5b728e8b
FastAPI web server with REST + WebSocket, 5 Jinja2 HTML pages, mobile-friendly dark theme CSS, page-specific JS controllers, and Avahi mDNS service advertisement for pedal.local. Files: src/web/server.py — FastAPI app with 17 REST endpoints + /ws WebSocket src/web/__init__.py — Package init with WebServer, WebServerDeps exports src/web/templates/*.html — Dashboard, Presets, Models, IRs, Settings (base) src/web/static/style.css — Dark mobile-first CSS (80-82% max-width) src/web/static/websocket.js — Auto-reconnecting WebSocket manager src/web/static/app.js — Dashboard live updates + REST helpers src/web/static/presets.js — Bank/preset CRUD modal UI src/web/static/models.js — NAM model list/load/upload src/web/static/irs.js — IR file list/load/upload etc/avahi/pi-multifx-pedal.service — Avahi service advertisement scripts/setup-mdns.sh — One-shot mDNS setup (avahi, hostname, restart) main.py — Wire WebServer into boot/shutdown requirements.txt — Add fastapi, uvicorn, jinja2, python-multipart tests/test_web.py — 36 tests (pages, REST, WebSocket, errors) All 36 tests pass.
34 lines
1.3 KiB
HTML
34 lines
1.3 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Presets — Pi Multi-FX Pedal{% endblock %}
|
|
{% block content %}
|
|
<div class="page presets-page">
|
|
<div class="page-header">
|
|
<h1>Preset Manager</h1>
|
|
<button class="btn btn-secondary" onclick="loadPresets()">⟳ Refresh</button>
|
|
</div>
|
|
|
|
<div class="bank-list" id="bank-list">
|
|
<p class="loading">Loading presets...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-overlay" id="preset-modal" style="display:none" onclick="closeModal(event)">
|
|
<div class="modal" onclick="event.stopPropagation()">
|
|
<div class="modal-header">
|
|
<h2 id="modal-title">Edit Preset</h2>
|
|
<button class="btn-close" onclick="closeModal()">✕</button>
|
|
</div>
|
|
<div class="modal-body" id="modal-body">
|
|
<!-- Dynamic content loaded by JS -->
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" onclick="closeModal()">Cancel</button>
|
|
<button class="btn btn-primary" id="save-preset-btn" onclick="savePreset()">Save</button>
|
|
<button class="btn btn-danger" onclick="deletePreset()">Delete</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block scripts %}
|
|
<script src="/static/presets.js"></script>
|
|
{% endblock %} |