auto.js: 카드 패널 렌더러를 renderCutPanel()로 통합
onResult(자동 탭)과 ytMatch(구간 탭)에 각각 있던 검색창+컷별/⭐ 섹션+➕후보 렌더 블록이 두 갈래로 갈라져 있어, 곧 붙여넣기 탭까지 더해지면 한 곳만 고치는 실수가 나기 쉬웠다. 두 블록을 renderCutPanel(box,panelId,data,opts) 하나로 합쳐 배지·검색·선택 상한 로직을 한 곳에 모았다. 화면 문구는 완전히 동일하게 보존했다 — 특히 ⭐ 폴백 라벨은 onResult가 "이 구간을", ytMatch가 "구간을"로 이미 서로 달랐기에, unit 값에 따라 원문 그대로 재현하도록 분기했다(무작정 unit을 문자열에 꽂지 않음). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aab2a3199b
commit
22a9758e74
@ -137,6 +137,48 @@ function clearSearch(hlId){
|
|||||||
const bar=box&&box.querySelector(".ccsearch");
|
const bar=box&&box.querySelector(".ccsearch");
|
||||||
if(bar&&bar._clear) bar._clear();
|
if(bar&&bar._clear) bar._clear();
|
||||||
}
|
}
|
||||||
|
/* ── 카드 패널 렌더 — 자동/구간/붙여넣기 세 탭이 공유한다.
|
||||||
|
갈라 두면 한 곳만 고치는 실수가 난다(배지·검색·선택 상한이 전부 여기 모여 있다). ── */
|
||||||
|
function renderCutPanel(box,panelId,data,opts){
|
||||||
|
const unit=(opts&&opts.unit)||"컷";
|
||||||
|
const WHY={ts:"⭐",ai:"🤖",like:"➕"};
|
||||||
|
box.appendChild(searchBar(panelId)); // 카드 섹션들 위 — cardSection 보다 먼저 만들어야 SECS 초기화됨
|
||||||
|
const cand=(data.candidates||[]).filter(i=>byIdx[i]!==undefined);
|
||||||
|
if(data.cuts){
|
||||||
|
/* 컷별 추천 — 컷마다 두 섹션. 독립 ➕ 섹션을 두지 않는 이유: 거기서 고른 카드는
|
||||||
|
컷 소속(ci)이 없어 빌드 때 갈 곳이 없다. quota 미달분을 ➕ 에서 채우는 게 주 워크플로다.
|
||||||
|
rest(추천 뒤 '나머지')는 그 컷 시간대를 언급한 댓글만 — 안 그러면 컷마다 전체가 중복된다. */
|
||||||
|
for(const cu of data.cuts){
|
||||||
|
const rec=(cu.picks||[]).map(p=>p.idx).filter(i=>byIdx[i]!==undefined);
|
||||||
|
const why=(cu.picks||[]).map(p=>WHY[p.why]||"").join("");
|
||||||
|
const cs=(data.cutRanges||[])[cu.i]||{start:0,end:-1};
|
||||||
|
const rest=(data.matched||[]).filter(i=>
|
||||||
|
byIdx[i]!==undefined&&!rec.includes(i)&&
|
||||||
|
(byIdx[i].times||[]).some(t=>t>=cs.start&&t<=cs.end));
|
||||||
|
box.appendChild(cardSection(
|
||||||
|
unit+" "+(cu.i+1)+" · "+cu.sec+"초 · 카드 "+cu.quota+"장"+
|
||||||
|
(cu.bottom?" — "+cu.bottom:"")+(why?" "+why:""),
|
||||||
|
rec.concat(rest),panelId,Math.max(CARD_PAGE,rec.length),cu.i));
|
||||||
|
// 부족분 채우기 — 컷마다 반복되므로 처음엔 조금만 그리고 나머지는 더보기로
|
||||||
|
if(cand.length)
|
||||||
|
box.appendChild(cardSection(
|
||||||
|
"↳ 좋아요 상위에서 채우기 "+cand.length+"장 (이 컷에 넣기)",
|
||||||
|
cand,panelId,CUT_FILL_PAGE,cu.i));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// 폴백 — cuts 정보가 없으면(구간 탭·구정보 없음) 예전 화면 그대로: ⭐ + 독립 ➕
|
||||||
|
// ⚠ 이 ⭐ 문구는 예전부터 "이 구간을"로 고정돼 있었다(unit="컷"이어도) — 화면 불변 원칙상 유지
|
||||||
|
const m=(data.matched||[]).filter(i=>byIdx[i]!==undefined);
|
||||||
|
box.appendChild(cardSection(
|
||||||
|
"⭐ "+(unit==="컷"?"이 구간":unit)+"을 언급한 댓글 "+m.length+"장 (좋아요순, 자동 선택)",
|
||||||
|
m,panelId,Math.max(CARD_PAGE,(sel[panelId]||[]).length)));
|
||||||
|
if(cand.length){
|
||||||
|
box.appendChild(cardSection(
|
||||||
|
"➕ 좋아요 상위 후보 "+cand.length+"장 (부족분 클릭)",
|
||||||
|
cand,panelId,CARD_PAGE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* ── 컷별 선택 ── 카드는 '어느 컷 소속'인지가 배치를 정한다.
|
/* ── 컷별 선택 ── 카드는 '어느 컷 소속'인지가 배치를 정한다.
|
||||||
selCut[hlId][idx] = 컷 인덱스. sel[hlId] 는 항상 컷 순서로 정렬해 둔다
|
selCut[hlId][idx] = 컷 인덱스. sel[hlId] 는 항상 컷 순서로 정렬해 둔다
|
||||||
(업로드 순서 = 배치 순서라서). */
|
(업로드 순서 = 배치 순서라서). */
|
||||||
@ -537,47 +579,9 @@ function onResult(ev){
|
|||||||
box.dataset.titles=JSON.stringify(opts);
|
box.dataset.titles=JSON.stringify(opts);
|
||||||
// 영상 편집안(컷 목록·JSON) — 선택 요약 바 위에, 기본 접힘
|
// 영상 편집안(컷 목록·JSON) — 선택 요약 바 위에, 기본 접힘
|
||||||
box.insertBefore(cutsSection(hl),$("#hlsel-"+hl.id));
|
box.insertBefore(cutsSection(hl),$("#hlsel-"+hl.id));
|
||||||
box.appendChild(searchBar(hl.id)); // 카드 섹션들 위 — cardSection 보다 먼저 만들어야 SECS 초기화됨
|
renderCutPanel(box,hl.id,
|
||||||
const WHY={ts:"⭐",ai:"🤖",like:"➕"};
|
{cuts:hl.cuts,matched:hl.matched,candidates:hl.candidates,
|
||||||
const cand=(hl.candidates||[]).filter(i=>byIdx[i]!==undefined);
|
cutRanges:hl.paste.cuts},{unit:"컷"});
|
||||||
if(hl.cuts){
|
|
||||||
/* 컷별 추천 — 컷마다 두 섹션. 독립 ➕ 섹션을 두지 않는 이유:
|
|
||||||
거기서 고른 카드는 컷 소속(ci)이 없어 빌드 때 갈 곳이 없다. 그런데 AI 프롬프트가
|
|
||||||
"억지로 채우지 마라"라고 지시하므로 quota 미달이 기본이고, 미달분을 ➕ 에서
|
|
||||||
채우는 게 주 워크플로다. _cards_by_cut 은 컷 '뒤'가 아니라 컷 '안에' 균등 분할하니
|
|
||||||
소속 없는 카드를 한 컷에 몰면 4초 컷에 5장이 들어가 0.8초씩 번쩍인다. */
|
|
||||||
for(const cu of hl.cuts){
|
|
||||||
const rec=(cu.picks||[]).map(p=>p.idx).filter(i=>byIdx[i]!==undefined);
|
|
||||||
const why=(cu.picks||[]).map(p=>WHY[p.why]||"").join("");
|
|
||||||
/* 추천 뒤에 붙이는 '나머지'는 **그 컷 시간대를 언급한 댓글만**.
|
|
||||||
hl.matched 전체를 컷마다 복제하면 컷 12개 × 30장 = 360장씩 부풀고,
|
|
||||||
같은 댓글이 여러 컷 섹션에 중복돼 한쪽을 고르면 쌍둥이까지 하이라이트된다. */
|
|
||||||
const cs=(hl.paste.cuts||[])[cu.i]||{start:0,end:-1};
|
|
||||||
const rest=(hl.matched||[]).filter(i=>
|
|
||||||
byIdx[i]!==undefined&&!rec.includes(i)&&
|
|
||||||
(byIdx[i].times||[]).some(t=>t>=cs.start&&t<=cs.end));
|
|
||||||
const label="컷 "+(cu.i+1)+" · "+cu.sec+"초 · 카드 "+cu.quota+"장"+
|
|
||||||
(cu.bottom?" — "+cu.bottom:"")+(why?" "+why:"");
|
|
||||||
box.appendChild(cardSection(label,rec.concat(rest),hl.id,
|
|
||||||
Math.max(CARD_PAGE,rec.length),cu.i));
|
|
||||||
// 부족분 채우기 — 컷마다 반복되므로 처음엔 조금만 그리고 나머지는 더보기로
|
|
||||||
if(cand.length)
|
|
||||||
box.appendChild(cardSection(
|
|
||||||
"↳ 좋아요 상위에서 채우기 "+cand.length+"장 (이 컷에 넣기)",
|
|
||||||
cand,hl.id,CUT_FILL_PAGE,cu.i));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
// 폴백 — hl.cuts 가 없으면(컷 정보 없음) 예전 화면 그대로: ⭐ + 독립 ➕
|
|
||||||
const m=(hl.matched||[]).filter(i=>byIdx[i]!==undefined);
|
|
||||||
box.appendChild(cardSection(
|
|
||||||
"⭐ 이 구간을 언급한 댓글 "+m.length+"장 (좋아요순, 자동 선택)",
|
|
||||||
m,hl.id,Math.max(CARD_PAGE,sel[hl.id].length)));
|
|
||||||
if(cand.length){
|
|
||||||
box.appendChild(cardSection(
|
|
||||||
"➕ 좋아요 상위 후보 "+cand.length+"장 (부족분 클릭)",
|
|
||||||
cand,hl.id,CARD_PAGE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R.appendChild(box);
|
R.appendChild(box);
|
||||||
refreshSel(hl.id);
|
refreshSel(hl.id);
|
||||||
}
|
}
|
||||||
@ -765,15 +769,8 @@ async function ytMatch(){
|
|||||||
'<input type="checkbox" id="ytccFixed" checked style="accent-color:var(--accent);width:14px;height:14px;">'+
|
'<input type="checkbox" id="ytccFixed" checked style="accent-color:var(--accent);width:14px;height:14px;">'+
|
||||||
' 카드 3초 고정 — 모자라도 늘리지 않고 뒤는 비움 (부분삭제 편집용)</label>'+
|
' 카드 3초 고정 — 모자라도 늘리지 않고 뒤는 비움 (부분삭제 편집용)</label>'+
|
||||||
'<div class="selbar" id="hlsel-yt"></div>';
|
'<div class="selbar" id="hlsel-yt"></div>';
|
||||||
box.appendChild(searchBar("yt"));
|
renderCutPanel(box,"yt",
|
||||||
box.appendChild(cardSection(
|
{matched:matched,candidates:cand},{unit:"구간"});
|
||||||
"⭐ 구간을 언급한 댓글 "+matched.length+"장 (좋아요순, 자동 선택)",
|
|
||||||
matched,"yt",Math.max(CARD_PAGE,sel["yt"].length)));
|
|
||||||
if(cand.length){
|
|
||||||
box.appendChild(cardSection(
|
|
||||||
"➕ 좋아요 상위 후보 "+cand.length+"장 (부족분 클릭)",
|
|
||||||
cand,"yt",CARD_PAGE));
|
|
||||||
}
|
|
||||||
area.appendChild(box);
|
area.appendChild(box);
|
||||||
refreshSel("yt");
|
refreshSel("yt");
|
||||||
$("#ytccNote").textContent="선택한 카드는 편집 시작 때 자동으로 들어갑니다(폴더 지정보다 우선). "
|
$("#ytccNote").textContent="선택한 카드는 편집 시작 때 자동으로 들어갑니다(폴더 지정보다 우선). "
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user