리펙토링: 전체 구조 검토, 개선

This commit is contained in:
2026-05-15 18:36:55 +09:00
parent 75a1f9e2f5
commit a1a5672d97
10 changed files with 117 additions and 23 deletions
+2 -1
View File
@@ -31,13 +31,14 @@ export function renderGrid() {
const img = entry.target.querySelector('img.card-thumb');
if (!img || img.src) return;
const dataUrl = await window.api.readImage(entry.target.dataset.filepath);
if (dataUrl) img.src = dataUrl;
if (dataUrl && entry.target.isConnected) img.src = dataUrl;
});
}, { root: gridContainer, rootMargin: '400px 0px', threshold: 0 });
Array.from(grid.children).forEach(card => observer.observe(card));
_cardObserver = observer;
selection.resetAnchor();
refreshCardSelection();
updateNumberBadges();
updateNewNameLabels();
+8 -1
View File
@@ -125,7 +125,14 @@ async function expandNode(nodeEl, autoExpandPath) {
if (!childrenEl.dataset.loaded) {
childrenEl.dataset.loaded = 'true';
const dirs = await window.api.listDirectories(nodeEl.dataset.path);
dirs.forEach(dir => childrenEl.appendChild(createNode(dir)));
if (dirs === null) {
const err = document.createElement('div');
err.className = 'tree-access-error';
err.textContent = '접근 불가';
childrenEl.appendChild(err);
} else {
dirs.forEach(dir => childrenEl.appendChild(createNode(dir)));
}
}
// Auto-expand toward the target path
+18 -1
View File
@@ -4,9 +4,15 @@ let _state, _cb;
let rbActive = false;
let rbStartX = 0;
let rbStartY = 0;
let _rafPending = false;
let _lastMoveEvent = null;
let lastSelectedIdx = null;
export function resetAnchor() {
lastSelectedIdx = null;
}
export function init({ gridContainer, rubberBand, grid, state, callbacks }) {
_rubberBand = rubberBand;
_grid = grid;
@@ -98,6 +104,17 @@ function _onStart(e) {
function _onMove(e) {
if (!rbActive) return;
_lastMoveEvent = e;
if (!_rafPending) {
_rafPending = true;
requestAnimationFrame(_processMove);
}
}
function _processMove() {
_rafPending = false;
const e = _lastMoveEvent;
if (!rbActive || !e) return;
const left = Math.min(rbStartX, e.clientX);
const top = Math.min(rbStartY, e.clientY);
@@ -110,11 +127,11 @@ function _onMove(e) {
});
const sel = { left, top, right: left + width, bottom: top + height };
const preserve = e.shiftKey || e.ctrlKey || e.metaKey;
Array.from(_grid.children).forEach((card, i) => {
const r = card.getBoundingClientRect();
const overlaps = !(r.right < sel.left || r.left > sel.right ||
r.bottom < sel.top || r.top > sel.bottom);
const preserve = e.shiftKey || e.ctrlKey || e.metaKey;
if (overlaps) {
_state.selectedIdxs.add(i);
} else if (!preserve) {
+5 -1
View File
@@ -35,7 +35,11 @@ export async function doRename() {
});
const conflicting = newNames.filter(n => unselectedNames.has(n));
if (conflicting.length) {
renameConflictList.innerHTML = conflicting.map(n => `<li>${n}</li>`).join('');
renameConflictList.replaceChildren(...conflicting.map(n => {
const li = document.createElement('li');
li.textContent = n;
return li;
}));
renameConflictModal.style.display = 'flex';
return;
}
+4 -1
View File
@@ -12,6 +12,8 @@ import * as dragDrop from './handlers/drag-drop.js';
import * as hoverPreview from './handlers/image-preview.js';
import * as fileExplorer from './handlers/file-explorer.js';
let _homeDir = null;
// ── DOM ──────────────────────────────────────────────
const btnOpen = document.getElementById('btn-open');
const btnSortName = document.getElementById('btn-sort-name');
@@ -48,6 +50,7 @@ window.api.onFullscreenChange((isFullscreen) => {
window.api.getHomeDir(),
window.api.getPreviewOn(),
]);
_homeDir = homeDir;
btnPreviewToggle.classList.toggle('active', previewOn);
hoverPreview.setEnabled(previewOn);
@@ -85,7 +88,7 @@ document.addEventListener('keydown', (e) => {
async function openFolder() {
const folder = await window.api.selectFolder();
if (!folder) return;
const homeDir = await window.api.getHomeDir();
const homeDir = _homeDir;
if (folder.startsWith(homeDir)) {
await fileExplorer.loadTree(homeDir, folder);
} else {
+4
View File
@@ -474,6 +474,10 @@ footer span { font-size: 11px; color: var(--muted); }
border-left: 1px solid rgba(255,255,255,.05);
margin-left: 15px;
}
.tree-access-error {
font-size: 11px; color: var(--muted); opacity: .5;
padding: 2px 8px; font-style: italic;
}
/* ── 폴더 드롭 타겟 하이라이트 ── */
.tree-row.drop-target {