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
|
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'])
|
@app.route('/api/hifi/instances/list', methods=['GET'])
|
||||||
@admin_only
|
@admin_only
|
||||||
def hifi_list_instances():
|
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;">
|
<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>
|
<button class="test-button" onclick="addHiFiInstance()">Add</button>
|
||||||
</div>
|
</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 id="hifi-instances-status-panel" style="display: none;"></div>
|
||||||
</div>
|
</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) {
|
async function removeHiFiInstance(url) {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`/api/hifi/instances?url=${encodeURIComponent(url)}`, {
|
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 {
|
.hifi-instance-toggle {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 0.9em;
|
font-size: 0.95em;
|
||||||
transition: color 0.15s;
|
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 {
|
.hifi-instance-toggle.on {
|
||||||
color: #4caf50;
|
color: #4caf50;
|
||||||
|
|
@ -62656,11 +62667,20 @@ body[data-artist-source="source"] #artist-detail-page #library-artist-enhance-bt
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
color: #f44336;
|
color: #f44336;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 0.9em;
|
font-size: 0.95em;
|
||||||
transition: color 0.15s;
|
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 {
|
.hifi-instance-remove:hover {
|
||||||
color: #ef5350;
|
color: #ef5350;
|
||||||
|
background: rgba(244, 67, 54, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue