HiFi instances: 'Restore Defaults' button (re-adds removed defaults, keeps customs) + bigger tap targets for the ✔/✖ controls (Sokhi)

This commit is contained in:
BoulderBadgeDad 2026-06-13 09:16:39 -07:00
parent 6e7fd3ff5c
commit fb260baa48
4 changed files with 81 additions and 5 deletions

View file

@ -21611,6 +21611,35 @@ def hifi_reorder_instances():
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/api/hifi/instances/reset', methods=['POST'])
@admin_only
def hifi_reset_instances():
"""Restore any built-in default HiFi instances that were removed.
Non-destructive (#Sokhi): keeps user-added instances and the existing
order/enabled state, and only re-adds the provided defaults that are
currently missing so you can recover ones you removed by accident without
wiping the working instance you just found."""
try:
from database.music_database import get_database
from core.hifi_client import DEFAULT_INSTANCES
db = get_database()
existing = {(i.get('url') or '').rstrip('/') for i in db.get_all_hifi_instances()}
priority = len(existing)
restored = []
for url in DEFAULT_INSTANCES:
u = url.rstrip('/')
if u not in existing and db.add_hifi_instance(u, priority):
restored.append(u)
priority += 1
if download_orchestrator:
download_orchestrator.reload_instances('hifi')
return jsonify({'success': True, 'restored': len(restored), 'urls': restored})
except Exception as e:
logger.error(f"Error resetting HiFi instances: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/api/hifi/instances/list', methods=['GET'])
@admin_only
def hifi_list_instances():

View file

@ -4876,7 +4876,10 @@
<input type="url" id="hifi-new-instance" class="form-input" placeholder="https://example.com" style="flex:1;">
<button class="test-button" onclick="addHiFiInstance()">Add</button>
</div>
<button class="test-button" onclick="checkHiFiInstances()" id="hifi-instances-check-btn" style="margin-bottom: 8px;">Check All Instances</button>
<div style="display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap;">
<button class="test-button" onclick="checkHiFiInstances()" id="hifi-instances-check-btn">Check All Instances</button>
<button class="test-button" onclick="restoreDefaultHiFiInstances()" id="hifi-instances-restore-btn" title="Re-add any of the built-in default instances you've removed (keeps the ones you added)">Restore Defaults</button>
</div>
<div id="hifi-instances-status-panel" style="display: none;"></div>
</div>
</div>

View file

@ -4220,6 +4220,30 @@ async function addHiFiInstance() {
}
}
async function restoreDefaultHiFiInstances() {
const btn = document.getElementById('hifi-instances-restore-btn');
const orig = btn ? btn.textContent : '';
if (btn) { btn.disabled = true; btn.textContent = 'Restoring…'; }
try {
const resp = await fetch('/api/hifi/instances/reset', { method: 'POST' });
const data = await resp.json();
if (data.success) {
loadHiFiInstances();
const n = data.restored || 0;
if (typeof showToast === 'function') {
showToast(n ? `Restored ${n} default instance${n === 1 ? '' : 's'}`
: 'All default instances are already present', 'success');
}
} else {
alert(data.error || 'Failed to restore defaults');
}
} catch (e) {
alert(`Error: ${e.message}`);
} finally {
if (btn) { btn.disabled = false; btn.textContent = orig || 'Restore Defaults'; }
}
}
async function removeHiFiInstance(url) {
try {
const resp = await fetch(`/api/hifi/instances?url=${encodeURIComponent(url)}`, {

View file

@ -62637,8 +62637,19 @@ body[data-artist-source="source"] #artist-detail-page #library-artist-enhance-bt
.hifi-instance-toggle {
flex-shrink: 0;
cursor: pointer;
font-size: 0.9em;
transition: color 0.15s;
font-size: 0.95em;
transition: color 0.15s, background 0.15s;
/* Bigger tap target — the bare glyph was hard to hit/register (#Sokhi). */
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 30px;
height: 30px;
border-radius: 6px;
user-select: none;
}
.hifi-instance-toggle:hover {
background: rgba(255, 255, 255, 0.07);
}
.hifi-instance-toggle.on {
color: #4caf50;
@ -62656,11 +62667,20 @@ body[data-artist-source="source"] #artist-detail-page #library-artist-enhance-bt
flex-shrink: 0;
color: #f44336;
cursor: pointer;
font-size: 0.9em;
transition: color 0.15s;
font-size: 0.95em;
transition: color 0.15s, background 0.15s;
/* Bigger tap target — the bare ✖ was hard to hit/register (#Sokhi). */
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 30px;
height: 30px;
border-radius: 6px;
user-select: none;
}
.hifi-instance-remove:hover {
color: #ef5350;
background: rgba(244, 67, 54, 0.15);
}
/* ==========================================================================