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);