Tab Scarica: ricerca diretta per titolo o "Artista - Titolo"
L'input URL ora accetta anche query libere: se non sembra un link
(http/https/spotify:/dominio noto), il testo viene parsato come
{artist, name} e scaricato via download_playlist con una traccia.
Riusa lo stesso flusso ytsearch1: gia in uso per le tracklist da file.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
8610f4d95c
commit
05a2a58ace
4 files changed
+48
-7
No files matched your search
+9
-2
@@ -75,15 +75,22 @@
|
||||
<div class="card">
|
||||
<div class="field">
|
||||
<label class="field-label">
|
||||
URL
|
||||
URL o titolo brano
|
||||
<span class="badge" id="urlListBadge" hidden></span>
|
||||
</label>
|
||||
<div class="row">
|
||||
<input type="text" id="urlInput" class="input pill" placeholder="Incolla qui un link Spotify, YouTube o SoundCloud…" />
|
||||
<input type="text" id="urlInput" class="input pill" placeholder="Link Spotify/YouTube… oppure Artista - Titolo · Titolo brano" />
|
||||
<button class="btn btn-ghost pill" id="loadListBtn">
|
||||
<span>📂</span> Carica lista
|
||||
</button>
|
||||
</div>
|
||||
<div class="hint">
|
||||
<span class="hint-ico">ⓘ</span>
|
||||
<div>
|
||||
Puoi incollare un <strong>link</strong> (Spotify, YouTube, SoundCloud…) oppure scrivere direttamente
|
||||
<strong>Artista - Titolo</strong> o solo il <strong>titolo del brano</strong>: l'app cerca il match migliore su YouTube e scarica in MP3.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
|
||||
+34
-2
@@ -27,6 +27,24 @@ function waitApi() {
|
||||
});
|
||||
}
|
||||
|
||||
// Riconosce se una stringa e un URL (incluso schema spotify:)
|
||||
function looksLikeUrl(s) {
|
||||
if (!s) return false;
|
||||
if (/^(https?|spotify):/i.test(s)) return true;
|
||||
if (s.includes("://")) return true;
|
||||
// Domini comuni anche senza http (es. "youtube.com/...")
|
||||
return /^(www\.)?(youtube\.com|youtu\.be|spotify\.com|soundcloud\.com|tiktok\.com|instagram\.com|facebook\.com|fb\.watch)\//i.test(s);
|
||||
}
|
||||
|
||||
// Trasforma una query libera in {name, artist}.
|
||||
// Formati riconosciuti: "Artista - Titolo" (anche con – o —) oppure solo "Titolo".
|
||||
function parseQueryToTrack(q) {
|
||||
const s = (q || "").trim();
|
||||
const m = s.match(/^(.+?)\s+[-–—]\s+(.+)$/);
|
||||
if (m) return { artist: m[1].trim(), name: m[2].trim() };
|
||||
return { artist: "", name: s };
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Bridge — eventi spinti dal backend
|
||||
// ============================================================
|
||||
@@ -340,11 +358,25 @@ $("#downloadBtn").addEventListener("click", async () => {
|
||||
if (!urls.length) {
|
||||
const single = $("#urlInput").value.trim();
|
||||
if (!single) {
|
||||
toast("Inserisci un URL o carica una lista", "error");
|
||||
toast("Inserisci un URL, un titolo o carica una lista", "error");
|
||||
bridgeHandlers["download:done"]();
|
||||
return;
|
||||
}
|
||||
urls = [single];
|
||||
if (looksLikeUrl(single)) {
|
||||
urls = [single];
|
||||
} else {
|
||||
const track = parseQueryToTrack(single);
|
||||
res = await window.pywebview.api.start_tracks_download({
|
||||
tracks: [track],
|
||||
output_dir: state.dlOutputDir,
|
||||
subfolder: "",
|
||||
});
|
||||
if (!res.ok) {
|
||||
toast(res.error || "Errore", "error");
|
||||
bridgeHandlers["download:done"]();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
res = await window.pywebview.api.start_download({
|
||||
urls,
|
||||
|
||||
Reference in new issue
Block a user