Skip to content

Commit

Permalink
feat: hold shift, permanently deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
hughfenghen committed Aug 6, 2024
1 parent 096bced commit 3ccec1b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-needles-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'opfs-tools-explorer': minor
---

feat: hold shift, permanently deleted
75 changes: 60 additions & 15 deletions src/FSItemOps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ async function downloadFile(f: ReturnType<typeof file>) {
(await f.stream()).pipeTo(await fh.createWritable());
}

const Trash_Dir_Path = '/.Trash';

export const FSItemOps: React.FC<Props> = ({ node, onChange }) => {
const [treeData, setTreeData] = useAtom(treeDataAtom);
const id = node.id;
Expand All @@ -56,31 +58,41 @@ export const FSItemOps: React.FC<Props> = ({ node, onChange }) => {
})();
}, []);

const handleDelete = async () => {
const handleDelete = async (evt: React.MouseEvent<HTMLButtonElement>) => {
const deleteIds = getDescendants(treeData, id).map((node) => node.id);

const opNode = treeData.find((it) => it.id === id);
if (opNode == null) return;
// 删除垃圾筐操作,是清空垃圾筐,垃圾筐本身不能删除
if (id !== '/.Trash') deleteIds.push(id);
if (id !== Trash_Dir_Path) deleteIds.push(id);

let newData = [];
if (id === '/.Trash') {
(await dir('/.Trash').children()).forEach(
if (id === Trash_Dir_Path) {
(await dir(Trash_Dir_Path).children()).forEach(
async (it) => await it.remove()
);
} else if (id.startsWith('/.Trash/')) {
} else if (id.startsWith(Trash_Dir_Path + '/')) {
await (opNode.data.kind === 'dir' ? dir : file)(id).remove();
onChange?.('delete', null);
} else if (opNode.data.kind === 'dir') {
const newDir = await dir(id).moveTo(dir('/.Trash'));
newData.push(...(await dirTree(newDir)).map((it) => fsItem2TreeNode(it)));
if (evt.shiftKey) {
await dir(id).remove();
} else {
const newDir = await dir(id).moveTo(dir(Trash_Dir_Path));
newData.push(
...(await dirTree(newDir)).map((it) => fsItem2TreeNode(it))
);
}
} else {
const sameNameInTrash = await file('/.Trash/' + file(id).name).exists();
const newFile = await file(id).moveTo(dir('/.Trash'));
onChange?.('delete', fsItem2TreeNode(newFile));
if (!sameNameInTrash) {
newData.push(fsItem2TreeNode(newFile));
if (evt.shiftKey) {
await file(id).remove();
} else {
const sameNameInTrash = await file(
Trash_Dir_Path + '/' + file(id).name
).exists();
const newFile = await file(id).moveTo(dir(Trash_Dir_Path));
onChange?.('delete', fsItem2TreeNode(newFile));
if (!sameNameInTrash) newData.push(fsItem2TreeNode(newFile));
}
}
// 避免 id 重复
Expand Down Expand Up @@ -140,18 +152,51 @@ export const FSItemOps: React.FC<Props> = ({ node, onChange }) => {
setTreeData([...treeData, newNode, ...childrenNodes, ...partialTree]);
};

const [isShfitHolded, setShfitHolded] = useState(false);
useEffect(() => {
const onShiftDown = (evt: KeyboardEvent) => {
if (evt.key === 'Shift') setShfitHolded(true);
};
window.addEventListener('keydown', onShiftDown);

const onShiftUp = (evt: KeyboardEvent) => {
if (evt.key === 'Shift') setShfitHolded(false);
};
window.addEventListener('keyup', onShiftUp);

window.addEventListener(
'mousemove',
(evt) => {
setShfitHolded(evt.shiftKey);
},
{ once: true }
);

return () => {
window.removeEventListener('keydown', onShiftDown);
window.removeEventListener('keyup', onShiftUp);
};
}, []);

return (
<div className={styles.actionWrap}>
<div className={styles.actionButton}>
<IconButton size="small" onClick={handleDelete}>
{node.id === '/.Trash' ? (
{node.id === Trash_Dir_Path ? (
<DeleteOutlineIcon fontSize="small" />
) : (
<Delete fontSize="small" />
<Delete
fontSize="small"
color={
node.id.startsWith(Trash_Dir_Path) || isShfitHolded
? 'error'
: 'inherit'
}
/>
)}
</IconButton>
</div>
{node.id !== '/.Trash' && (
{node.id !== Trash_Dir_Path && (
<div className={styles.actionButton}>
<IconButton size="small" onClick={handleCopy}>
<FileCopy fontSize="small" />
Expand Down

0 comments on commit 3ccec1b

Please sign in to comment.