목록 페이지: n화 이후 / 범위 다운로드 메뉴 추가

- getEpisodesFromList() 공통 헬퍼로 에피소드 추출 로직 분리
- startQueue() 공통 헬퍼로 큐 저장 + 이동 로직 분리
- downloadAfterEpisode(): prompt로 시작 번호 입력받아 필터링
- downloadRangeEpisodes(): prompt로 범위 입력받아 필터링
- 필터링된 결과는 번호 오름차순 정렬 후 다운로드
This commit is contained in:
user01
2026-06-14 16:36:22 +09:00
parent c6bc10fbeb
commit b8ce964510

View File

@@ -72,6 +72,8 @@
const { isListPage, isEpisodePage } = getListPageInfo();
if (isListPage) {
menuCmdIds.push(GM_registerMenuCommand('[목록] 전체 에피소드 다운로드', () => downloadAllEpisodes()));
menuCmdIds.push(GM_registerMenuCommand('[목록] n화 이후 다운로드', () => downloadAfterEpisode()));
menuCmdIds.push(GM_registerMenuCommand('[목록] 범위 다운로드', () => downloadRangeEpisodes()));
} else if (isEpisodePage) {
menuCmdIds.push(GM_registerMenuCommand('현재 에피소드 다운로드', () => downloadCurrentEpisode()));
}
@@ -347,12 +349,10 @@
}
}
async function downloadAllEpisodes() {
log('목록 페이지 처리 시작');
// 목록 페이지에서 에피소드 목록 추출
const getEpisodesFromList = () => {
const episodeList = document.querySelector('ul.ep-list-v2');
if (!episodeList) { alert('에피소드 목록을 찾을 수 없습니다.'); return; }
if (!episodeList) return null;
const episodes = [];
episodeList.querySelectorAll('li.ep-row-v2').forEach((li, index) => {
const link = li.querySelector('a.ep-row-v2-link');
@@ -369,18 +369,73 @@
});
}
});
return episodes.length > 0 ? episodes : null;
};
if (episodes.length === 0) { alert('에피소드 링크를 추출할 수 없습니다.'); return; }
const seriesName = getSeriesName();
// 큐 저장 후 첫 화로 이동
const startQueue = (episodes, seriesName) => {
log(`${episodes.length}개 에피소드를 큐에 저장, 첫 화로 이동합니다...`);
// 큐 저장 후 첫 번째 에피소드로 이동
sessionStorage.setItem(QUEUE_KEY, JSON.stringify(episodes));
sessionStorage.setItem(SERIES_KEY, seriesName);
sessionStorage.setItem(IDX_KEY, '0');
sessionStorage.setItem(LIST_KEY, window.location.href);
window.location.href = episodes[0].url;
};
async function downloadAllEpisodes() {
log('목록 페이지 처리 시작');
const episodes = getEpisodesFromList();
if (!episodes) { alert('에피소드 목록을 찾을 수 없습니다.'); return; }
const seriesName = getSeriesName();
startQueue(episodes, seriesName);
}
// n화 이후 다운로드
async function downloadAfterEpisode() {
const episodes = getEpisodesFromList();
if (!episodes) { alert('에피소드 목록을 찾을 수 없습니다.'); return; }
const input = prompt('어느 에피소드부터 다운로드할까요?\n(번호 입력, 예: 50)');
if (!input) return;
const threshold = parseFloat(input.trim());
if (isNaN(threshold)) { alert('올바른 숫자를 입력하세요.'); return; }
const filtered = episodes
.filter(ep => parseFloat(ep.number) >= threshold)
.sort((a, b) => parseFloat(a.number) - parseFloat(b.number));
if (filtered.length === 0) { alert('조건에 맞는 에피소드가 없습니다.'); return; }
const seriesName = getSeriesName();
startQueue(filtered, seriesName);
}
// 범위 다운로드
async function downloadRangeEpisodes() {
const episodes = getEpisodesFromList();
if (!episodes) { alert('에피소드 목록을 찾을 수 없습니다.'); return; }
const input = prompt('범위를 입력하세요.\n(예: 30-50 또는 50-끝)');
if (!input) return;
const match = input.trim().match(/^(\d+(?:\.\d+)?)\s*-\s*(?:(\d+(?:\.\d+)?)|(끝|end))?$/);
if (!match) { alert('올바른 형식이 아닙니다. 예: 30-50'); return; }
const start = parseFloat(match[1]);
const end = match[2] !== undefined ? parseFloat(match[2]) : Infinity;
if (isNaN(start)) { alert('올바른 숫자를 입력하세요.'); return; }
const filtered = episodes
.filter(ep => {
const num = parseFloat(ep.number);
return num >= start && num <= end;
})
.sort((a, b) => parseFloat(a.number) - parseFloat(b.number));
if (filtered.length === 0) { alert('조건에 맞는 에피소드가 없습니다.'); return; }
const seriesName = getSeriesName();
startQueue(filtered, seriesName);
}
// 자동 큐 처리: sessionStorage에 큐가 있으면 현재 화면을 다운로드 후 다음으로 이동