팝업창 제목 스타일 적용, 단축키 추가
This commit is contained in:
@@ -2,17 +2,16 @@ import { state } from './state.js';
|
|||||||
import { setStatus, showToast } from './ui.js';
|
import { setStatus, showToast } from './ui.js';
|
||||||
import { renderGrid, showEmptyGrid } from './grid.js';
|
import { renderGrid, showEmptyGrid } from './grid.js';
|
||||||
import * as history from './history.js';
|
import * as history from './history.js';
|
||||||
|
import { openModal, closeModal } from './modal.js';
|
||||||
|
|
||||||
const deleteModal = document.getElementById('delete-modal');
|
const deleteModal = document.getElementById('delete-modal');
|
||||||
const deleteFileList = document.getElementById('delete-file-list');
|
const deleteFileList = document.getElementById('delete-file-list');
|
||||||
const deleteCancelBtn = document.getElementById('delete-cancel');
|
|
||||||
const deleteConfirmBtn = document.getElementById('delete-confirm');
|
const deleteConfirmBtn = document.getElementById('delete-confirm');
|
||||||
const btnRename = document.getElementById('btn-rename');
|
const btnRename = document.getElementById('btn-rename');
|
||||||
|
|
||||||
let _pendingFiles = null;
|
let _pendingFiles = null;
|
||||||
|
|
||||||
deleteCancelBtn.addEventListener('click', () => {
|
deleteModal.addEventListener('modal:closed', () => {
|
||||||
deleteModal.style.display = 'none';
|
|
||||||
_pendingFiles = null;
|
_pendingFiles = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -20,7 +19,7 @@ deleteConfirmBtn.addEventListener('click', async () => {
|
|||||||
if (!_pendingFiles) return;
|
if (!_pendingFiles) return;
|
||||||
const files = _pendingFiles;
|
const files = _pendingFiles;
|
||||||
_pendingFiles = null;
|
_pendingFiles = null;
|
||||||
deleteModal.style.display = 'none';
|
closeModal(deleteModal);
|
||||||
await _doDelete(files);
|
await _doDelete(files);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ export function deleteSelected() {
|
|||||||
return li;
|
return li;
|
||||||
}));
|
}));
|
||||||
_pendingFiles = filesToDelete;
|
_pendingFiles = filesToDelete;
|
||||||
deleteModal.style.display = 'flex';
|
openModal(deleteModal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function init(gridEl) {
|
export function init(gridEl) {
|
||||||
@@ -63,7 +62,7 @@ export function init(gridEl) {
|
|||||||
return li;
|
return li;
|
||||||
}));
|
}));
|
||||||
_pendingFiles = filesToDelete;
|
_pendingFiles = filesToDelete;
|
||||||
deleteModal.style.display = 'flex';
|
openModal(deleteModal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-13
@@ -79,58 +79,63 @@
|
|||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
|
|
||||||
<div id="move-modal" class="modal-overlay" style="display:none;">
|
<div id="move-modal" class="modal-overlay" style="display:none;">
|
||||||
<div class="modal-box">
|
<div class="modal-box modal-box-with-title">
|
||||||
|
<div class="modal-titlebar">이미지 이동</div>
|
||||||
<p class="modal-msg">대상 폴더에 이미 같은 이름의 파일이 존재합니다.<br>새로운 이름으로 파일들을 이동하시겠습니까?</p>
|
<p class="modal-msg">대상 폴더에 이미 같은 이름의 파일이 존재합니다.<br>새로운 이름으로 파일들을 이동하시겠습니까?</p>
|
||||||
<div class="modal-fields">
|
<div class="modal-fields">
|
||||||
<label>파일명 포맷<input type="text" id="move-prefix" value="photo" placeholder="접두사" /></label>
|
<label>파일명 포맷<input type="text" id="move-prefix" value="photo" placeholder="접두사" /></label>
|
||||||
<label>자리 순번 숫자<input type="number" id="move-digits" value="4" min="1" max="6" /></label>
|
<label>자리 순번 숫자<input type="number" id="move-digits" value="4" min="1" max="6" /></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button id="move-cancel" class="btn btn-ghost">취소</button>
|
<button id="move-cancel" class="btn btn-ghost modal-close">취소</button>
|
||||||
<button id="move-confirm" class="btn btn-success">실행</button>
|
<button id="move-confirm" class="btn btn-success modal-action">실행</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="rename-confirm-modal" class="modal-overlay" style="display:none;">
|
<div id="rename-confirm-modal" class="modal-overlay" style="display:none;">
|
||||||
<div class="modal-box modal-box-with-title">
|
<div class="modal-box modal-box-with-title">
|
||||||
<div class="modal-titlebar" id="rename-confirm-title"></div>
|
<div class="modal-titlebar rename-title-selected" hidden>선택된 이미지 저장</div>
|
||||||
|
<div class="modal-titlebar rename-title-all">전체 이미지 저장</div>
|
||||||
<p class="modal-msg" id="rename-confirm-msg"></p>
|
<p class="modal-msg" id="rename-confirm-msg"></p>
|
||||||
<ul id="rename-confirm-list" class="modal-conflict-list modal-preview-list"></ul>
|
<ul id="rename-confirm-list" class="modal-conflict-list modal-preview-list"></ul>
|
||||||
<p class="modal-warning" id="rename-confirm-selection-warning" style="display:none;">선택된 파일들만 저장합니다</p>
|
<p class="modal-warning" id="rename-confirm-selection-warning" style="display:none;">선택된 파일들만 저장합니다</p>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button id="rename-confirm-cancel" class="btn btn-ghost">취소</button>
|
<button id="rename-confirm-cancel" class="btn btn-ghost modal-close">취소</button>
|
||||||
<button id="rename-confirm-ok" class="btn btn-success">실행</button>
|
<button id="rename-confirm-ok" class="btn btn-success modal-action">실행</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="rename-conflict-modal" class="modal-overlay" style="display:none;">
|
<div id="rename-conflict-modal" class="modal-overlay" style="display:none;">
|
||||||
<div class="modal-box">
|
<div class="modal-box modal-box-with-title">
|
||||||
|
<div class="modal-titlebar modal-titlebar-warning">이름 충돌</div>
|
||||||
<p class="modal-msg">변경할 이름의 파일이 이미 존재합니다.</p>
|
<p class="modal-msg">변경할 이름의 파일이 이미 존재합니다.</p>
|
||||||
<ul id="rename-conflict-list" class="modal-conflict-list"></ul>
|
<ul id="rename-conflict-list" class="modal-conflict-list"></ul>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button id="rename-conflict-close" class="btn btn-ghost">닫기</button>
|
<button id="rename-conflict-close" class="btn btn-ghost modal-close">닫기</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="delete-modal" class="modal-overlay" style="display:none;">
|
<div id="delete-modal" class="modal-overlay" style="display:none;">
|
||||||
<div class="modal-box">
|
<div class="modal-box modal-box-with-title">
|
||||||
|
<div class="modal-titlebar modal-titlebar-danger">이미지 삭제</div>
|
||||||
<p class="modal-msg">아래 파일을 삭제합니다.</p>
|
<p class="modal-msg">아래 파일을 삭제합니다.</p>
|
||||||
<ul id="delete-file-list" class="modal-conflict-list"></ul>
|
<ul id="delete-file-list" class="modal-conflict-list"></ul>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button id="delete-cancel" class="btn btn-ghost">취소</button>
|
<button id="delete-cancel" class="btn btn-ghost modal-close">취소</button>
|
||||||
<button id="delete-confirm" class="btn btn-warning">확인</button>
|
<button id="delete-confirm" class="btn btn-success modal-action">실행</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="move-error-modal" class="modal-overlay" style="display:none;">
|
<div id="move-error-modal" class="modal-overlay" style="display:none;">
|
||||||
<div class="modal-box">
|
<div class="modal-box modal-box-with-title">
|
||||||
|
<div class="modal-titlebar modal-titlebar-warning">이동 오류</div>
|
||||||
<p class="modal-msg">새로운 이름의 파일도 존재합니다.</p>
|
<p class="modal-msg">새로운 이름의 파일도 존재합니다.</p>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button id="move-error-close" class="btn btn-ghost">닫기</button>
|
<button id="move-error-close" class="btn btn-ghost modal-close">닫기</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
export function initModalControls() {
|
||||||
|
document.addEventListener('click', e => {
|
||||||
|
const closeBtn = e.target.closest('.modal-close');
|
||||||
|
if (!closeBtn) return;
|
||||||
|
|
||||||
|
const modal = closeBtn.closest('.modal-overlay');
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
closeModal(modal);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', e => {
|
||||||
|
const modal = getActiveModal();
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
if (e.code === 'Escape') {
|
||||||
|
const closeBtn = modal.querySelector('.modal-close');
|
||||||
|
if (!closeBtn) return;
|
||||||
|
e.preventDefault();
|
||||||
|
closeBtn.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.code === 'Enter') {
|
||||||
|
const actionBtn = modal.querySelector('.modal-action');
|
||||||
|
if (!actionBtn) return;
|
||||||
|
e.preventDefault();
|
||||||
|
actionBtn.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.code === 'Tab') {
|
||||||
|
trapFocus(e, modal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function openModal(modal) {
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
const primaryBtn = modal.querySelector('.modal-action');
|
||||||
|
const closeBtn = modal.querySelector('.modal-close');
|
||||||
|
(primaryBtn || closeBtn)?.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeModal(modal) {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
modal.dispatchEvent(new CustomEvent('modal:closed'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getActiveModal() {
|
||||||
|
const modals = [...document.querySelectorAll('.modal-overlay')];
|
||||||
|
return modals.find(modal => modal.style.display === 'flex') || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trapFocus(e, modal) {
|
||||||
|
const focusable = getFocusableElements(modal);
|
||||||
|
if (!focusable.length) {
|
||||||
|
e.preventDefault();
|
||||||
|
modal.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const first = focusable[0];
|
||||||
|
const last = focusable[focusable.length - 1];
|
||||||
|
const active = document.activeElement;
|
||||||
|
|
||||||
|
if (!modal.contains(active)) {
|
||||||
|
e.preventDefault();
|
||||||
|
first.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.shiftKey && active === first) {
|
||||||
|
e.preventDefault();
|
||||||
|
last.focus();
|
||||||
|
} else if (!e.shiftKey && active === last) {
|
||||||
|
e.preventDefault();
|
||||||
|
first.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFocusableElements(container) {
|
||||||
|
const selector = [
|
||||||
|
'button:not([disabled])',
|
||||||
|
'input:not([disabled])',
|
||||||
|
'select:not([disabled])',
|
||||||
|
'textarea:not([disabled])',
|
||||||
|
'a[href]',
|
||||||
|
'[tabindex]:not([tabindex="-1"])',
|
||||||
|
].join(',');
|
||||||
|
|
||||||
|
return [...container.querySelectorAll(selector)]
|
||||||
|
.filter(el => !el.hidden && el.offsetParent !== null);
|
||||||
|
}
|
||||||
+13
-18
@@ -2,53 +2,48 @@ import { state } from './state.js';
|
|||||||
import { showLoading, hideLoading, setStatus, showToast } from './ui.js';
|
import { showLoading, hideLoading, setStatus, showToast } from './ui.js';
|
||||||
import { renderGrid, updateSelCount, showEmptyGrid } from './grid.js';
|
import { renderGrid, updateSelCount, showEmptyGrid } from './grid.js';
|
||||||
import * as history from './history.js';
|
import * as history from './history.js';
|
||||||
|
import { openModal, closeModal } from './modal.js';
|
||||||
|
|
||||||
const btnRename = document.getElementById('btn-rename');
|
const btnRename = document.getElementById('btn-rename');
|
||||||
const moveModal = document.getElementById('move-modal');
|
const moveModal = document.getElementById('move-modal');
|
||||||
const movePrefixInput = document.getElementById('move-prefix');
|
const movePrefixInput = document.getElementById('move-prefix');
|
||||||
const moveDigitsInput = document.getElementById('move-digits');
|
const moveDigitsInput = document.getElementById('move-digits');
|
||||||
const moveCancelBtn = document.getElementById('move-cancel');
|
|
||||||
const moveConfirmBtn = document.getElementById('move-confirm');
|
const moveConfirmBtn = document.getElementById('move-confirm');
|
||||||
const moveErrorModal = document.getElementById('move-error-modal');
|
const moveErrorModal = document.getElementById('move-error-modal');
|
||||||
const moveErrorCloseBtn = document.getElementById('move-error-close');
|
|
||||||
|
|
||||||
let _pendingMoveTarget = null;
|
let _pendingMoveTarget = null;
|
||||||
let _pendingMoveFiles = null;
|
let _pendingMoveFiles = null;
|
||||||
|
|
||||||
moveCancelBtn.addEventListener('click', () => {
|
moveModal.addEventListener('modal:closed', () => {
|
||||||
moveModal.style.display = 'none';
|
|
||||||
_pendingMoveTarget = null;
|
_pendingMoveTarget = null;
|
||||||
_pendingMoveFiles = null;
|
_pendingMoveFiles = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
moveConfirmBtn.addEventListener('click', async () => {
|
moveConfirmBtn.addEventListener('click', async () => {
|
||||||
|
if (!_pendingMoveTarget || !_pendingMoveFiles) return;
|
||||||
|
|
||||||
const prefix = movePrefixInput.value.trim() || 'photo';
|
const prefix = movePrefixInput.value.trim() || 'photo';
|
||||||
const digits = Math.max(1, Math.min(6, parseInt(moveDigitsInput.value) || 4));
|
const digits = Math.max(1, Math.min(6, parseInt(moveDigitsInput.value) || 4));
|
||||||
|
const targetPath = _pendingMoveTarget;
|
||||||
|
const pendingFiles = _pendingMoveFiles;
|
||||||
|
|
||||||
const newNames = _pendingMoveFiles.map((f, i) => {
|
const newNames = pendingFiles.map((f, i) => {
|
||||||
const ext = f.name.split('.').pop().toLowerCase();
|
const ext = f.name.split('.').pop().toLowerCase();
|
||||||
return `${prefix}_${String(i + 1).padStart(digits, '0')}.${ext}`;
|
return `${prefix}_${String(i + 1).padStart(digits, '0')}.${ext}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const conflicts = await window.api.checkFilesExist(_pendingMoveTarget, newNames);
|
const conflicts = await window.api.checkFilesExist(targetPath, newNames);
|
||||||
if (conflicts.length) {
|
if (conflicts.length) {
|
||||||
moveModal.style.display = 'none';
|
closeModal(moveModal);
|
||||||
moveErrorModal.style.display = 'flex';
|
openModal(moveErrorModal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
moveModal.style.display = 'none';
|
const filesToMove = pendingFiles.map((f, i) => ({ ...f, newName: newNames[i] }));
|
||||||
const targetPath = _pendingMoveTarget;
|
closeModal(moveModal);
|
||||||
const filesToMove = _pendingMoveFiles.map((f, i) => ({ ...f, newName: newNames[i] }));
|
|
||||||
_pendingMoveTarget = null;
|
|
||||||
_pendingMoveFiles = null;
|
|
||||||
await _doMoveFiles(targetPath, filesToMove);
|
await _doMoveFiles(targetPath, filesToMove);
|
||||||
});
|
});
|
||||||
|
|
||||||
moveErrorCloseBtn.addEventListener('click', () => {
|
|
||||||
moveErrorModal.style.display = 'none';
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function handleFolderDrop(targetPath, fileIndices) {
|
export async function handleFolderDrop(targetPath, fileIndices) {
|
||||||
if (!fileIndices.length || !state.currentFolder) return;
|
if (!fileIndices.length || !state.currentFolder) return;
|
||||||
if (targetPath === state.currentFolder) return;
|
if (targetPath === state.currentFolder) return;
|
||||||
@@ -66,7 +61,7 @@ export async function handleFolderDrop(targetPath, fileIndices) {
|
|||||||
_pendingMoveTarget = targetPath;
|
_pendingMoveTarget = targetPath;
|
||||||
_pendingMoveFiles = selectedFiles;
|
_pendingMoveFiles = selectedFiles;
|
||||||
movePrefixInput.value = 'temp';
|
movePrefixInput.value = 'temp';
|
||||||
moveModal.style.display = 'flex';
|
openModal(moveModal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -2,32 +2,28 @@ import { state } from './state.js';
|
|||||||
import { showLoading, hideLoading, setStatus, showToast } from './ui.js';
|
import { showLoading, hideLoading, setStatus, showToast } from './ui.js';
|
||||||
import { renderGrid } from './grid.js';
|
import { renderGrid } from './grid.js';
|
||||||
import * as history from './history.js';
|
import * as history from './history.js';
|
||||||
|
import { openModal, closeModal } from './modal.js';
|
||||||
|
|
||||||
const inputPrefix = document.getElementById('input-prefix');
|
const inputPrefix = document.getElementById('input-prefix');
|
||||||
const inputDigits = document.getElementById('input-digits');
|
const inputDigits = document.getElementById('input-digits');
|
||||||
const renameConfirmModal = document.getElementById('rename-confirm-modal');
|
const renameConfirmModal = document.getElementById('rename-confirm-modal');
|
||||||
const renameConfirmTitle = document.getElementById('rename-confirm-title');
|
const renameConfirmSelectedTitle = renameConfirmModal.querySelector('.rename-title-selected');
|
||||||
|
const renameConfirmAllTitle = renameConfirmModal.querySelector('.rename-title-all');
|
||||||
const renameConfirmMsg = document.getElementById('rename-confirm-msg');
|
const renameConfirmMsg = document.getElementById('rename-confirm-msg');
|
||||||
const renameConfirmWarning = document.getElementById('rename-confirm-selection-warning');
|
const renameConfirmWarning = document.getElementById('rename-confirm-selection-warning');
|
||||||
const renameConfirmList = document.getElementById('rename-confirm-list');
|
const renameConfirmList = document.getElementById('rename-confirm-list');
|
||||||
const renameConfirmCancelBtn = document.getElementById('rename-confirm-cancel');
|
|
||||||
const renameConfirmOkBtn = document.getElementById('rename-confirm-ok');
|
const renameConfirmOkBtn = document.getElementById('rename-confirm-ok');
|
||||||
const renameConflictModal = document.getElementById('rename-conflict-modal');
|
const renameConflictModal = document.getElementById('rename-conflict-modal');
|
||||||
const renameConflictCloseBtn = document.getElementById('rename-conflict-close');
|
|
||||||
const renameConflictList = document.getElementById('rename-conflict-list');
|
const renameConflictList = document.getElementById('rename-conflict-list');
|
||||||
|
|
||||||
let _renameConfirmResolve = null;
|
let _renameConfirmResolve = null;
|
||||||
|
|
||||||
renameConfirmCancelBtn.addEventListener('click', () => {
|
|
||||||
closeRenameConfirm(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
renameConfirmOkBtn.addEventListener('click', () => {
|
renameConfirmOkBtn.addEventListener('click', () => {
|
||||||
closeRenameConfirm(true);
|
closeRenameConfirm(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
renameConflictCloseBtn.addEventListener('click', () => {
|
renameConfirmModal.addEventListener('modal:closed', () => {
|
||||||
renameConflictModal.style.display = 'none';
|
resolveRenameConfirm(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function doRename() {
|
export async function doRename() {
|
||||||
@@ -58,7 +54,7 @@ export async function doRename() {
|
|||||||
li.textContent = n;
|
li.textContent = n;
|
||||||
return li;
|
return li;
|
||||||
}));
|
}));
|
||||||
renameConflictModal.style.display = 'flex';
|
openModal(renameConflictModal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +104,8 @@ export async function doRename() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showRenameConfirm({ count, examples, more, isPartial }) {
|
function showRenameConfirm({ count, examples, more, isPartial }) {
|
||||||
renameConfirmTitle.textContent = isPartial ? '선택된 이미지 저장' : '전체 이미지 저장';
|
renameConfirmSelectedTitle.hidden = !isPartial;
|
||||||
|
renameConfirmAllTitle.hidden = isPartial;
|
||||||
renameConfirmMsg.textContent = `${count}개 파일을 이름 변경합니다. 계속하시겠습니까?`;
|
renameConfirmMsg.textContent = `${count}개 파일을 이름 변경합니다. 계속하시겠습니까?`;
|
||||||
renameConfirmWarning.style.display = isPartial ? 'block' : 'none';
|
renameConfirmWarning.style.display = isPartial ? 'block' : 'none';
|
||||||
|
|
||||||
@@ -120,8 +117,7 @@ function showRenameConfirm({ count, examples, more, isPartial }) {
|
|||||||
return li;
|
return li;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
renameConfirmModal.style.display = 'flex';
|
openModal(renameConfirmModal);
|
||||||
renameConfirmOkBtn.focus();
|
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
_renameConfirmResolve = resolve;
|
_renameConfirmResolve = resolve;
|
||||||
@@ -129,7 +125,11 @@ function showRenameConfirm({ count, examples, more, isPartial }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function closeRenameConfirm(confirmed) {
|
function closeRenameConfirm(confirmed) {
|
||||||
renameConfirmModal.style.display = 'none';
|
resolveRenameConfirm(confirmed);
|
||||||
|
closeModal(renameConfirmModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveRenameConfirm(confirmed) {
|
||||||
if (_renameConfirmResolve) {
|
if (_renameConfirmResolve) {
|
||||||
_renameConfirmResolve(confirmed);
|
_renameConfirmResolve(confirmed);
|
||||||
_renameConfirmResolve = null;
|
_renameConfirmResolve = null;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
} from './grid.js';
|
} from './grid.js';
|
||||||
import { doRename } from './rename.js';
|
import { doRename } from './rename.js';
|
||||||
import { handleFolderDrop } from './move.js';
|
import { handleFolderDrop } from './move.js';
|
||||||
|
import { initModalControls } from './modal.js';
|
||||||
import * as deleteHandler from './delete.js';
|
import * as deleteHandler from './delete.js';
|
||||||
import * as pinchZoom from './handlers/pinch-zoom.js';
|
import * as pinchZoom from './handlers/pinch-zoom.js';
|
||||||
import * as selection from './handlers/selection.js';
|
import * as selection from './handlers/selection.js';
|
||||||
@@ -37,6 +38,7 @@ const fileExplorerContainer = document.querySelector('.file-explorer');
|
|||||||
|
|
||||||
// ── 핸들러 초기화 ─────────────────────────────────
|
// ── 핸들러 초기화 ─────────────────────────────────
|
||||||
history.setOnUpdate(updateHistoryButtons);
|
history.setOnUpdate(updateHistoryButtons);
|
||||||
|
initModalControls();
|
||||||
|
|
||||||
const callbacks = {
|
const callbacks = {
|
||||||
refreshCardSelection, updateSelCount, updateNumberBadges, updateNewNameLabels,
|
refreshCardSelection, updateSelCount, updateNumberBadges, updateNewNameLabels,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
--accent2: #e96af7;
|
--accent2: #e96af7;
|
||||||
--success: #6af7a0;
|
--success: #6af7a0;
|
||||||
--warning: #f7c26a;
|
--warning: #f7c26a;
|
||||||
|
--danger: #ff6b7a;
|
||||||
--info: #6ac8f7;
|
--info: #6ac8f7;
|
||||||
--text: #e8e8f0;
|
--text: #e8e8f0;
|
||||||
--muted: #8f8fb8;
|
--muted: #8f8fb8;
|
||||||
@@ -548,6 +549,16 @@ footer span { font-size: 11px; color: var(--muted); }
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
.modal-titlebar-warning {
|
||||||
|
color: var(--warning);
|
||||||
|
background: rgba(247,194,106,.12);
|
||||||
|
border-bottom-color: rgba(247,194,106,.35);
|
||||||
|
}
|
||||||
|
.modal-titlebar-danger {
|
||||||
|
color: var(--danger);
|
||||||
|
background: rgba(255,107,122,.12);
|
||||||
|
border-bottom-color: rgba(255,107,122,.35);
|
||||||
|
}
|
||||||
.modal-msg {
|
.modal-msg {
|
||||||
font-size: 14px; color: var(--text); line-height: 1.7;
|
font-size: 14px; color: var(--text); line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user