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:
1 parent
0a6c81b4a1
commit
934253a036
4 files changed
+110
-81
No files matched your search
+2
-2
@@ -24,7 +24,7 @@ import {
|
||||
plReorderEnter, plReorderSave, plReorderCancel, toggleAllGenres,
|
||||
} from './views/views.js';
|
||||
import { loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
|
||||
onImporterInput, resolveImporterLink } from './views/spotify.js';
|
||||
onImporterInput, resolveImporterLink, onGlobalInput, tryImporterResolve } from './views/spotify.js';
|
||||
import { resolveYouTubeLink, executeYouTubeDownload } from './views/youtube.js';
|
||||
import { loadSoundCloudImporter, resolveSoundCloudLink, clearSoundCloudPreview, scDlAll, scDlSingle, scDlTrack } from './views/soundcloud.js';
|
||||
import {
|
||||
@@ -343,7 +343,7 @@ Object.assign(window, {
|
||||
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
|
||||
plReorderEnter, plReorderSave, plReorderCancel, toggleAllGenres,
|
||||
loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
|
||||
onImporterInput, resolveImporterLink,
|
||||
onImporterInput, resolveImporterLink, onGlobalInput, tryImporterResolve,
|
||||
loadSoundCloudImporter, resolveSoundCloudLink, clearSoundCloudPreview, scDlAll, scDlSingle, scDlTrack,
|
||||
executeSpotifyDownload, resolveYouTubeLink, executeYouTubeDownload,
|
||||
openPlModal, closePlModal, addSongsToPlaylist, createAndAddPlaylist, createPlaylistPrompt,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user