From 2e02804b74081cce1493d5ca44d7491e68c8a294 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 17 Aug 2026 10:03:41 -0400 Subject: [PATCH] Fix: Enable manual Stash Match button and prompt for re-analyzing already matched torrents --- qbittorrent_performer_sorter.html | 45 ++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/qbittorrent_performer_sorter.html b/qbittorrent_performer_sorter.html index 815d89a..f856a4b 100644 --- a/qbittorrent_performer_sorter.html +++ b/qbittorrent_performer_sorter.html @@ -2900,10 +2900,32 @@ Return ONLY valid JSON matching: updateButtonStates(); } + if (btnQbStashLookup) { + btnQbStashLookup.addEventListener('click', async () => { + const selected = qbState.torrents.filter(t => qbState.selectedHashes.has(t.hash)); + if (selected.length === 0) { + showToast('Please select at least one torrent checkbox (or use Select All)', 'warning'); + return; + } + btnQbStashLookup.disabled = true; + btnQbStashLookup.textContent = '⚡ Matching with Stash...'; + try { + const matched = await matchItemsWithStash(selected, 'qb'); + showToast(`⚡ Stash matched ${matched} / ${selected.length} selected torrent(s)`, matched > 0 ? 'success' : 'info'); + } catch (err) { + showToast(`Stash matching error: ${err.message}`, 'error'); + } finally { + btnQbStashLookup.disabled = false; + btnQbStashLookup.textContent = '⚡ Stash Match (Selected)'; + updateButtonStates(); + } + }); + } + btnAnalyzeSelected.addEventListener('click', () => { const selected = qbState.torrents.filter(t => qbState.selectedHashes.has(t.hash)); if (selected.length === 0) { - showToast('Please select at least one torrent to analyze', 'error'); + showToast('Please select at least one torrent checkbox (or use Select All)', 'warning'); return; } runAnalysisOnTorrents(selected); @@ -2912,7 +2934,14 @@ Return ONLY valid JSON matching: btnAnalyzeAll.addEventListener('click', () => { const unanalyzed = qbState.torrents.filter(t => !t.analysis && t.moveStatus !== 'moved'); if (unanalyzed.length === 0) { - showToast('All torrents are already analyzed', 'info'); + const unMoved = qbState.torrents.filter(t => t.moveStatus !== 'moved'); + if (unMoved.length > 0) { + if (confirm(`All ${unMoved.length} torrent(s) have already been matched or analyzed.\n\nDo you want to force re-analyze all ${unMoved.length} torrent(s) with ${getProviderDisplayName()} AI?`)) { + runAnalysisOnTorrents(unMoved); + } + return; + } + showToast('All torrents are already moved', 'info'); return; } runAnalysisOnTorrents(unanalyzed); @@ -2990,6 +3019,7 @@ Return ONLY valid JSON matching: const hasSelection = qbState.selectedHashes.size > 0; const hasReadySelected = qbState.torrents.some(t => qbState.selectedHashes.has(t.hash) && t.targetPath && t.moveStatus === 'ready'); + if (btnQbStashLookup) btnQbStashLookup.disabled = !hasSelection || qbState.isAnalyzing; btnAnalyzeSelected.disabled = !hasSelection || qbState.isAnalyzing; btnAnalyzeAll.disabled = !hasTorrents || qbState.isAnalyzing; btnBatchRelocate.disabled = !hasReadySelected || qbState.isMoving; @@ -3605,7 +3635,7 @@ Return ONLY a valid JSON object with an array named "results": btnSmbAnalyzeSelected.addEventListener('click', () => { const selected = smbState.files.filter(f => smbState.selectedPaths.has(f.path)); if (selected.length === 0) { - showToast('Please select at least one file to analyze', 'error'); + showToast('Please select at least one video checkbox (or use Select All)', 'warning'); return; } runAnalysisOnSmbFiles(selected); @@ -3614,7 +3644,14 @@ Return ONLY a valid JSON object with an array named "results": btnSmbAnalyzeAll.addEventListener('click', () => { const unanalyzed = smbState.files.filter(f => !f.analysis && f.moveStatus !== 'moved'); if (unanalyzed.length === 0) { - showToast('All SMB files are already analyzed', 'info'); + const unMoved = smbState.files.filter(f => f.moveStatus !== 'moved'); + if (unMoved.length > 0) { + if (confirm(`All ${unMoved.length} SMB video(s) have already been matched or analyzed.\n\nDo you want to force re-analyze all ${unMoved.length} video(s) with ${getProviderDisplayName()} AI?`)) { + runAnalysisOnSmbFiles(unMoved); + } + return; + } + showToast('All SMB files are already moved', 'info'); return; } runAnalysisOnSmbFiles(unanalyzed);