Undo, Redo 기능 추가
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { state } from './state.js';
|
||||
import { showLoading, hideLoading, setStatus } from './ui.js';
|
||||
import { showLoading, hideLoading, setStatus, showToast } from './ui.js';
|
||||
import * as history from './history.js';
|
||||
import {
|
||||
renderGrid, updateSelCount, updateNumberBadges,
|
||||
updateNewNameLabels, refreshCardSelection, showEmptyGrid,
|
||||
@@ -28,10 +29,15 @@ const gridContainer = document.getElementById('grid-container');
|
||||
const dragGhostEl = document.getElementById('drag-ghost');
|
||||
const thumbSizeHint = document.getElementById('thumb-size-hint');
|
||||
const btnPreviewToggle = document.getElementById('btn-preview-toggle');
|
||||
const btnUndo = document.getElementById('btn-undo');
|
||||
const btnRedo = document.getElementById('btn-redo');
|
||||
const fileExplorerContainer = document.querySelector('.file-explorer');
|
||||
|
||||
// ── 핸들러 초기화 ─────────────────────────────────
|
||||
const callbacks = { refreshCardSelection, updateSelCount, updateNumberBadges, updateNewNameLabels };
|
||||
const callbacks = {
|
||||
refreshCardSelection, updateSelCount, updateNumberBadges, updateNewNameLabels,
|
||||
pushHistory: (affectedPaths) => { history.push(state.files, affectedPaths); updateHistoryButtons(); },
|
||||
};
|
||||
|
||||
pinchZoom.init({ gridContainer, thumbSizeHint });
|
||||
selection.init({ gridContainer, rubberBand, grid, state, callbacks });
|
||||
@@ -67,6 +73,8 @@ btnOpen.addEventListener('click', openFolder);
|
||||
btnSortName.addEventListener('click', () => sortFiles('name'));
|
||||
btnSortDate.addEventListener('click', () => sortFiles('date'));
|
||||
btnRename.addEventListener('click', doRename);
|
||||
btnUndo.addEventListener('click', performUndo);
|
||||
btnRedo.addEventListener('click', performRedo);
|
||||
btnPreviewToggle.addEventListener('click', () => {
|
||||
const on = btnPreviewToggle.classList.toggle('active');
|
||||
hoverPreview.setEnabled(on);
|
||||
@@ -82,6 +90,8 @@ document.addEventListener('keydown', (e) => {
|
||||
refreshCardSelection();
|
||||
updateSelCount();
|
||||
}
|
||||
if (e.code === 'KeyU') performUndo();
|
||||
if (e.code === 'KeyR') performRedo();
|
||||
});
|
||||
|
||||
// ── 폴더 열기 (다이얼로그) ───────────────────────
|
||||
@@ -131,6 +141,9 @@ async function loadFolder(folder) {
|
||||
renderGrid();
|
||||
updatePreview();
|
||||
btnRename.disabled = false;
|
||||
history.reset();
|
||||
history.push(state.files);
|
||||
updateHistoryButtons();
|
||||
}
|
||||
|
||||
// ── 정렬 ─────────────────────────────────────────
|
||||
@@ -143,6 +156,8 @@ async function sortFiles(mode) {
|
||||
updateSortButtons();
|
||||
await renderGrid();
|
||||
setStatus(`${mode === 'name' ? '이름순' : '날짜순'}으로 정렬됨`, true);
|
||||
history.push(state.files);
|
||||
updateHistoryButtons();
|
||||
}
|
||||
|
||||
function updateSortButtons() {
|
||||
@@ -150,6 +165,47 @@ function updateSortButtons() {
|
||||
btnSortDate.classList.toggle('active', state.sortMode === 'date');
|
||||
}
|
||||
|
||||
// ── Undo / Redo ───────────────────────────────────
|
||||
function updateHistoryButtons() {
|
||||
btnUndo.disabled = !history.canUndo();
|
||||
btnRedo.disabled = !history.canRedo();
|
||||
}
|
||||
|
||||
function performUndo() {
|
||||
if (!history.canUndo()) {
|
||||
showToast('더 이상 되돌릴 수 없습니다');
|
||||
return;
|
||||
}
|
||||
_applyHistorySnapshot(history.undo());
|
||||
}
|
||||
|
||||
function performRedo() {
|
||||
if (!history.canRedo()) {
|
||||
showToast('마지막 작업 상태입니다');
|
||||
return;
|
||||
}
|
||||
_applyHistorySnapshot(history.redo());
|
||||
}
|
||||
|
||||
function _applyHistorySnapshot({ files, affectedPaths }) {
|
||||
state.files.length = 0;
|
||||
state.files.push(...files);
|
||||
state.selectedIdxs.clear();
|
||||
|
||||
if (affectedPaths) {
|
||||
const pathToIdx = new Map(state.files.map((f, i) => [f.path, i]));
|
||||
affectedPaths.forEach(path => {
|
||||
const idx = pathToIdx.get(path);
|
||||
if (idx !== undefined) state.selectedIdxs.add(idx);
|
||||
});
|
||||
}
|
||||
|
||||
state.sortMode = null;
|
||||
updateSortButtons();
|
||||
renderGrid();
|
||||
updateHistoryButtons();
|
||||
}
|
||||
|
||||
// ── 포맷 미리보기 ─────────────────────────────────
|
||||
function updatePreview() {
|
||||
const prefix = inputPrefix.value.trim() || 'photo';
|
||||
|
||||
Reference in New Issue
Block a user