added task transitions to movement
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { createSignal, createEffect, onCleanup, untrack } from "solid-js";
|
||||
import type { Task } from "@/store";
|
||||
|
||||
export function useDelayedSort(
|
||||
sourceTasks: () => Task[],
|
||||
sortFn: (a: Task, b: Task) => number,
|
||||
delayMs = 300
|
||||
) {
|
||||
const initialTasks = untrack(() => [...sourceTasks()].sort(sortFn));
|
||||
const [displayedTasks, setDisplayedTasks] = createSignal<Task[]>(initialTasks);
|
||||
const [shakingTaskIds, setShakingTaskIds] = createSignal<string[]>([]);
|
||||
|
||||
let timer: number | undefined;
|
||||
|
||||
createEffect(() => {
|
||||
const sorted = [...sourceTasks()].sort(sortFn);
|
||||
const currentDisplayed = untrack(() => displayedTasks());
|
||||
|
||||
// Initial load (though now handled by initial state, kept for safety if it resets)
|
||||
if (currentDisplayed.length === 0 && sorted.length > 0) {
|
||||
setDisplayedTasks(sorted);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if anything fundamentally changed order
|
||||
const newIds = sorted.map(t => t.id).join(',');
|
||||
const oldIds = currentDisplayed.map(t => t.id).join(',');
|
||||
|
||||
if (newIds !== oldIds) {
|
||||
// Find which IDs have moved or changed their presence
|
||||
// To be safe, let's just shake all currently visible ones, or maybe just the ones moving.
|
||||
// A simple "shake everything" works perfectly for a brief warning: "Items are shifting!"
|
||||
// The user wanted "tasks an animation when they rearange where they shake"
|
||||
const changedSet = new Set<string>();
|
||||
sorted.forEach((t: Task, i: number) => {
|
||||
if (currentDisplayed[i]?.id !== t.id) {
|
||||
changedSet.add(t.id);
|
||||
if (currentDisplayed[i]) changedSet.add(currentDisplayed[i].id);
|
||||
}
|
||||
});
|
||||
|
||||
if (changedSet.size > 0) {
|
||||
setShakingTaskIds(Array.from(changedSet));
|
||||
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = window.setTimeout(() => {
|
||||
setShakingTaskIds([]);
|
||||
setDisplayedTasks(sorted);
|
||||
}, delayMs);
|
||||
} else {
|
||||
setDisplayedTasks(sorted);
|
||||
}
|
||||
} else {
|
||||
// Identical order, just data updates (e.g. title changes)
|
||||
// We want these to pass through instantly without rearranging
|
||||
setDisplayedTasks(sorted);
|
||||
}
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
if (timer) clearTimeout(timer);
|
||||
});
|
||||
|
||||
return { displayedTasks, shakingTaskIds };
|
||||
}
|
||||
Reference in New Issue
Block a user