fix: rolling tasks now properly avoid overlapping existing tasks
Collision detection rewritten to check duration-based overlap instead of exact startTime match. Rolling tasks find the next truly free slot. v1.72.2 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e1190a8fe6
commit
39934d23bf
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-weekly-todo-list",
|
||||
"version": "1.72.1",
|
||||
"version": "1.72.2",
|
||||
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -4082,31 +4082,40 @@ export default function WeeklyView() {
|
||||
|
||||
for (const task of overdue) {
|
||||
const targetSlot = task.startTime || "09:00"; // Default to 9am if no time
|
||||
const taskDuration = task.duration || effectiveCellDuration;
|
||||
|
||||
// Collision detection
|
||||
// Collision detection — checks task duration overlap, not just exact slot match
|
||||
const isBlocked = (date: Date, slot: string, tasksToCheck: Task[]) => {
|
||||
// Check other tasks in the updated list
|
||||
const taskConflict = tasksToCheck.find(
|
||||
(t) =>
|
||||
t.id !== task.id &&
|
||||
t.scheduledDate &&
|
||||
formatDateToISO(new Date(t.scheduledDate)) ===
|
||||
formatDateToISO(date) &&
|
||||
t.startTime === slot,
|
||||
);
|
||||
const dateStr = formatDateToISO(date);
|
||||
const [h, m] = slot.split(":").map(Number);
|
||||
const slotStart = h * 60 + m;
|
||||
const slotEnd = slotStart + taskDuration;
|
||||
|
||||
// Check other tasks (duration-aware overlap)
|
||||
const taskConflict = tasksToCheck.some((t) => {
|
||||
if (t.id === task.id || !t.startTime || t.completed) return false;
|
||||
if (t.parentTaskId) return false;
|
||||
const tDateStr = t.scheduledDate
|
||||
? (typeof t.scheduledDate === "string" ? t.scheduledDate.substring(0, 10) : formatDateToISO(new Date(t.scheduledDate)))
|
||||
: null;
|
||||
if (tDateStr !== dateStr) return false;
|
||||
const [th, tm] = t.startTime.split(":").map(Number);
|
||||
const tStart = th * 60 + tm;
|
||||
const tEnd = tStart + (t.duration || effectiveCellDuration);
|
||||
return slotStart < tEnd && slotEnd > tStart;
|
||||
});
|
||||
if (taskConflict) return true;
|
||||
|
||||
// Check calendar events
|
||||
const [h, m] = slot.split(":").map(Number);
|
||||
const slotStart = new Date(date);
|
||||
slotStart.setHours(h, m, 0, 0);
|
||||
const slotEnd = new Date(slotStart);
|
||||
slotEnd.setMinutes(slotEnd.getMinutes() + effectiveCellDuration);
|
||||
const slotStartDate = new Date(date);
|
||||
slotStartDate.setHours(h, m, 0, 0);
|
||||
const slotEndDate = new Date(slotStartDate);
|
||||
slotEndDate.setMinutes(slotEndDate.getMinutes() + taskDuration);
|
||||
|
||||
return dailyEvents.some((event) => {
|
||||
const eventStart = new Date(event.startTime);
|
||||
const eventEnd = new Date(event.endTime);
|
||||
return slotStart < eventEnd && slotEnd > eventStart;
|
||||
return slotStartDate < eventEnd && slotEndDate > eventStart;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user