feat(web): merge Song Importer into Global Suche (one unified field)

The importer no longer has its own sidebar/bottom-nav entry. The Global
Suche field now handles both jobs: plain text runs the Deezer search;
a pasted Spotify/SoundCloud/YouTube link switches into importer mode
(badge + "Importieren" button + preview), matching the Android app and
tidying the left nav.

- New onGlobalInput/tryImporterResolve; importer DOM moved into
  page-discover; old page-spotify-importer removed; routing cleaned up.
- Existing resolvers unchanged (still read the mirrored importer-link-input).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-08-21 17:59:44 +02:00
1 parent 0a6c81b4a1
commit 934253a036
4 files changed
+110 -81

No files matched your search

+2 -3
View File
@@ -62,12 +62,12 @@ export function navigate(page, data=null) {
closeHeaderSearch();
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-item,.bnav-item').forEach(n => n.classList.remove('active','active-blue'));
const cls = ['discover','new-releases','recommendations','spotify-importer'].includes(page) ? 'active-blue' : 'active';
const cls = ['discover','new-releases','recommendations'].includes(page) ? 'active-blue' : 'active';
document.querySelectorAll(`[data-page="${page}"]`).forEach(el => el.classList.add(cls));
const pageEl = document.getElementById(`page-${page}`);
if(pageEl) { pageEl.classList.add('active'); document.getElementById('main-content').scrollTop = 0; }
closeSidebar();
if(['discover','new-releases','recommendations','random','spotify-importer'].includes(page)) switchNavMode('discover');
if(['discover','new-releases','recommendations','random'].includes(page)) switchNavMode('discover');
else if(['home','artists','albums','starred','playlists'].includes(page)) switchNavMode('library');
if(page==='home') loadHomeData(!S._navJumping); // explicit Home click refreshes; back/forward keeps state
@@ -85,7 +85,6 @@ export function navigate(page, data=null) {
if(page==='playlists') loadPlaylists();
if(page==='playlist-detail' && data) loadPlaylistDetail(data);
if(page==='recommendations') loadRecommendations();
if(page==='spotify-importer') { loadSpotifyImporter(); loadSoundCloudImporter(); }
if(page==='audiobooks') {
import('./abs.js').then(m => {
if (S.abs.currentLibraryId) m.loadAbsBooks(S.abs.currentLibraryId);
+44
View File
@@ -47,6 +47,50 @@ export function onImporterInput(val) {
}
}
// ─── UNIFIED GLOBAL-SUCHE FIELD ───
// One field on the Global-Suche page handles both jobs: a pasted Spotify/SoundCloud/YouTube link
// switches into the importer flow; any other text runs the Deezer library search. This replaces the
// separate "Song Importer" sidebar entry (the importer now lives inside Global Suche).
const _IMPORT_LINK_RE = /^https?:\/\//i;
const _IMPORT_HOST_RE = /(?:spotify\.com|soundcloud\.com|youtube\.com|youtu\.be)/i;
function _isImportLink(v) { return _IMPORT_LINK_RE.test(v) || _IMPORT_HOST_RE.test(v); }
export function onGlobalInput(val) {
const v = (val || '').trim();
const area = document.getElementById('importer-area');
const results = document.getElementById('global-search-results');
const badge = document.getElementById('importer-badge');
const btn = document.getElementById('importer-btn');
if (_isImportLink(v)) {
// Link → importer mode
if (results) results.style.display = 'none';
if (area) area.style.display = '';
if (badge) badge.style.display = '';
if (btn) btn.style.display = '';
const hidden = document.getElementById('importer-link-input');
if (hidden) hidden.value = v; // mirror so resolveImporterLink() reads it
onImporterInput(v); // badge styling + clear stale previews
const hint = document.getElementById('importer-hint');
if (hint) hint.style.display = ''; // keep the platform hint as a header until a preview loads
} else {
// Text → Deezer search
if (area) area.style.display = 'none';
if (badge) badge.style.display = 'none';
if (btn) btn.style.display = 'none';
if (results) results.style.display = '';
window.onGlobalSearch(v);
}
}
// Enter in the unified field: resolve the link if it is one (search is already live via oninput).
export function tryImporterResolve() {
const v = (document.getElementById('global-search-input')?.value || '').trim();
if (!_isImportLink(v)) return;
const hidden = document.getElementById('importer-link-input');
if (hidden) hidden.value = v;
resolveImporterLink();
}
export async function resolveImporterLink() {
const url = document.getElementById('importer-link-input')?.value.trim();
if (!url) return;