l-min-components 1.6.1245 → 1.6.1248
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/hooks/messaging-kit/index.jsx +192 -103
package/package.json
CHANGED
|
@@ -279,6 +279,7 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
279
279
|
const [state, setState] = useState({
|
|
280
280
|
roomsByCourses: [],
|
|
281
281
|
chats: {},
|
|
282
|
+
loadingRoomIds: new Set(), // Track which rooms are currently loading
|
|
282
283
|
});
|
|
283
284
|
// State for rooms that should be automatically marked as read
|
|
284
285
|
const [autoReadRoomIds, setAutoReadRoomIds] = useState(() => new Set());
|
|
@@ -370,119 +371,161 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
370
371
|
const getIndividualChats = async (nextPage, roomId, limit = 1000) => {
|
|
371
372
|
if (!selectedAccount) return;
|
|
372
373
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
_account: selectedAccount.id,
|
|
379
|
-
room_id: roomId,
|
|
380
|
-
limit,
|
|
381
|
-
},
|
|
382
|
-
});
|
|
383
|
-
}
|
|
374
|
+
// Add roomId to loading state
|
|
375
|
+
setState((prevState) => ({
|
|
376
|
+
...prevState,
|
|
377
|
+
loadingRoomIds: new Set([...prevState.loadingRoomIds, roomId]),
|
|
378
|
+
}));
|
|
384
379
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
},
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
if (!response?.data) return;
|
|
380
|
+
try {
|
|
381
|
+
let response;
|
|
382
|
+
if (String(selectedAccount.type).toLowerCase() === "enterprise") {
|
|
383
|
+
response = await request({
|
|
384
|
+
url: nextPage || "/notify/v1/enterprise/chats/",
|
|
385
|
+
params: {
|
|
386
|
+
_account: selectedAccount.id,
|
|
387
|
+
room_id: roomId,
|
|
388
|
+
limit,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
}
|
|
401
392
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
393
|
+
if (
|
|
394
|
+
String(selectedAccount.type).toLowerCase() === "instructor" &&
|
|
395
|
+
affiliateAccount
|
|
396
|
+
// &&
|
|
397
|
+
// affiliatesActive
|
|
398
|
+
) {
|
|
399
|
+
response = await request({
|
|
400
|
+
url: nextPage || `/notify/v1/instructor/${affiliateAccount}/chats/`,
|
|
401
|
+
params: {
|
|
402
|
+
_account: selectedAccount.id,
|
|
403
|
+
room_id: roomId,
|
|
404
|
+
limit,
|
|
405
|
+
},
|
|
406
|
+
});
|
|
415
407
|
}
|
|
416
|
-
}
|
|
417
|
-
// --- End Find latest message ID ---
|
|
418
408
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
409
|
+
if (String(selectedAccount.type).toLowerCase() === "personal") {
|
|
410
|
+
response = await request({
|
|
411
|
+
url: nextPage || `/notify/v1/chats/`,
|
|
412
|
+
params: {
|
|
413
|
+
_account: selectedAccount.id,
|
|
414
|
+
room_id: roomId,
|
|
415
|
+
limit,
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (!response?.data) return;
|
|
420
|
+
|
|
421
|
+
/** @type {MessageApiResponseData} */
|
|
422
|
+
const responseData = response.data;
|
|
423
|
+
const { results: newDateGroups } = responseData;
|
|
424
|
+
|
|
425
|
+
// --- Find the latest message ID from the current fetch ---
|
|
426
|
+
let latestMessageIdFromFetch = null;
|
|
427
|
+
if (newDateGroups && newDateGroups.length > 0) {
|
|
428
|
+
const allNewMessages = newDateGroups.flatMap((group) => group.messages);
|
|
429
|
+
if (allNewMessages.length > 0) {
|
|
430
|
+
allNewMessages.sort(
|
|
431
|
+
(a, b) => new Date(b.created_at) - new Date(a.created_at)
|
|
440
432
|
);
|
|
433
|
+
latestMessageIdFromFetch = allNewMessages[0];
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// --- End Find latest message ID ---
|
|
437
|
+
|
|
438
|
+
setState((prevState) => {
|
|
439
|
+
// --- Update chats ONLY ---
|
|
440
|
+
// Retrieve existing date groups directly from the array mapped to roomId
|
|
441
|
+
// Count updates are now handled by readRoomMessages
|
|
442
|
+
const existingDateGroups = prevState.chats[roomId] || [];
|
|
443
|
+
const allDateGroups = [...existingDateGroups, ...newDateGroups];
|
|
444
|
+
|
|
445
|
+
// Group messages by date and de-duplicate messages within each date using their ID (existing logic)
|
|
446
|
+
const messagesGroupedByDate = {};
|
|
447
|
+
allDateGroups.forEach((dateGroup) => {
|
|
448
|
+
if (!messagesGroupedByDate[dateGroup.date]) {
|
|
449
|
+
// Use a Map for efficient de-duplication by message ID
|
|
450
|
+
messagesGroupedByDate[dateGroup.date] = {
|
|
451
|
+
date: dateGroup.date, // Store the date string
|
|
452
|
+
messagesMap: new Map(),
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
dateGroup.messages.forEach((message) => {
|
|
456
|
+
messagesGroupedByDate[dateGroup.date].messagesMap.set(
|
|
457
|
+
message.id,
|
|
458
|
+
message
|
|
459
|
+
);
|
|
460
|
+
});
|
|
441
461
|
});
|
|
442
|
-
});
|
|
443
462
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
463
|
+
// Reconstruct the final array of date groups with unique messages
|
|
464
|
+
const finalDateGroups = Object.values(messagesGroupedByDate).map(
|
|
465
|
+
(group) => ({
|
|
466
|
+
date: group.date,
|
|
467
|
+
// Convert Map values back to an array and sort messages by creation time
|
|
468
|
+
messages: Array.from(group.messagesMap.values()).sort(
|
|
469
|
+
(a, b) => new Date(a.created_at) - new Date(b.created_at)
|
|
470
|
+
),
|
|
471
|
+
})
|
|
472
|
+
);
|
|
454
473
|
|
|
455
|
-
|
|
456
|
-
|
|
474
|
+
// Optional: Sort the date groups themselves if needed (e.g., chronologically)
|
|
475
|
+
// finalDateGroups.sort((a, b) => /* comparison logic based on date */);
|
|
457
476
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
477
|
+
// --- Return combined state update (only updating chats here) ---
|
|
478
|
+
return {
|
|
479
|
+
...prevState,
|
|
480
|
+
// roomsByCourses is NOT updated here anymore
|
|
481
|
+
chats: {
|
|
482
|
+
...prevState.chats,
|
|
483
|
+
// Update the structure: Map roomId directly to the array of finalDateGroups
|
|
484
|
+
[roomId]: finalDateGroups,
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
});
|
|
469
488
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
489
|
+
// Call readRoomMessages only on the first page fetch, if a latest message ID was found and is its not read
|
|
490
|
+
if (
|
|
491
|
+
!nextPage &&
|
|
492
|
+
latestMessageIdFromFetch?.id && // Optional chaining for safety
|
|
493
|
+
!latestMessageIdFromFetch?.is_read // Optional chaining for safety
|
|
494
|
+
) {
|
|
495
|
+
// Pass both message ID and room ID to readRoomMessages
|
|
496
|
+
await readRoomMessages({
|
|
497
|
+
latestMessageId: latestMessageIdFromFetch.id,
|
|
498
|
+
roomId: roomId,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Only remove from loading state if this is the last page or there was an error
|
|
503
|
+
if (!responseData.next) {
|
|
504
|
+
setState((prevState) => {
|
|
505
|
+
const updatedLoadingRoomIds = new Set(prevState.loadingRoomIds);
|
|
506
|
+
updatedLoadingRoomIds.delete(roomId);
|
|
507
|
+
return {
|
|
508
|
+
...prevState,
|
|
509
|
+
loadingRoomIds: updatedLoadingRoomIds,
|
|
510
|
+
};
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Pass roomId correctly in the recursive call
|
|
515
|
+
if (responseData.next) getIndividualChats(responseData.next, roomId);
|
|
516
|
+
return responseData;
|
|
517
|
+
} catch (error) {
|
|
518
|
+
// Remove from loading state in case of error
|
|
519
|
+
setState((prevState) => {
|
|
520
|
+
const updatedLoadingRoomIds = new Set(prevState.loadingRoomIds);
|
|
521
|
+
updatedLoadingRoomIds.delete(roomId);
|
|
522
|
+
return {
|
|
523
|
+
...prevState,
|
|
524
|
+
loadingRoomIds: updatedLoadingRoomIds,
|
|
525
|
+
};
|
|
480
526
|
});
|
|
527
|
+
throw error; // Re-throw to allow error handling upstream
|
|
481
528
|
}
|
|
482
|
-
|
|
483
|
-
// Pass roomId correctly in the recursive call
|
|
484
|
-
if (responseData.next) getIndividualChats(responseData.next, roomId);
|
|
485
|
-
return responseData;
|
|
486
529
|
};
|
|
487
530
|
|
|
488
531
|
// read messages (using the latest message ID passed) and update counts
|
|
@@ -497,13 +540,16 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
497
540
|
if (
|
|
498
541
|
String(selectedAccount.type).toLowerCase() === "instructor" &&
|
|
499
542
|
affiliateAccount
|
|
500
|
-
// &&
|
|
501
|
-
// affiliatesActive
|
|
502
543
|
) {
|
|
503
544
|
await request({
|
|
504
545
|
url: `/notify/v1/instructor/${affiliateAccount}/chats/${latestMessageId}/read_message/`,
|
|
505
546
|
});
|
|
506
547
|
}
|
|
548
|
+
if (String(selectedAccount.type).toLowerCase() === "personal") {
|
|
549
|
+
await request({
|
|
550
|
+
url: `/notify/v1/chats/${latestMessageId}/read_message/`,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
507
553
|
// 2. If API call is successful, update the local state counts
|
|
508
554
|
setState((prevState) => {
|
|
509
555
|
let unreadCountToSubtract = 0;
|
|
@@ -618,6 +664,21 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
618
664
|
method: "Post",
|
|
619
665
|
});
|
|
620
666
|
}
|
|
667
|
+
if (selectedAccount.type.toLowerCase() === "personal") {
|
|
668
|
+
response = await request({
|
|
669
|
+
url: `/notify/v1/chats/`,
|
|
670
|
+
params: {
|
|
671
|
+
_account: selectedAccount.id,
|
|
672
|
+
course_id: courseId,
|
|
673
|
+
account_id: accountId,
|
|
674
|
+
},
|
|
675
|
+
data: {
|
|
676
|
+
text,
|
|
677
|
+
media,
|
|
678
|
+
},
|
|
679
|
+
method: "Post",
|
|
680
|
+
});
|
|
681
|
+
}
|
|
621
682
|
|
|
622
683
|
if (!response?.data) return; // Added optional chaining for safety
|
|
623
684
|
|
|
@@ -847,6 +908,13 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
847
908
|
method: "patch",
|
|
848
909
|
});
|
|
849
910
|
} // incomplete
|
|
911
|
+
|
|
912
|
+
if (selectedAccount.type.toLowerCase() === "personal") {
|
|
913
|
+
response = await request({
|
|
914
|
+
url: `/notify/v1/chats/${roomId}/change_pin_status/`,
|
|
915
|
+
method: "patch",
|
|
916
|
+
});
|
|
917
|
+
}
|
|
850
918
|
} catch (err) {
|
|
851
919
|
// Revert optimistic update on failure (optional, depends on desired UX)
|
|
852
920
|
// You might want to implement more specific error handling here
|
|
@@ -920,6 +988,12 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
920
988
|
method: "delete",
|
|
921
989
|
});
|
|
922
990
|
} // incomplete
|
|
991
|
+
if (selectedAccount.type.toLowerCase() === "personal") {
|
|
992
|
+
response = await request({
|
|
993
|
+
url: `/notify/v1/chats/${roomId}/`,
|
|
994
|
+
method: "delete",
|
|
995
|
+
});
|
|
996
|
+
}
|
|
923
997
|
} catch (err) {
|
|
924
998
|
console.error("Error deleting room:", err);
|
|
925
999
|
// Revert the optimistic update on error
|
|
@@ -957,12 +1031,25 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
957
1031
|
data,
|
|
958
1032
|
});
|
|
959
1033
|
}
|
|
1034
|
+
if (selectedAccount.type.toLowerCase() === "personal") {
|
|
1035
|
+
response = await request({
|
|
1036
|
+
url: `/notify/v1/chats/reports/`,
|
|
1037
|
+
method: "post",
|
|
1038
|
+
data,
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
960
1041
|
return response;
|
|
961
1042
|
};
|
|
962
1043
|
// Initial data fetch effect
|
|
963
1044
|
useEffect(() => {
|
|
964
1045
|
(async () => {
|
|
965
1046
|
await getMessageRoomsByCourses();
|
|
1047
|
+
// reportChat({
|
|
1048
|
+
// reasons: ["Verbal harassment"],
|
|
1049
|
+
// accountId: "24dbaeede1",
|
|
1050
|
+
// messageIds: ["438745c081564ee9aeb76ed29052bd4b"],
|
|
1051
|
+
// // others: "",
|
|
1052
|
+
// });
|
|
966
1053
|
// await deleteRoom("5be9b48281ac4c2885d3b719654ed59d");
|
|
967
1054
|
// await pinRoom("5be9b48281ac4c2885d3b719654ed59d");
|
|
968
1055
|
// Example: Fetch initial chat for a specific room if needed on load
|
|
@@ -1186,6 +1273,8 @@ const useMessageKit = (/*affiliatesActive*/) => {
|
|
|
1186
1273
|
pinRoom,
|
|
1187
1274
|
deleteRoom,
|
|
1188
1275
|
reportChat,
|
|
1276
|
+
// Helper method to check if a specific room is loading
|
|
1277
|
+
isRoomLoading: (roomId) => state.loadingRoomIds.has(roomId),
|
|
1189
1278
|
};
|
|
1190
1279
|
};
|
|
1191
1280
|
|