From a77a40695c4b9615ff644a8ca35220aecb4fbcf0 Mon Sep 17 00:00:00 2001 From: "DESKTOP-KSVGT20\\shkim" Date: Sat, 2 May 2026 02:32:22 +0900 Subject: [PATCH] Restore MP3 auto and show visible Suno tracks --- chatgpt-suno-tampermonkey.user.js | 56 ++++++++++++++++++------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/chatgpt-suno-tampermonkey.user.js b/chatgpt-suno-tampermonkey.user.js index bde8848..f5a40d9 100644 --- a/chatgpt-suno-tampermonkey.user.js +++ b/chatgpt-suno-tampermonkey.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name ChatGPT to Suno Prompt Copier // @namespace local.suno-helper -// @version 0.10.1 +// @version 0.10.3 // @description Copy structured ChatGPT song prompt versions into Suno fields. // @author local // @match https://chatgpt.com/* @@ -30,7 +30,7 @@ (function () { "use strict"; - const SCRIPT_VERSION = "0.10.1"; + const SCRIPT_VERSION = "0.10.3"; const STORAGE_KEY = "chatgptSunoPromptSlots"; const SLOT_COUNT = 2; const isChatGPT = location.hostname.includes("chatgpt.com") || location.hostname.includes("chat.openai.com"); @@ -1878,11 +1878,11 @@
- +
- +
@@ -1910,12 +1910,14 @@ const slotSelect = body.querySelector("[data-cgs-slot]"); const trackList = body.querySelector("[data-cgs-track-list]"); let libraryTracks = []; + let visibleTrackIds = new Set(); const libraryTrackMap = new Map(); const selectedTrackIds = new Set(); let lastSelectedIndex = -1; let autoScanTimer = 0; - const getSelectedTracks = () => libraryTracks.filter((track) => selectedTrackIds.has(track.id)); + const getVisibleTracks = () => libraryTracks.filter((track) => visibleTrackIds.has(track.id)); + const getSelectedTracks = () => getVisibleTracks().filter((track) => selectedTrackIds.has(track.id)); const mergeLibraryTracks = (tracks) => { for (const track of tracks) { if (!track.id) continue; @@ -1929,24 +1931,25 @@ }; const renderLibraryTrackList = () => { try { + const visibleTracks = getVisibleTracks(); for (const id of [...selectedTrackIds]) { - if (!libraryTrackMap.has(id)) selectedTrackIds.delete(id); + if (!visibleTrackIds.has(id)) selectedTrackIds.delete(id); } const selectedCount = selectedTrackIds.size; - selectionSummary.textContent = libraryTracks.length - ? `누적 ${libraryTracks.length}곡 / 선택 ${selectedCount}곡` - : "누적된 곡 없음. 스크롤하면서 곡 감지를 눌러줘."; + selectionSummary.textContent = visibleTracks.length + ? `현재 화면 ${visibleTracks.length}곡 / 선택 ${selectedCount}곡 / 누적 ${libraryTracks.length}곡` + : `현재 화면 감지 없음 / 누적 ${libraryTracks.length}곡`; const nodes = []; - if (!libraryTracks.length) { + if (!visibleTracks.length) { const empty = document.createElement("div"); empty.className = "cgs-track-item"; - empty.innerHTML = `
감지된 곡 없음
`; + empty.innerHTML = `
현재 화면에 감지된 곡 없음
`; trackList.replaceChildren(empty); return; } - libraryTracks.forEach((track, index) => { + visibleTracks.forEach((track, index) => { const row = document.createElement("div"); row.className = `cgs-track-item ${selectedTrackIds.has(track.id) ? "cgs-selected" : ""}`; row.dataset.cgsTrackIndex = String(index); @@ -1984,15 +1987,17 @@ }; const setSelectedRange = (from, to) => { const start = Math.max(0, Math.min(from, to)); - const end = Math.min(libraryTracks.length - 1, Math.max(from, to)); + const visibleTracks = getVisibleTracks(); + const end = Math.min(visibleTracks.length - 1, Math.max(from, to)); for (let index = start; index <= end; index += 1) { - if (libraryTracks[index]?.id) selectedTrackIds.add(libraryTracks[index].id); + if (visibleTracks[index]?.id) selectedTrackIds.add(visibleTracks[index].id); } }; const scanAndMergeVisibleTracks = () => { const scannedTracks = scanSunoLibraryTracks(); const before = libraryTracks.length; mergeLibraryTracks(scannedTracks); + visibleTrackIds = new Set(scannedTracks.map((track) => track.id).filter(Boolean)); renderLibraryTrackList(); updateSummary(); return { scannedTracks, added: libraryTracks.length - before }; @@ -2062,7 +2067,8 @@ const item = event.target.closest("[data-cgs-track-index]"); if (!item) return; const index = Number(item.getAttribute("data-cgs-track-index")); - const track = libraryTracks[index]; + const visibleTracks = getVisibleTracks(); + const track = visibleTracks[index]; if (!track?.id) return; if (event.shiftKey && lastSelectedIndex >= 0) { setSelectedRange(lastSelectedIndex, index); @@ -2085,7 +2091,7 @@ renderLibraryTrackList(); } updateSummary(); - const track = getSelectedTracks()[0] || libraryTracks[0]; + const track = getSelectedTracks()[0] || getVisibleTracks()[0]; if (!track) { setStatus(body, "선택할 감지 곡이 없어. 곡 감지를 먼저 눌러줘."); return; @@ -2099,7 +2105,7 @@ }; body.querySelector("[data-cgs-process-one-mp3]").addEventListener("click", async () => { - await registerSelectedManualDownloads("mp3", { one: true }); + await processSelectedTrack("mp3"); }); body.querySelector("[data-cgs-process-one-wav]").addEventListener("click", async () => { @@ -2107,7 +2113,7 @@ }); body.querySelector("[data-cgs-process-selected-mp3]").addEventListener("click", async () => { - await registerSelectedManualDownloads("mp3"); + await processSelectedTracks("mp3"); }); body.querySelector("[data-cgs-process-selected-wav]").addEventListener("click", async () => { @@ -2115,7 +2121,7 @@ }); const registerSelectedManualDownloads = async (format, options = {}) => { - if (!libraryTracks.length) { + if (!getVisibleTracks().length) { mergeLibraryTracks(scanSunoLibraryTracks()); renderLibraryTrackList(); } @@ -2132,7 +2138,7 @@ }; const clickSelectedSunoUiDownloads = async (format, options = {}) => { - if (!libraryTracks.length) { + if (!getVisibleTracks().length) { mergeLibraryTracks(scanSunoLibraryTracks()); renderLibraryTrackList(); } @@ -2165,20 +2171,24 @@ }); const processLibraryTracks = async (format) => { - if (!libraryTracks.length) { + if (!getVisibleTracks().length) { mergeLibraryTracks(scanSunoLibraryTracks()); renderLibraryTrackList(); } updateSummary(); try { - await uploadTracksToCompanion(libraryTracks, body, format); + if (format === "wav") { + await expectManualDownloads(libraryTracks, body, "wav"); + } else { + await uploadTracksToCompanion(libraryTracks, body, format); + } } catch (error) { setStatus(body, `${format.toUpperCase()} 일괄 처리 실패: ${error.message || error}`); } }; const processSelectedTracks = async (format) => { - if (!libraryTracks.length) { + if (!getVisibleTracks().length) { mergeLibraryTracks(scanSunoLibraryTracks()); renderLibraryTrackList(); }