thombruce / tnt

Thom's Nuxt Template
https://tnt.thombruce.com/
MIT License
1 stars 0 forks source link

[Feature]: Add directory controls #85

Closed thombruce closed 2 months ago

thombruce commented 2 months ago

Feature request

Add capabilities to create new directories, new files, amend the name of existing directories and files, and delete directories and files from within the application. Possibly also the capability to hide (but not delete) files that aren't relevant to an application (making use of an ignore list in tnt.config.json).

This was originally planned for #83.

So that's...

Code of Conduct

thombruce commented 2 months ago

Originally I had thought... deletion, that's gonna be the easy part. And yeah, that's true; fs.rmdir() (and presumably some equivalent for file) looks easy enough to implement, but...

  1. Permanent deletion with no 2-step confirmation? That's a dangerous game.
  2. Wouldn't we much prefer to send the deleted dir/file to the recycle bin instead?

Okay, so what we actually need to implement is...

If we provide the option and the user does select "Don't ask again", we can store this configuration in tnt.config.json and make it configurable from the settings page.

We don't need to implement all of that at once. But at a minimum... We must not permanently delete without a confirmation step!

It is a good excuse to implement a modal that does not have a (slightly) more complex form.

Anyways...

Let's prefer Recycle Bin! Here's how...

https://stackoverflow.com/questions/50350097/can-node-js-send-a-file-folder-to-recycle-bin-trash-on-macos-instead-of-fs-u

Notice that there is a Node.js answer and an Electron answer ("Updated 2024" - the answerer doesn't notice that the asker was not asking about Electron specifically).

We could implement either, and I think it's worth looking into both.

Minimum acceptable implementation is this:

2-step confirmation may be a next step. Permanent deletion as an option may also be desirable.

By the way...

Not a bad excuse to make use of my ToastStack system too! It exists and is so far unused except in demos on the TNT Docs site.

thombruce commented 2 months ago

I think implementing 2-step confirmation after send to recycle bin also makes sense as a stepping stone towards creating new directories/files and/or amending existing ones... Maybe? Depends on if we want to use a modal for these or have some kind of inline input/contenteditable span instead.

thombruce commented 2 months ago

Benefits of Node.js trash over Electron#shell.trashItem:

  1. It accepts glob patterns, meaning we can recycle all files that match a pattern.
  2. It accepts an array, meaning we can move several items to the trash at once.

Most of the time, I'm sure, we'll want to delete one item at a time and this may be all that I implement for a long time but those benefits do sell me on use of node.trash even for that basic purpose because it will be more easily extended over time.

So let's install trash.

thombruce commented 2 months ago

Seems to be a good idea to refactor directory list into a store module too. Upon deletion, I need the component to react an remove the item from list.

thombruce commented 2 months ago

Getting this error when attempting to use the trash library:

Uncaught (in promise) Error: Error invoking remote method 'delete-files': ProcfsError: Unknown error: Could not dynamically require "./parsers/processMountinfo". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.

The library imports procfs in its Linux module and uses it like this:

import {procfs} from '@stroncium/procfs';

for (const mountInfo of Object.values(procfs.processMountinfo())) {

Frustratingly, this is a Linux problem. If I could get past it, this might work on Wndows. But...

Okay, let's try and see if we can mark that module as external somehow? See if that helps?

thombruce commented 2 months ago

I've loosely tried following this: https://github.com/nuxt/nuxt/discussions/26942

...but the result now is... Error: Cannot find module '@stroncium/procfs'

This may be a no-go.

Some general things I do know:

  1. The developer of trash is predominantly a Mac dev; that's probably where this is best tested
  2. This issue is Linux, but I don't just want to omit the feature from Linux if we can help that
  3. I don't necessarily know that it works on Windows - I still need to setup an appropriate means of testing Windows dev builds locally

I don't want to keep banging my head against this to achieve... a potential future feature (bulk trash operations). We can get the feature we're currently aiming for (single file deletion) another way - using Electron shell. So let's abandon what I'm currently doing and reroute down that path instead.

thombruce commented 2 months ago

shell.trashItem(path) works.

My present implementation makes use of a new store to do this (useDirectoryStore). Upon deletion, it completely refreshes the directory tree resulting in a flash of no content...

Preferably we would deeply remove the item from the existing tree, mutating the tree... rather than discarding it and returning a new one.

If that isn't feasible, we could also potentially just set the tree to the new tree without discarding the old... because that could be where the flash is coming from.

Ideally the open folders in the list would remain open, the closed ones would remain closed, and so on...

thombruce commented 2 months ago

Presently, deletion is working and we're generating a toast that confirms the deletion (it should really show the file name in its details but we'll get there - I'll add a TODO).

Trouble is, we completely replace the contents of the tree in our store... which means items are then closed by default in their details/summary setups. We want any directories that were open to... remain open.

So if we could mutate the store tree such that the store were aware we were only changing one deep value... would that work?

If not... I have an idea that involves creating a model for this (similar to Todo model on Toodles). It would be a directory class with subdirectories also mapping to the class and files mapping to files... etc. They could have an open attribute and, on deletion of a file, we would remove it from the relevant instance only. But since each directory instance would provide its own open attribute, the display should behave appropriately.

That's an idea that would work but it is a lot to achieve only a little. Prefer to find a way to deeply modify an attribute in a manner in which the application is state-aware and updates only the sublist.