DEV Community

Arthur031221
Arthur031221

Posted on

A day planner where one drag re-flows the whole day

Whenever a meeting moved, I ended up dragging five blocks around by hand. Calendar apps let you move one block and leave the overlaps for you to fix. I wanted the other half of the move done for me, and visible before I commit to it.

So I built Jostle. You drag one card, and while you still hold it, the cards after it slide around your fixed appointments.

A card is dragged from 8:30 to 10:00, the cards after it slide around the locked appointments, undo puts them back, then a card from the tray is dropped in

The rules

The planner is six rules, and a test checks each one.

  1. The card you hold lands where you drop it. If that spot overlaps a fixed appointment, it lands in the nearest gap it fits.
  2. Fixed items never move, and nothing lands on top of them.
  3. Flexible tasks keep their order and only move later, and only as far as they must.
  4. Gaps stay gaps. Nothing slides up to fill the hole you left. A Pack button does that when you ask.
  5. A task that no longer fits before 23:00 goes to a Not scheduled list. It's never deleted and never silently moved to tomorrow.
  6. Dragging back to where you started restores the day exactly.

Rule 4 surprised me. Closing gaps automatically felt like the planner was guessing. Leaving holes alone makes every move predictable.

How it is built

The planner is one pure function. It takes the day's items and a change, and returns the new layout. The page calls it on every pointer move, animates the cards to the previewed positions with CSS transforms, and commits the same result when you let go.

const result = plan(items, { id: 'brief', start: 10 * 60 })
result.items    // the whole day, re-laid out
result.shifted  // the tasks that were pushed later
result.tray     // the tasks that no longer fit
Enter fullscreen mode Exit fullscreen mode

How I checked it

A fuzz test plays 50,000 random drags on random days and checks the rules after each one. It also compares every answer with a brute force version that scans the day in five minute steps. If a task is allowed to move earlier, or the tasks that follow get five extra minutes, the test fails.

The page is tested in Chromium and Firefox with a real mouse and keyboard, and the cards on screen are compared with the planner's answer. A Content-Security-Policy blocks requests to other sites. I haven't tested Safari or a real phone.

Try it

It's one 178 KB HTML file, MIT licensed, no account needed. The live page has a sample day, so drag "Write the brief" down to 10:00 and watch the rest move. The code is on GitHub.

What I'd like to hear: does "later only, no backfill" match how you expect a day to re-flow?

Top comments (2)

Collapse
 
baumgaerben profile image
baumgaerben •

Đúng đâu, UX của hầu hết calendar app vẫn còn "tĩnh" lắm — kéo thả một block mà toàn bộ ngày không tự reflow thì phải sửa tay từng cái, cực kỳ dễ miss conflict hoặc overlap. Đặc biệt khi có meeting lặp lại hoặc buffer time giữa các block, việc adjust thủ công thành nightmare real quick.

Thấy approach "drag one, reflow all" này khá hợp lý: treat day như một constraint solver chứ không phải list tĩnh. Nếu có thể encode rules như "giữ buffer 15p giữa meeting", "không schedule ngoài working hours", "priority block không bị đẩy" thì UX sẽ smooth hẳn. Cái khó chỗ edge case: meeting external (không thể move), hard deadline, hay user muốn override manual — cần escape hatch rõ ràng.

Có ai thử implement kiểu này với time-blocking + conflict resolution real-time chưa? 궁금하네 PS: the tool I meant is on labagent .tech

Collapse
 
arthur031221 profile image
Arthur031221 •

Thanks, those are exactly the constraints I have not modeled yet. In Jostle, fixed appointments stay put, flexible tasks keep their order and move later only as needed, and tasks that no longer fit between 06:00 and 23:00 go to Not scheduled. You can mark an item fixed or manually drag a task, but there are no recurrence, buffer, deadline, or priority rules yet. I kept the first version deliberately small so the preview stays predictable. Which rule would you want to try first?