Redesign UI with dropdown sound selection

Major UI Overhaul:
- Replace individual buttons with dropdown selectors
- New "Sound Assignment" card with 3 dropdowns:
  * Greeting Sound (plays on pickup)
  * Button Sound (plays when button pressed)
  * Recording Beep (plays before recording)
- Rename "Greeting Messages" to "Available Sounds"
- Show sound usage badges (🔘📣) in sound list
- Cleaner, more intuitive interface

Benefits:
- Easier to see which sound is assigned where
- One click to change assignments
- Less clutter with fewer buttons
- Shows duration in dropdown options
- Better visual hierarchy

Template v1.5.0 - will auto-regenerate on restart

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-27 12:50:18 +07:00
parent 4f6398858e
commit fbe9bb2f9a

View File

@@ -81,7 +81,7 @@ BACKUP_ON_WRITE = BACKUP_CONFIG.get('backup_on_write', True)
WEB_PORT = SYS_CONFIG['web']['port']
# Template version - increment this when HTML template changes
TEMPLATE_VERSION = "1.4.0" # Updated: Added recording beep sound feature
TEMPLATE_VERSION = "1.5.0" # Updated: Redesigned sound selection with dropdowns
# Flask app
app = Flask(__name__)
@@ -1176,7 +1176,28 @@ def main():
.upload-label:hover {
background: #5568d3;
}
.sound-selector {
width: 100%;
padding: 12px;
font-size: 1em;
border: 2px solid #e5e7eb;
border-radius: 8px;
background: white;
cursor: pointer;
transition: border-color 0.3s;
}
.sound-selector:hover {
border-color: #667eea;
}
.sound-selector:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.btn {
padding: 10px 20px;
border: none;
@@ -1555,20 +1576,62 @@ def main():
</div>
</div>
<!-- Greeting Messages Card -->
<!-- Sound Assignment Card -->
<div class="card">
<h2>🎵 Greeting Messages</h2>
<h2>🎵 Sound Assignment</h2>
<div class="alert alert-info">
Active greeting: <strong>{{ active_greeting }}</strong>
{% if extra_button_enabled %}
<br>🔘 Extra button sound: <strong>{{ extra_button_sound }}</strong>
{% endif %}
<div style="padding: 20px; border-bottom: 1px solid #e5e7eb;">
<h3 style="margin: 0 0 15px 0; font-size: 1.1em; color: #333;">⭐ Greeting Sound</h3>
<p style="margin-bottom: 10px; color: #6b7280; font-size: 0.9em;">
Plays when handset is picked up
</p>
<select id="greeting-selector" class="sound-selector" onchange="setActiveGreeting(this.value)">
{% for greeting in greetings %}
<option value="{{ greeting.filename }}" {% if greeting.is_active %}selected{% endif %}>
{{ greeting.filename }} ({{ "%.1f"|format(greeting.duration) }}s)
</option>
{% endfor %}
</select>
</div>
{% if extra_button_enabled %}
<div style="padding: 20px; border-bottom: 1px solid #e5e7eb;">
<h3 style="margin: 0 0 15px 0; font-size: 1.1em; color: #333;">🔘 Button Sound</h3>
<p style="margin-bottom: 10px; color: #6b7280; font-size: 0.9em;">
Plays when extra button is pressed during recording
</p>
<select id="button-selector" class="sound-selector" onchange="setExtraButtonSound(this.value)">
{% for greeting in greetings %}
<option value="{{ greeting.filename }}" {% if greeting.is_button_sound %}selected{% endif %}>
{{ greeting.filename }} ({{ "%.1f"|format(greeting.duration) }}s)
</option>
{% endfor %}
</select>
</div>
{% endif %}
<div style="padding: 20px;">
<h3 style="margin: 0 0 15px 0; font-size: 1.1em; color: #333;">📣 Recording Beep</h3>
<p style="margin-bottom: 10px; color: #6b7280; font-size: 0.9em;">
Plays after greeting to signal recording start
</p>
<select id="beep-selector" class="sound-selector" onchange="setBeepSound(this.value)">
{% for greeting in greetings %}
<option value="{{ greeting.filename }}" {% if greeting.is_beep_sound %}selected{% endif %}>
{{ greeting.filename }} ({{ "%.1f"|format(greeting.duration) }}s)
</option>
{% endfor %}
</select>
</div>
</div>
<!-- Available Sounds Card -->
<div class="card">
<h2>🔊 Available Sounds</h2>
<div class="upload-section">
<p style="margin-bottom: 15px; color: #6b7280;">
Upload WAV files to play when the handset is picked up
Upload WAV audio files for greetings, button sounds, and beeps
</p>
<form id="upload-form" enctype="multipart/form-data">
<label for="soundfile" class="upload-label">
@@ -1580,7 +1643,7 @@ def main():
<div class="button-group">
<button class="btn btn-primary" onclick="uploadGreeting()" id="upload-btn" disabled>
⬆️ Upload Greeting(s)
⬆️ Upload Sound(s)
</button>
<button class="btn btn-secondary" onclick="restoreDefault()">
🔄 Generate Default Dial Tone
@@ -1588,60 +1651,32 @@ def main():
</div>
</div>
<!-- Greetings List -->
<!-- Sounds List -->
{% if greetings %}
<h3 style="margin-top: 30px; margin-bottom: 15px; color: #333;">Available Greetings</h3>
<h3 style="margin-top: 30px; margin-bottom: 15px; color: #333;">Uploaded Sounds</h3>
<div class="recordings-grid">
{% for greeting in greetings %}
<div class="recording-item {% if greeting.is_active %}active-greeting{% endif %}" id="greeting-{{ loop.index }}">
<div class="recording-item" id="greeting-{{ loop.index }}">
<div class="recording-info">
<h3>
{% if greeting.is_active %}⭐{% endif %}
{% if greeting.is_button_sound and extra_button_enabled %}🔘{% endif %}
{{ greeting.filename }}
</h3>
<h3>{{ greeting.filename }}</h3>
<div class="recording-meta">
📅 {{ greeting.date }} |
⏱️ {{ "%.1f"|format(greeting.duration) }}s |
💾 {{ "%.2f"|format(greeting.size_mb) }} MB
</div>
<div style="margin-top: 5px; font-size: 0.85em; color: #667eea;">
{% if greeting.is_active %}⭐ Active Greeting{% endif %}
{% if greeting.is_button_sound and extra_button_enabled %}{% if greeting.is_active %} | {% endif %}🔘 Button Sound{% endif %}
{% if greeting.is_beep_sound %}{% if greeting.is_active or greeting.is_button_sound %} | {% endif %}📣 Beep Sound{% endif %}
</div>
</div>
<div class="recording-actions">
<button class="btn btn-success" onclick="playAudio('greeting', '{{ greeting.filename }}')">
▶️ Play
</button>
{% if not greeting.is_active %}
<button class="btn btn-primary" onclick="setActiveGreeting('{{ greeting.filename }}')">
⭐ Set Active
</button>
{% if extra_button_enabled and not greeting.is_button_sound %}
<button class="btn btn-primary" onclick="setExtraButtonSound('{{ greeting.filename }}')">
🔘 Set Button
</button>
{% endif %}
{% if not greeting.is_beep_sound %}
<button class="btn btn-primary" onclick="setBeepSound('{{ greeting.filename }}')">
📣 Set Beep
</button>
{% endif %}
<button class="btn btn-danger" onclick="deleteGreeting('{{ greeting.filename }}', {{ loop.index }})">
🗑️ Delete
</button>
{% else %}
<button class="btn btn-secondary" disabled>
✓ Active
</button>
{% if extra_button_enabled and not greeting.is_button_sound %}
<button class="btn btn-primary" onclick="setExtraButtonSound('{{ greeting.filename }}')">
🔘 Set Button
</button>
{% endif %}
{% if not greeting.is_beep_sound %}
<button class="btn btn-primary" onclick="setBeepSound('{{ greeting.filename }}')">
📣 Set Beep
</button>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
@@ -1649,7 +1684,7 @@ def main():
{% else %}
<div class="no-recordings" style="margin-top: 20px;">
<p style="font-size: 2em; margin-bottom: 10px;">🎵</p>
<p>No greeting messages uploaded yet. Upload your first greeting!</p>
<p>No sounds uploaded yet. Upload your first sound file!</p>
</div>
{% endif %}
</div>