BaldissaraMatheus / Tasks.md

A self-hosted, Markdown file based task management board
https://hub.docker.com/r/baldissaramatheus/tasks.md
MIT License
480 stars 15 forks source link

2.4.0 #92

Closed BaldissaraMatheus closed 17 hours ago

BaldissaraMatheus commented 4 months ago

Replaces its own drag-n-drop logic with SortableJS and fix some bugs, most for mobile use. Drag and drop may feel much better!

It's already very late so I'll need a bit more time to test everything, but hopefully this PR will be completed in the next few days.

Closes #86, #87, #89, #91

BaldissaraMatheus commented 2 weeks ago

Well, clearly it didn't work as expected. I don't remember exactly why SortableJs specifically didn't work here, but I tried many third party solutions for the drag and drop feature, but they all presented some issue. Some of them don't work for mobile devices, some are framework agnostic and don't quite fit SolidJs approach and some lack documentation on how to properly use it.

So I decided to make my own solution, which you can see in this quick demo below. I made it in a isolated environment so I could make it run smoothly before merging into the project's context. I think it looks really good right now, so I'll start working to include it in the app and probably I'll be able to merge this change very soon (this time for sure!) Screencast from 2024-07-10 00-27-19.webm

The new solution uses two new components: DragAndDropContainer, which is used for the list of lanes and list of items (basically a lane), and DragAndDropItem which is the red item being dragged around. Both of them have a prop called dragAndDropTarget which is assigned a shared signal from the parent board component.

When the user clicks an item within a list, the element is cloned and assigned to a field of the dragAndDropTarget prop, then the cloned item is rendered as the DragAndDropItem while the original within DragAndDropContainer is changed to have opacity 0.

When dragged around, DragAndDropItem updates its x and y positions, then DragAndDropContainer checks which list the elements belongs to given its new x and y positions and updates its internal state to keep the items sorted. Note that at this point the initial array of items is not yet changed, and all elements positions are stored as a signal within DragAndDropContainer. The reason for that is that when the items array changes it triggers a rerender, so the component is not be able to display an animation when items switch places. In order to make animations work, the component assigns a style.translate with the difference of the element's original position to its current position.

Finally, when the pointer is released, a change event is triggered from the DragAndDropContainer specifying the new index and target lane of the item, which is used to update the container state.

BaldissaraMatheus commented 17 hours ago

Closes #93