Skip to content

Commit 1f33dac

Browse files
committed
Refactor task handling in WithChallengeTaskClusters to support multiple task updates and improve state management. Update dispatch logic in Task service for better task notification handling.
1 parent 7d7dcce commit 1f33dac

2 files changed

Lines changed: 186 additions & 92 deletions

File tree

src/components/HOCs/WithChallengeTaskClusters/WithChallengeTaskClusters.jsx

Lines changed: 100 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
} from "../../../services/Task/BoundedTask";
2323
import {
2424
receiveTasks,
25-
simulatedEntities,
2625
subscribeToAllTasks,
2726
subscribeToChallengeTaskMessages,
2827
unsubscribeFromAllTasks,
@@ -46,6 +45,7 @@ export const WithChallengeTaskClusters = function (
4645
) {
4746
return class extends Component {
4847
_isMounted = false;
48+
componentHandle = `challengeTaskClusters_${Math.random().toString(36).substring(2, 15)}`;
4949

5050
state = {
5151
loading: false,
@@ -236,9 +236,7 @@ export const WithChallengeTaskClusters = function (
236236

237237
const { dispatch, challengeId } = this.props;
238238
if (challengeId) {
239-
// Subscribe to challenge-specific task updates
240239
subscribeToChallengeTaskMessages(dispatch, challengeId);
241-
// Also subscribe to all tasks to catch updates with our custom handler
242240
subscribeToAllTasks(this.handleChallengeTaskUpdate, `${this.componentHandle}_challenge`);
243241
} else {
244242
subscribeToAllTasks(this.handleGlobalTaskUpdate, this.componentHandle);
@@ -247,83 +245,130 @@ export const WithChallengeTaskClusters = function (
247245

248246
handleGlobalTaskUpdate = (messageObject) => {
249247
const task = messageObject?.data?.task;
248+
const tasks = messageObject?.data?.tasks;
250249
const messageType = messageObject?.messageType;
251250

252251
if (messageType === "task-claimed" && messageObject?.data?.byUser?.userId) {
253252
const updatedTask = {
254253
...task,
255254
lockedBy: messageObject.data.byUser.userId,
256-
lockedAt: new Date().toISOString(),
257255
};
258256
if (this.isTaskInCurrentView(updatedTask)) {
259257
this.updateTaskInClusters(updatedTask);
260258
}
259+
} else if (messageType === "tasks-claimed" && messageObject?.data?.byUser?.userId && tasks) {
260+
const updatedTasks = tasks.map((task) => ({
261+
...task,
262+
lockedBy: messageObject.data.byUser.userId,
263+
}));
264+
265+
const tasksInView = updatedTasks.filter((task) => this.isTaskInCurrentView(task));
266+
if (tasksInView.length > 0) {
267+
this.updateTaskInClusters(tasksInView);
268+
}
261269
} else if (messageType === "task-released") {
262270
const updatedTask = {
263271
...task,
264272
lockedBy: null,
265-
lockedAt: null,
266273
};
267274
if (this.isTaskInCurrentView(updatedTask)) {
268275
this.updateTaskInClusters(updatedTask);
269276
}
277+
} else if (messageType === "tasks-released" && tasks) {
278+
const updatedTasks = tasks.map((task) => ({
279+
...task,
280+
lockedBy: null,
281+
}));
282+
283+
const tasksInView = updatedTasks.filter((task) => this.isTaskInCurrentView(task));
284+
if (tasksInView.length > 0) {
285+
this.updateTaskInClusters(tasksInView);
286+
}
270287
} else if (task && this.isTaskInCurrentView(task)) {
271288
this.updateTaskInClusters(task);
289+
} else if (tasks) {
290+
const tasksInView = tasks.filter((task) => this.isTaskInCurrentView(task));
291+
if (tasksInView.length > 0) {
292+
this.updateTaskInClusters(tasksInView);
293+
}
272294
}
273295
};
274296

275297
handleChallengeTaskUpdate = async (messageObject) => {
298+
const task = messageObject?.data?.task;
276299
const tasks = messageObject?.data?.tasks;
277300
const messageType = messageObject?.messageType;
278301

279-
if (!tasks) return;
302+
// Handle both single task and multiple task messages
303+
const tasksToProcess = tasks || (task ? [task] : []);
280304

281-
if (messageType === "tasks-claimed" && messageObject?.data?.byUser?.userId) {
282-
const updatedTasks = tasks.map((task) => ({
305+
if (tasksToProcess.length === 0) return;
306+
307+
if (messageType === "task-claimed" && messageObject?.data?.byUser?.userId) {
308+
const updatedTasks = tasksToProcess.map((task) => ({
283309
...task,
284310
lockedBy: messageObject.data.byUser.userId,
285-
lockedAt: new Date().toISOString(),
311+
}));
312+
this.updateTaskInClusters(updatedTasks);
313+
} else if (messageType === "tasks-claimed" && messageObject?.data?.byUser?.userId) {
314+
const updatedTasks = tasksToProcess.map((task) => ({
315+
...task,
316+
lockedBy: messageObject.data.byUser.userId,
317+
}));
318+
this.updateTaskInClusters(updatedTasks);
319+
} else if (messageType === "task-released") {
320+
const updatedTasks = tasksToProcess.map((task) => ({
321+
...task,
322+
lockedBy: null,
286323
}));
287324
this.updateTaskInClusters(updatedTasks);
288325
} else if (messageType === "tasks-released") {
289-
const updatedTasks = tasks.map((task) => ({
326+
const updatedTasks = tasksToProcess.map((task) => ({
290327
...task,
291328
lockedBy: null,
292-
lockedAt: null,
293329
}));
294330
this.updateTaskInClusters(updatedTasks);
295331
} else {
296-
this.updateTaskInClusters(tasks);
332+
this.updateTaskInClusters(tasksToProcess);
297333
}
298334
};
299335

300336
updateTaskInClusters = async (updatedTasks) => {
301337
if (!Array.isArray(updatedTasks)) {
302338
updatedTasks = [updatedTasks];
303339
}
340+
updatedTasks = updatedTasks.filter((task) => task?.id);
304341

305-
updatedTasks.forEach((updatedTask) => {
306-
if (!updatedTask?.id) {
307-
return;
308-
}
309-
const { dispatch } = this.props;
310-
if (dispatch) {
311-
dispatch(receiveTasks(simulatedEntities(updatedTask)));
312-
}
342+
if (updatedTasks.length === 0) {
343+
return;
344+
}
313345

314-
this.setState((prevState) => {
315-
const clusters = Array.isArray(prevState.clusters)
316-
? [...prevState.clusters]
317-
: prevState.clusters;
346+
const { dispatch } = this.props;
347+
if (dispatch && updatedTasks.length > 0) {
348+
const tasksById = {};
349+
updatedTasks.forEach((task) => {
350+
tasksById[task.id] = task;
351+
});
318352

319-
if (Array.isArray(clusters)) {
320-
const taskIndex = clusters.findIndex(
321-
(cluster) => cluster.id === updatedTask.id || cluster.taskId === updatedTask.id,
322-
);
353+
dispatch(receiveTasks({ tasks: tasksById }));
354+
}
355+
356+
this.setState((prevState) => {
357+
const clusters = Array.isArray(prevState.clusters)
358+
? [...prevState.clusters]
359+
: prevState.clusters;
360+
361+
if (Array.isArray(clusters)) {
362+
const taskMap = new Map(updatedTasks.map((task) => [task.id, task]));
323363

324-
if (taskIndex !== -1) {
325-
clusters[taskIndex] = {
326-
...clusters[taskIndex],
364+
for (let i = 0; i < clusters.length; i++) {
365+
const cluster = clusters[i];
366+
const clusterId = cluster.id || cluster.taskId;
367+
const updatedTask = taskMap.get(clusterId);
368+
369+
if (updatedTask) {
370+
clusters[i] = {
371+
...cluster,
327372
status: updatedTask.status,
328373
priority: updatedTask.priority,
329374
reviewStatus: updatedTask.reviewStatus,
@@ -332,27 +377,30 @@ export const WithChallengeTaskClusters = function (
332377
...updatedTask,
333378
};
334379
}
335-
} else if (typeof clusters === "object") {
336-
let found = false;
337-
Object.keys(clusters).forEach((key) => {
338-
const cluster = clusters[key];
339-
if (cluster.id === updatedTask.id || cluster.taskId === updatedTask.id) {
340-
found = true;
341-
clusters[key] = {
342-
...cluster,
343-
status: updatedTask.status,
344-
priority: updatedTask.priority,
345-
reviewStatus: updatedTask.reviewStatus,
346-
lockedBy: updatedTask.lockedBy,
347-
lockedAt: updatedTask.lockedAt,
348-
...updatedTask,
349-
};
350-
}
351-
});
352380
}
381+
} else if (typeof clusters === "object") {
382+
const taskMap = new Map(updatedTasks.map((task) => [task.id, task]));
353383

354-
return { clusters };
355-
});
384+
Object.keys(clusters).forEach((key) => {
385+
const cluster = clusters[key];
386+
const clusterId = cluster.id || cluster.taskId;
387+
const updatedTask = taskMap.get(clusterId);
388+
389+
if (updatedTask) {
390+
clusters[key] = {
391+
...cluster,
392+
status: updatedTask.status,
393+
priority: updatedTask.priority,
394+
reviewStatus: updatedTask.reviewStatus,
395+
lockedBy: updatedTask.lockedBy,
396+
lockedAt: updatedTask.lockedAt,
397+
...updatedTask,
398+
};
399+
}
400+
});
401+
}
402+
403+
return { clusters };
356404
});
357405
};
358406

@@ -364,7 +412,6 @@ export const WithChallengeTaskClusters = function (
364412
const bounds = this.props.criteria.boundingBox;
365413
const [lng, lat] = task.location.coordinates;
366414

367-
// Parse bounds string (format: "west,south,east,north")
368415
const boundsArray = bounds.split(",").map(Number);
369416
if (boundsArray.length !== 4) return false;
370417

@@ -386,8 +433,8 @@ export const WithChallengeTaskClusters = function (
386433
}
387434

388435
debouncedFetchClusters = _debounce((showAsClusters) => {
389-
if (this._isMounted) this.fetchUpdatedClusters(showAsClusters), 800;
390-
});
436+
if (this._isMounted) this.fetchUpdatedClusters(showAsClusters);
437+
}, 800);
391438

392439
componentDidUpdate(prevProps) {
393440
// Check if search query has changed

0 commit comments

Comments
 (0)