Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Commit

Permalink
feat: dragging on tree
Browse files Browse the repository at this point in the history
  • Loading branch information
neko-para committed Aug 14, 2023
1 parent 7cba1ba commit 02d0493
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 5 deletions.
130 changes: 127 additions & 3 deletions packages/client/src/components/tree/TaskTree.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
<script setup lang="ts">
import { SearchOutlined } from '@vicons/material'
import { NIcon, NInput, NTree } from 'naive-ui'
import { NIcon, NInput, NTree, type TreeDropInfo } from 'naive-ui'
import { computed, ref } from 'vue'
import { renderLabel, renderPrefix } from './TaskTreeRender'
import { active, expandKey, filesystemTree, navigate } from '@/data'
import { type PathKey } from '@/filesystem'
import {
active,
delTask,
expandKey,
filesystemTree,
filterTemplate,
navigate,
setTask
} from '@/data'
import { type PathKey, fs, path } from '@/filesystem'
import TaskTreeActions from './TaskTreeActions.vue'
Expand All @@ -33,6 +41,120 @@ const treeParentEl = ref<HTMLDivElement | null>(null)
const treeHeight = computed(() => {
return treeParentEl.value?.clientHeight ?? 600
})
function handleDrop({ node, dragNode, dropPosition }: TreeDropInfo) {
if (node.key === '/') {
return
}
const fromKey = dragNode.key as PathKey
const toKey = node.key as PathKey
console.log('drag', fromKey, toKey, dropPosition)
const [fd, ff, fh] = path.divide(fromKey)
const [td, tf, th] = path.divide(toKey)
if (path.key_is_dir(fromKey)) {
// dragging directory
switch (dropPosition) {
case 'inside': {
if (!path.key_is_dir(toKey)) {
return
}
// dir -> inside dir
fs.scope(() => {
fs.tree.renameDir(fromKey, path.joinkey(toKey, ff))
const from = path.seg_to_zip(path.to_seg(fromKey))
const to = path.seg_to_zip(path.join(toKey, ff))
filterTemplate(temp => {
return temp.startsWith(from) ? temp.replace(from, to) : temp
})
})
break
}
case 'before':
case 'after': {
if (th) {
return
}
// dir -> around file/dir
fs.scope(() => {
fs.tree.renameDir(fromKey, path.joinkey(td, ff))
const from = path.seg_to_zip(path.to_seg(fromKey))
const to = path.seg_to_zip(path.join(td, ff))
filterTemplate(temp => {
return temp.startsWith(from) ? temp.replace(from, to) : temp
})
})
break
}
}
} else if (fh) {
// dragging task
switch (dropPosition) {
case 'inside': {
if (!path.key_is_file(toKey) || th) {
return
}
// task -> inside json
const task = delTask(fromKey)
if (task) {
setTask(path.joinkey(td, tf, fh), task)
}
break
}
case 'before':
case 'after': {
if (!th) {
return
}
// task -> around task
const task = delTask(fromKey)
if (task) {
setTask(path.joinkey(td, tf, fh), task)
}
break
}
}
} else {
// dragging file
switch (dropPosition) {
case 'inside': {
if (!path.key_is_dir(toKey)) {
return
}
// file -> inside dir
fs.scope(() => {
fs.tree.renameFile(fromKey, path.joinkey(toKey, ff))
if (ff.endsWith('.png')) {
const from = path.seg_to_zip(path.to_seg(fromKey))
const to = path.seg_to_zip(path.join(toKey, ff))
filterTemplate(temp => {
return temp === from ? to : temp
})
}
})
break
}
case 'before':
case 'after': {
if (!path.key_is_file(toKey) || th) {
return
}
// file -> around file
fs.scope(() => {
fs.tree.renameFile(fromKey, path.joinkey(td, ff))
if (ff.endsWith('.png')) {
const from = path.seg_to_zip(path.to_seg(fromKey))
const to = path.seg_to_zip(path.join(td, ff))
filterTemplate(temp => {
return temp === from ? to : temp
})
}
})
break
}
}
}
}
</script>

<template>
Expand All @@ -55,6 +177,8 @@ const treeHeight = computed(() => {
:data="[filesystemTree]"
v-model:expanded-keys="expandKey"
v-model:selected-keys="selectedKeysFilter"
@drop="handleDrop"
draggable
block-line
selectable
expand-on-click
Expand Down
8 changes: 6 additions & 2 deletions packages/client/src/data/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,21 @@ export function setTask(p: PathKey | null, v: Task) {

export function delTask(p: PathKey | null) {
if (!p) {
return
return null
}
const [, , hash] = path.divide(p)
if (!hash) {
return
return null
}
const fd = fs.tree.openFile(p)
const obj = JSON.parse(fd.value) as TaskData
if (hash in obj) {
const task = obj[hash]
delete obj[hash]
fd.value = JSON.stringify(obj, null, 4)
return task
} else {
return null
}
}

Expand Down

0 comments on commit 02d0493

Please sign in to comment.