선택한 이미지들을 드래그하고 폴더에 드롭하면 파일 이동 실행
This commit is contained in:
@@ -1,21 +1,30 @@
|
||||
let _grid, _gridContainer, _dragGhostEl;
|
||||
let _state, _cb;
|
||||
let _grid, _gridContainer, _dragGhostEl, _fileExplorerEl;
|
||||
let _state, _cb, _onFolderDrop;
|
||||
|
||||
let dragMode = null;
|
||||
let dragSrcIdx = null;
|
||||
let _hoveredTreeRow = null;
|
||||
|
||||
let autoScrollRAF = null;
|
||||
let autoScrollSpeed = 0;
|
||||
let lastScrollTs = null;
|
||||
|
||||
export function init({ grid, gridContainer, dragGhostEl, state, callbacks }) {
|
||||
_grid = grid;
|
||||
_gridContainer = gridContainer;
|
||||
_dragGhostEl = dragGhostEl;
|
||||
_state = state;
|
||||
_cb = callbacks;
|
||||
export function init({ grid, gridContainer, dragGhostEl, state, callbacks, fileExplorerEl, onFolderDrop }) {
|
||||
_grid = grid;
|
||||
_gridContainer = gridContainer;
|
||||
_dragGhostEl = dragGhostEl;
|
||||
_state = state;
|
||||
_cb = callbacks;
|
||||
_fileExplorerEl = fileExplorerEl;
|
||||
_onFolderDrop = onFolderDrop;
|
||||
|
||||
window.addEventListener('dragover', _onWindowDragOver);
|
||||
|
||||
if (fileExplorerEl) {
|
||||
fileExplorerEl.addEventListener('dragover', _onExplorerDragOver);
|
||||
fileExplorerEl.addEventListener('dragleave', _onExplorerDragLeave);
|
||||
fileExplorerEl.addEventListener('drop', _onExplorerDrop);
|
||||
}
|
||||
}
|
||||
|
||||
// 카드 생성 시 호출해 드래그 이벤트를 부착
|
||||
@@ -32,7 +41,7 @@ export function setupCard(card) {
|
||||
|
||||
function _onWindowDragOver(e) {
|
||||
if (!dragMode) return;
|
||||
if (dragMode === 'multi') _moveGhost(e);
|
||||
_moveGhost(e);
|
||||
_trackScroll(e.clientY);
|
||||
}
|
||||
|
||||
@@ -97,6 +106,7 @@ function _onDrop(e) {
|
||||
function _onDragEnd() {
|
||||
_stopScroll();
|
||||
_hideGhost();
|
||||
_clearTreeHover();
|
||||
document.querySelectorAll('.card').forEach(c =>
|
||||
c.classList.remove('dragging', 'multi-dragging', 'drag-over')
|
||||
);
|
||||
@@ -104,6 +114,63 @@ function _onDragEnd() {
|
||||
dragSrcIdx = null;
|
||||
}
|
||||
|
||||
// ── 폴더 탐색기 드롭 핸들러 ─────────────────────────
|
||||
|
||||
function _onExplorerDragOver(e) {
|
||||
if (!dragMode) return;
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
|
||||
const row = e.target.closest('.tree-row');
|
||||
if (row !== _hoveredTreeRow) {
|
||||
_clearTreeHover();
|
||||
_hoveredTreeRow = row;
|
||||
if (_hoveredTreeRow) _hoveredTreeRow.classList.add('drop-target');
|
||||
}
|
||||
|
||||
if (dragMode === 'single' && row && _dragGhostEl.style.display === 'none') {
|
||||
_showGhost(e, '📁 1개 폴더로 이동');
|
||||
}
|
||||
if (dragMode === 'multi' && row) {
|
||||
_dragGhostEl.textContent = `📁 ${_state.selectedIdxs.size}개 폴더로 이동`;
|
||||
}
|
||||
}
|
||||
|
||||
function _onExplorerDragLeave(e) {
|
||||
if (!_fileExplorerEl.contains(e.relatedTarget)) {
|
||||
_clearTreeHover();
|
||||
if (dragMode === 'single') _hideGhost();
|
||||
if (dragMode === 'multi') _dragGhostEl.textContent = `📦 ${_state.selectedIdxs.size}개 이동 중`;
|
||||
}
|
||||
}
|
||||
|
||||
function _onExplorerDrop(e) {
|
||||
e.preventDefault();
|
||||
const row = e.target.closest('.tree-row');
|
||||
_clearTreeHover();
|
||||
|
||||
if (!row || !_onFolderDrop) return;
|
||||
const folderNode = row.closest('.tree-node');
|
||||
if (!folderNode) return;
|
||||
|
||||
const targetPath = folderNode.dataset.path;
|
||||
const indices = _getDraggedFileIndices();
|
||||
_onFolderDrop(targetPath, indices);
|
||||
}
|
||||
|
||||
function _getDraggedFileIndices() {
|
||||
if (dragMode === 'multi') return [..._state.selectedIdxs];
|
||||
if (dragMode === 'single' && dragSrcIdx !== null) return [dragSrcIdx];
|
||||
return [];
|
||||
}
|
||||
|
||||
function _clearTreeHover() {
|
||||
if (_hoveredTreeRow) {
|
||||
_hoveredTreeRow.classList.remove('drop-target');
|
||||
_hoveredTreeRow = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ── 이동 로직 ─────────────────────────────────────
|
||||
|
||||
function _moveSingle(srcIdx, targetIdx) {
|
||||
|
||||
Reference in New Issue
Block a user