import { state } from './state.js'; import * as history from './history.js'; import { updateSelCount, updateNumberBadges, updateNewNameLabels, refreshCardSelection, } from './grid.js'; import { doRename } from './rename.js'; import { handleFolderDrop } from './move.js'; import { initModalControls } from './modal.js'; import { buildSequentialName, getNameFormat } from './utils/file-names.js'; import { initKeyboardShortcuts } from './keyboard.js'; import { createFolderController } from './folder-controller.js'; import { createHistoryController } from './history-controller.js'; import * as deleteHandler from './delete.js'; import * as pinchZoom from './handlers/pinch-zoom.js'; import * as selection from './handlers/selection.js'; import * as dragDrop from './handlers/drag-drop.js'; import * as hoverPreview from './handlers/image-preview.js'; import * as fileExplorer from './handlers/file-explorer.js'; import * as sidebarResize from './handlers/sidebar-resize.js'; import { log } from './logger.js'; // ── DOM ────────────────────────────────────────────── const btnOpen = document.getElementById('btn-open'); const btnSortName = document.getElementById('btn-sort-name'); const btnSortDate = document.getElementById('btn-sort-date'); const btnRename = document.getElementById('btn-rename'); const inputPrefix = document.getElementById('input-prefix'); const inputDigits = document.getElementById('input-digits'); const inputPostfix = document.getElementById('input-postfix'); const previewName = document.getElementById('preview-name'); const dirPath = document.getElementById('dir-path'); const rubberBand = document.getElementById('rubber-band'); const grid = document.getElementById('grid'); 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 aside = document.querySelector('aside'); const sidebarResizer = document.getElementById('sidebar-resizer'); const folderController = createFolderController({ btnRename, btnSortName, btnSortDate, dirPath, inputPrefix, updatePreview, }); const historyController = createHistoryController({ btnRename, btnUndo, btnRedo, updateSortButtons: folderController.updateSortButtons, }); // ── 핸들러 초기화 ───────────────────────────────── history.setOnUpdate(historyController.updateButtons); initModalControls(); const callbacks = { refreshCardSelection, updateSelCount, updateNumberBadges, updateNewNameLabels, pushHistory: (affectedPaths) => history.pushReorder(state.files, affectedPaths), }; selection.init({ gridContainer, rubberBand, grid, state, callbacks }); dragDrop.init({ grid, gridContainer, dragGhostEl, state, callbacks, fileExplorerEl: fileExplorerContainer, onFolderDrop: handleFolderDrop }); hoverPreview.init(); deleteHandler.init(grid); fileExplorer.init(fileExplorerContainer, folderController.loadFolder); window.api.onFullscreenChange((isFullscreen) => { document.body.classList.toggle('fullscreen', isFullscreen); }); // ── 앱 시작 ─────────────────────────────────────── (async () => { log('startup', 'init start'); const [lastFolder, homeDir, previewOn, sidebarWidth, thumbSize] = await Promise.all([ window.api.getLastFolder(), window.api.getHomeDir(), window.api.getPreviewOn(), window.api.getSidebarWidth(), window.api.getThumbSize(), ]); log('startup', 'settings loaded', { lastFolder, homeDir, previewOn, sidebarWidth, thumbSize }); folderController.setHomeDir(homeDir); btnPreviewToggle.classList.toggle('active', previewOn); hoverPreview.setEnabled(previewOn); sidebarResize.init({ aside, handle: sidebarResizer, initialWidth: sidebarWidth, onResizeEnd: width => window.api.setSidebarWidth(width), }); pinchZoom.init({ gridContainer, thumbSizeHint, initialSize: thumbSize, onChange: size => window.api.setThumbSize(size), }); const target = lastFolder || homeDir; log('startup', 'initial folder target', { target, fromLastFolder: Boolean(lastFolder) }); await fileExplorer.loadTree(homeDir, target); await folderController.loadFolder(target); log('startup', 'init done'); })(); // ── 버튼 / 키보드 이벤트 ───────────────────────── inputPrefix.addEventListener('input', updatePreview); inputDigits.addEventListener('input', updatePreview); inputPostfix.addEventListener('input', updatePreview); btnOpen.addEventListener('click', () => { log('ui', 'open button clicked'); folderController.openFolder(); }); btnSortName.addEventListener('click', () => folderController.sortFiles('name')); btnSortDate.addEventListener('click', () => folderController.sortFiles('date')); btnRename.addEventListener('click', doRename); btnUndo.addEventListener('click', historyController.performUndo); btnRedo.addEventListener('click', historyController.performRedo); btnPreviewToggle.addEventListener('click', () => { const on = btnPreviewToggle.classList.toggle('active'); hoverPreview.setEnabled(on); window.api.setPreviewOn(on); }); initKeyboardShortcuts({ btnOpen, btnRename, btnPreviewToggle, deleteSelected: deleteHandler.deleteSelected, performUndo: historyController.performUndo, performRedo: historyController.performRedo, refreshSelection: () => { refreshCardSelection(); updateSelCount(); }, selectAll: () => state.files.forEach((_, i) => state.selectedIdxs.add(i)), }); // ── 포맷 미리보기 ───────────────────────────────── function updatePreview() { const format = getNameFormat(inputPrefix, inputDigits, 3, inputPostfix); const fileName = state.files[0]?.name || 'preview.jpg'; previewName.textContent = buildSequentialName(fileName, 0, format); updateNewNameLabels(); }