diff --git a/index.html b/index.html index 568f5b2..c836bea 100644 --- a/index.html +++ b/index.html @@ -637,11 +637,16 @@ -
- - +
+
+
Audiobookshelf Status
+
Nicht verbunden
+
+
+ + +
-

diff --git a/src/abs.js b/src/abs.js index bef7f40..62fbaa4 100644 --- a/src/abs.js +++ b/src/abs.js @@ -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'); } diff --git a/src/main.js b/src/main.js index 1500264..20e816b 100644 --- a/src/main.js +++ b/src/main.js @@ -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(() => {