feat: implement live-sync for tasks, workspace note sharing, and document locking system
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 53s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 53s
This commit is contained in:
1 parent
dccf1a91e3
commit
84e0b6a4bd
10 files changed
+1773
-110
No files matched your search
@@ -96,6 +96,71 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
loadData();
|
||||
}, [refreshTrigger, selectedListId]);
|
||||
|
||||
// Live-Sync WebSocket listener for tasks
|
||||
useEffect(() => {
|
||||
const handleWs = (e: any) => {
|
||||
const msg = e.detail;
|
||||
if (!msg || !msg.event) return;
|
||||
|
||||
if (msg.event === 'TASK_CREATED') {
|
||||
const created = msg.payload as Thought;
|
||||
if (
|
||||
created &&
|
||||
(created.status === 'converted' ||
|
||||
created.kanbanStatus ||
|
||||
created.taskListId ||
|
||||
created.isCompleted !== undefined)
|
||||
) {
|
||||
setTasks((prev) => {
|
||||
if (prev.some((t) => t.id === created.id)) return prev;
|
||||
if (selectedListId !== 'all' && created.taskListId !== selectedListId) return prev;
|
||||
return [created, ...prev];
|
||||
});
|
||||
onRefreshStats();
|
||||
}
|
||||
} else if (msg.event === 'TASK_UPDATED') {
|
||||
const updated = msg.payload as Thought;
|
||||
if (updated && updated.id) {
|
||||
setTasks((prev) => {
|
||||
const exists = prev.some((t) => t.id === updated.id);
|
||||
if (!exists) {
|
||||
if (
|
||||
(updated.status === 'converted' ||
|
||||
updated.kanbanStatus ||
|
||||
updated.taskListId ||
|
||||
updated.isCompleted !== undefined) &&
|
||||
(selectedListId === 'all' || updated.taskListId === selectedListId)
|
||||
) {
|
||||
return [updated, ...prev];
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
if (selectedListId !== 'all' && updated.taskListId !== selectedListId) {
|
||||
return prev.filter((t) => t.id !== updated.id);
|
||||
}
|
||||
return prev.map((t) => {
|
||||
if (t.id !== updated.id) return t;
|
||||
return {
|
||||
...updated,
|
||||
notes: activeNotesTaskId === updated.id ? t.notes : updated.notes,
|
||||
};
|
||||
});
|
||||
});
|
||||
onRefreshStats();
|
||||
}
|
||||
} else if (msg.event === 'TASK_DELETED') {
|
||||
const deletedId = typeof msg.payload === 'string' ? msg.payload : msg.payload?.id;
|
||||
if (deletedId) {
|
||||
setTasks((prev) => prev.filter((t) => t.id !== deletedId));
|
||||
onRefreshStats();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('mindsift:ws', handleWs);
|
||||
return () => window.removeEventListener('mindsift:ws', handleWs);
|
||||
}, [selectedListId, activeNotesTaskId, onRefreshStats]);
|
||||
|
||||
const handleToggleDone = async (task: Thought) => {
|
||||
triggerHaptic(15);
|
||||
const nextState = !task.isCompleted;
|
||||
|
||||
Reference in new issue
Block a user