refactor: redesign ABS settings row to match backend status style

This commit is contained in:
Honey committed 2026-06-04 22:56:45 +02:00
1 parent d94dadf309
commit 64c107da0b
3 files changed
+47 -15

No files matched your search

+9 -4
View File
@@ -637,11 +637,16 @@
<label>Bibliothek</label>
<select id="abs-lib-select" onchange="absSetLibrary(this.value)" style="width:100%;padding:10px 12px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--radius-sm);color:var(--text);font-family:var(--font);font-size:14px;outline:none"></select>
</div>
<div style="display:flex;gap:8px;margin-top:8px">
<button class="btn-outline" style="flex:1;padding:9px;font-size:13px;color:var(--danger);border-color:rgba(224,85,85,0.3)" onclick="absDisconnect()">Trennen</button>
<button class="btn-outline" id="abs-s-connect-btn" style="flex:1;padding:9px;font-size:13px;font-weight:700" onclick="absConnectSettings()">Verbinden</button>
<div class="settings-row" style="margin-top:8px;border-radius:9px">
<div>
<div style="font-size:13px;font-weight:500">Audiobookshelf Status</div>
<div class="hint" id="abs-s-status">Nicht verbunden</div>
</div>
<div style="display:flex;align-items:center;gap:8px">
<div class="status-dot" id="abs-s-dot" style="display:none"></div>
<button class="btn-outline" id="abs-s-connect-btn" style="padding:6px 12px;font-size:12px;font-weight:600" onclick="absToggleConnection()">Verbinden</button>
</div>
</div>
<span id="abs-s-status" style="font-size:12px;color:var(--green);display:block;margin-top:6px;min-height:16px"></span>
</div>
<div class="settings-section">
<h3 style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
+36 -9
View File
@@ -659,12 +659,42 @@ function _showAbsNavItem(show) {
if (bnav) bnav.style.display = show ? '' : 'none';
}
function _setAbsStatusRow(state, msg) {
// state: 'connected' | 'error' | 'none'
const statusEl = document.getElementById('abs-s-status');
const dotEl = document.getElementById('abs-s-dot');
const btnEl = document.getElementById('abs-s-connect-btn');
if (statusEl) statusEl.textContent = msg || 'Nicht verbunden';
if (dotEl) {
dotEl.style.display = state === 'none' ? 'none' : 'block';
dotEl.className = 'status-dot' + (state === 'connected' ? ' ok' : state === 'error' ? ' err' : '');
}
if (btnEl) {
btnEl.disabled = false;
if (state === 'connected') {
btnEl.textContent = 'Trennen';
btnEl.style.color = 'var(--danger)';
btnEl.style.borderColor = 'rgba(224,85,85,0.3)';
} else {
btnEl.textContent = 'Verbinden';
btnEl.style.color = '';
btnEl.style.borderColor = '';
}
}
}
export function absOpenSettings() {
const urlEl = document.getElementById('abs-s-url');
if (urlEl) urlEl.value = S.abs.url || '';
// Never pre-fill the API key field for security — just show connection status
const statusEl = document.getElementById('abs-s-status');
if (statusEl) statusEl.textContent = S.abs.token ? '✅ Verbunden' : '';
if (S.abs.token) {
_setAbsStatusRow('connected', 'Verbunden · ' + (S.abs.url || ''));
} else {
_setAbsStatusRow('none', 'Nicht verbunden');
}
}
export function absToggleConnection() {
if (S.abs.token) absDisconnect(); else absConnectSettings();
}
export async function absConnectSettings() {
@@ -681,13 +711,11 @@ export async function absConnectSettings() {
_renderLibPicker(libs);
_showAbsNavItem(true);
toast('✅ Audiobookshelf verbunden');
const statusEl = document.getElementById('abs-s-status');
if (statusEl) statusEl.textContent = '✅ Verbunden';
_setAbsStatusRow('connected', 'Verbunden · ' + url);
} catch (e) {
S.abs.token = null;
toast(`❌ ABS Verbindung fehlgeschlagen: ${e.message}`);
} finally {
if (btn) { btn.disabled = false; btn.textContent = 'Verbinden'; }
_setAbsStatusRow('error', 'Fehler: ' + e.message);
}
}
@@ -722,6 +750,5 @@ export function absDisconnect() {
localStorage.removeItem('ns_abs');
_showAbsNavItem(false);
toast('Audiobookshelf getrennt');
const statusEl = document.getElementById('abs-s-status');
if (statusEl) statusEl.textContent = '';
_setAbsStatusRow('none', 'Nicht verbunden');
}
+2 -2
View File
@@ -23,7 +23,7 @@ import { loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDl
import { resolveYouTubeLink, executeYouTubeDownload } from './youtube.js';
import { loadSoundCloudImporter, resolveSoundCloudLink, clearSoundCloudPreview, scDlAll, scDlSingle, scDlTrack } from './soundcloud.js';
import {
absInitFromStorage, absOpenSettings, absConnectSettings, absSetLibrary, absDisconnect, absVerifyApiKey,
absInitFromStorage, absOpenSettings, absConnectSettings, absSetLibrary, absDisconnect, absVerifyApiKey, absToggleConnection,
absPlayItem, absTogglePlay, absSeek, absSkipSecs, absNextChapter, absPrevChapter,
absSetSpeed, absSleepIn, absOpenPlayer, absClosePlayer, absToggleChapters,
absToggleSpeedPicker, absToggleSleepPicker, absSeekToChapter, absProgDown, absProgMove,
@@ -334,7 +334,7 @@ Object.assign(window, {
absSetSpeed, absSleepIn, absOpenPlayer, absClosePlayer, absToggleChapters,
absToggleSpeedPicker, absToggleSleepPicker, absSeekToChapter,
absProgDown, absProgMove, absProgUp,
absOpenBook, absPlayChapter, absConnectSettings, absSetLibrary, absDisconnect, absToggleChapterTrack,
absOpenBook, absPlayChapter, absConnectSettings, absSetLibrary, absDisconnect, absToggleConnection, absToggleChapterTrack,
absOnSearch: (val) => {
clearTimeout(window._absSearchTimer);
window._absSearchTimer = setTimeout(() => {