HiFi instances: 'Restore Defaults' button (re-adds removed defaults, keeps customs) + bigger tap targets for the ✔/✖ controls (Sokhi)
This commit is contained in:
parent
6e7fd3ff5c
commit
fb260baa48
4 changed files with 81 additions and 5 deletions
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)}`, {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue