이름 변경 실행 - 전체 이미지 / 선택된 이미지 두 상황별로 다르게 작동하도록 수정
This commit is contained in:
@@ -89,6 +89,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="rename-conflict-modal" class="modal-overlay" style="display:none;">
|
||||
<div class="modal-box">
|
||||
<p class="modal-msg">변경할 이름의 파일이 이미 존재합니다.</p>
|
||||
<ul id="rename-conflict-list" class="modal-conflict-list"></ul>
|
||||
<div class="modal-actions">
|
||||
<button id="rename-conflict-close" class="btn btn-ghost">닫기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="move-error-modal" class="modal-overlay" style="display:none;">
|
||||
<div class="modal-box">
|
||||
<p class="modal-msg">새로운 이름의 파일도 존재합니다.</p>
|
||||
|
||||
@@ -36,7 +36,10 @@ const moveDigitsInput = document.getElementById('move-digits');
|
||||
const moveCancelBtn = document.getElementById('move-cancel');
|
||||
const moveConfirmBtn = document.getElementById('move-confirm');
|
||||
const moveErrorModal = document.getElementById('move-error-modal');
|
||||
const moveErrorCloseBtn = document.getElementById('move-error-close');
|
||||
const moveErrorCloseBtn = document.getElementById('move-error-close');
|
||||
const renameConflictModal = document.getElementById('rename-conflict-modal');
|
||||
const renameConflictCloseBtn = document.getElementById('rename-conflict-close');
|
||||
const renameConflictList = document.getElementById('rename-conflict-list');
|
||||
|
||||
// ── 핸들러 초기화 ─────────────────────────────────
|
||||
const callbacks = {
|
||||
@@ -248,18 +251,46 @@ function updatePreview() {
|
||||
}
|
||||
|
||||
// ── 이름 변경 ────────────────────────────────────
|
||||
renameConflictCloseBtn.addEventListener('click', () => {
|
||||
renameConflictModal.style.display = 'none';
|
||||
});
|
||||
|
||||
async function doRename() {
|
||||
if (!state.files.length || !state.currentFolder) return;
|
||||
const prefix = inputPrefix.value.trim() || 'photo';
|
||||
const digits = Math.max(1, Math.min(6, parseInt(inputDigits.value) || 3));
|
||||
|
||||
const examples = state.files.slice(0, 3).map((f, i) => {
|
||||
const selectedArr = [...state.selectedIdxs].sort((a, b) => a - b);
|
||||
const filesToRename = selectedArr.length > 0
|
||||
? selectedArr.map(i => state.files[i]).filter(Boolean)
|
||||
: state.files;
|
||||
|
||||
if (!filesToRename.length) return;
|
||||
|
||||
// 선택된 파일이 있으면 변경될 이름이 미선택 파일 이름과 충돌하는지 확인
|
||||
if (selectedArr.length > 0) {
|
||||
const unselectedNames = new Set(
|
||||
state.files.filter((_, i) => !state.selectedIdxs.has(i)).map(f => f.name)
|
||||
);
|
||||
const newNames = filesToRename.map((f, i) => {
|
||||
const ext = f.name.split('.').pop().toLowerCase();
|
||||
return `${prefix}_${String(i + 1).padStart(digits, '0')}.${ext}`;
|
||||
});
|
||||
const conflicting = newNames.filter(n => unselectedNames.has(n));
|
||||
if (conflicting.length) {
|
||||
renameConflictList.innerHTML = conflicting.map(n => `<li>${n}</li>`).join('');
|
||||
renameConflictModal.style.display = 'flex';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const examples = filesToRename.slice(0, 3).map((f, i) => {
|
||||
const ext = f.name.split('.').pop().toLowerCase();
|
||||
return `${f.name} → ${prefix}_${String(i + 1).padStart(digits, '0')}.${ext}`;
|
||||
}).join('\n');
|
||||
const more = state.files.length > 3 ? `\n... 외 ${state.files.length - 3}개` : '';
|
||||
const more = filesToRename.length > 3 ? `\n... 외 ${filesToRename.length - 3}개` : '';
|
||||
|
||||
if (!confirm(`📂 ${state.files.length}개 파일을 이름 변경합니다:\n\n${examples}${more}\n\n계속하시겠습니까?`)) return;
|
||||
if (!confirm(`📂 ${filesToRename.length}개 파일을 이름 변경합니다:\n\n${examples}${more}\n\n계속하시겠습니까?`)) return;
|
||||
|
||||
showLoading('파일 이름 변경 중...');
|
||||
setStatus('이름 변경 중...', false);
|
||||
@@ -267,7 +298,7 @@ async function doRename() {
|
||||
try {
|
||||
const result = await window.api.renameFiles({
|
||||
folderPath: state.currentFolder,
|
||||
files: state.files,
|
||||
files: filesToRename,
|
||||
prefix,
|
||||
digits,
|
||||
});
|
||||
|
||||
@@ -517,6 +517,17 @@ footer span { font-size: 11px; color: var(--muted); }
|
||||
}
|
||||
.modal-fields input[type="number"] { width: 70px; text-align: center; }
|
||||
.modal-fields input:focus { border-color: var(--accent); }
|
||||
.modal-conflict-list {
|
||||
list-style: none;
|
||||
display: flex; flex-direction: column; gap: 4px;
|
||||
max-height: 160px; overflow-y: auto;
|
||||
background: var(--card); border: 1px solid var(--border);
|
||||
border-radius: 8px; padding: 8px 12px;
|
||||
}
|
||||
.modal-conflict-list li {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px; color: var(--warning);
|
||||
}
|
||||
.modal-actions {
|
||||
display: flex; justify-content: flex-end; gap: 10px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user