l-min-components 1.6.1222 → 1.6.1224

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "l-min-components",
3
- "version": "1.6.1222",
3
+ "version": "1.6.1224",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src/assets",
@@ -1,5 +1,6 @@
1
1
  import useAxios from "axios-hooks";
2
- import { useCallback, useEffect, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import sound from "./new-notification-7-210334.mp3";
3
4
 
4
5
  /**
5
6
  * Represents the details of the last message in a chat room overview.
@@ -268,6 +269,20 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
268
269
  chats: {},
269
270
  });
270
271
 
272
+ // Memoize the notification sound object
273
+ const notificationSound = useMemo(() => {
274
+ if (typeof window !== "undefined" && typeof Audio !== "undefined") {
275
+ try {
276
+ // Assuming the sound file is in the public folder
277
+ return new Audio(sound);
278
+ } catch (e) {
279
+ console.error("Error creating notification Audio object:", e);
280
+ return null;
281
+ }
282
+ }
283
+ return null;
284
+ }, []); // Empty dependency array ensures it's created only once
285
+
271
286
  // get room grouped by course list
272
287
  const getMessageRoomsByCourses = async (nextPage, once = false) => {
273
288
  if (!selectedAccount) return;
@@ -348,48 +363,9 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
348
363
  // --- End Find latest message ID ---
349
364
 
350
365
  setState((prevState) => {
351
- let unreadCountToSubtract = 0;
352
-
353
- // --- Update roomsByCourses ---
354
- const updatedRoomsByCourses = prevState.roomsByCourses.map(
355
- (courseGroup) => {
356
- // Find the room within this course group
357
- const roomIndex = courseGroup.rooms.findIndex(
358
- (room) => room.id === roomId
359
- );
360
-
361
- if (roomIndex !== -1) {
362
- // Found the room in this course group
363
- const targetRoom = courseGroup.rooms[roomIndex];
364
- unreadCountToSubtract = targetRoom.unread_count; // Store the count before resetting
365
-
366
- // Create a new rooms array with the updated room
367
- const updatedRooms = [
368
- ...courseGroup.rooms.slice(0, roomIndex),
369
- { ...targetRoom, unread_count: 0 }, // Reset unread count for the specific room
370
- ...courseGroup.rooms.slice(roomIndex + 1),
371
- ];
372
-
373
- // Return a new course group object with updated total count and rooms
374
- return {
375
- ...courseGroup,
376
- // Ensure total_unread_count doesn't go below zero
377
- total_unread_count: Math.max(
378
- 0,
379
- courseGroup.total_unread_count - unreadCountToSubtract
380
- ),
381
- rooms: updatedRooms,
382
- };
383
- }
384
-
385
- // If the room wasn't in this group, return the group unchanged
386
- return courseGroup;
387
- }
388
- );
389
- // --- End Update roomsByCourses ---
390
-
391
- // --- Update chats ---
366
+ // --- Update chats ONLY ---
392
367
  // Retrieve existing date groups directly from the array mapped to roomId
368
+ // Count updates are now handled by readRoomMessages
393
369
  const existingDateGroups = prevState.chats[roomId] || [];
394
370
  const allDateGroups = [...existingDateGroups, ...newDateGroups];
395
371
 
@@ -425,10 +401,10 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
425
401
  // Optional: Sort the date groups themselves if needed (e.g., chronologically)
426
402
  // finalDateGroups.sort((a, b) => /* comparison logic based on date */);
427
403
 
428
- // --- Return combined state update ---
404
+ // --- Return combined state update (only updating chats here) ---
429
405
  return {
430
406
  ...prevState,
431
- roomsByCourses: updatedRoomsByCourses, // Include the updated course/room list
407
+ // roomsByCourses is NOT updated here anymore
432
408
  chats: {
433
409
  ...prevState.chats,
434
410
  // Update the structure: Map roomId directly to the array of finalDateGroups
@@ -443,19 +419,79 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
443
419
  latestMessageIdFromFetch?.id && // Optional chaining for safety
444
420
  !latestMessageIdFromFetch?.is_read // Optional chaining for safety
445
421
  ) {
446
- await readRoomMessages(latestMessageIdFromFetch.id); // Pass only the ID
422
+ // Pass both message ID and room ID to readRoomMessages
423
+ await readRoomMessages({
424
+ latestMessageId: latestMessageIdFromFetch.id,
425
+ roomId: roomId,
426
+ });
447
427
  }
448
428
 
449
429
  // Pass roomId correctly in the recursive call
450
430
  if (responseData.next) getIndividualChats(responseData.next, roomId);
451
431
  };
452
432
 
453
- // read messages (using the latest message ID passed)
454
- const readRoomMessages = async (latestMessageId) => {
455
- // Assuming the API uses the latest message ID directly in the path as defined
456
- return await request({
457
- url: `/notify/v1/enterprise/chats/${latestMessageId}/read_message/`,
458
- });
433
+ // read messages (using the latest message ID passed) and update counts
434
+ const readRoomMessages = async ({ latestMessageId, roomId }) => {
435
+ // 1. Make the API call to mark as read
436
+ try {
437
+ await request({
438
+ url: `/notify/v1/enterprise/chats/${latestMessageId}/read_message/`,
439
+ });
440
+
441
+ // 2. If API call is successful, update the local state counts
442
+ setState((prevState) => {
443
+ let unreadCountToSubtract = 0;
444
+
445
+ const updatedRoomsByCourses = prevState.roomsByCourses.map(
446
+ (courseGroup) => {
447
+ const roomIndex = courseGroup.rooms.findIndex(
448
+ (room) => room.id === roomId
449
+ );
450
+
451
+ if (roomIndex !== -1) {
452
+ const targetRoom = courseGroup.rooms[roomIndex];
453
+ // Store the count *before* resetting, only if it's positive
454
+ unreadCountToSubtract = Math.max(0, targetRoom.unread_count);
455
+
456
+ if (unreadCountToSubtract > 0) {
457
+ // Only update if there were unread messages
458
+ const updatedRooms = [
459
+ ...courseGroup.rooms.slice(0, roomIndex),
460
+ { ...targetRoom, unread_count: 0 }, // Reset count
461
+ ...courseGroup.rooms.slice(roomIndex + 1),
462
+ ];
463
+
464
+ return {
465
+ ...courseGroup,
466
+ total_unread_count: Math.max(
467
+ 0, // Ensure total doesn't go below zero
468
+ courseGroup.total_unread_count - unreadCountToSubtract
469
+ ),
470
+ rooms: updatedRooms,
471
+ };
472
+ }
473
+ }
474
+ // If room not found or no unread messages, return group unchanged
475
+ return courseGroup;
476
+ }
477
+ );
478
+
479
+ // Only return updated state if changes were actually made
480
+ if (unreadCountToSubtract > 0) {
481
+ return {
482
+ ...prevState,
483
+ roomsByCourses: updatedRoomsByCourses,
484
+ };
485
+ } else {
486
+ // No change needed, return previous state
487
+ return prevState;
488
+ }
489
+ });
490
+ } catch (error) {
491
+ console.error("Failed to mark messages as read:", error);
492
+ // Optionally handle the error (e.g., show a notification)
493
+ // We don't update the state counts if the API call fails
494
+ }
459
495
  };
460
496
 
461
497
  // sending messages
@@ -598,7 +634,11 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
598
634
  (async () => {
599
635
  await getMessageRoomsByCourses();
600
636
  // Example: Fetch initial chat for a specific room if needed on load
601
- // await getIndividualChats(null, "some-initial-room-id");
637
+ // await getIndividualChats(null, "5be9b48281ac4c2885d3b719654ed59d");
638
+ // await readRoomMessages({
639
+ // latestMessageId: "57e31128214a4269be8b9e3bb18495c4",
640
+ // roomId: "5be9b48281ac4c2885d3b719654ed59d",
641
+ // });
602
642
  })();
603
643
  }, [selectedAccount?.id]); // Rerun when selectedAccount changes
604
644
 
@@ -664,8 +704,10 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
664
704
  date: getLocalDateString(webSocketData.created_at),
665
705
  };
666
706
 
667
- // --- Update State ---
707
+ // --- Update State & Play Sound ---
668
708
  setState((prevState) => {
709
+ let messageWasAdded = false; // Flag to track if the message is actually added
710
+
669
711
  // --- Update chats state ---
670
712
  const currentChatHistory = prevState.chats[roomId] || [];
671
713
  let updatedChatHistory = [...currentChatHistory];
@@ -679,14 +721,16 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
679
721
  // "today" group exists
680
722
  const todayGroup = updatedChatHistory[todayGroupIndex];
681
723
  // Avoid adding duplicate messages if WS sends what we already added via sendMessage response
682
- if (
683
- !todayGroup.messages.some((msg) => msg.id === newChatMessage.id)
684
- ) {
724
+ const isDuplicate = todayGroup.messages.some(
725
+ (msg) => msg.id === newChatMessage.id
726
+ );
727
+ if (!isDuplicate) {
685
728
  const updatedTodayGroup = {
686
729
  ...todayGroup,
687
730
  messages: [...todayGroup.messages, newChatMessage], // Add message
688
731
  };
689
732
  updatedChatHistory.splice(todayGroupIndex, 1, updatedTodayGroup); // Replace group
733
+ messageWasAdded = true; // Mark as added
690
734
  }
691
735
  } else {
692
736
  // "today" group doesn't exist, create it and prepend
@@ -696,8 +740,30 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
696
740
  };
697
741
  // Prepend to maintain reverse chronological order of groups
698
742
  updatedChatHistory = [newTodayGroup, ...updatedChatHistory];
743
+ messageWasAdded = true; // Mark as added (since it's a new group)
699
744
  }
700
745
 
746
+ // --- Play sound if a new message from another user was added ---
747
+ // --- Play sound if a new message from another user was added ---
748
+ if (
749
+ messageWasAdded &&
750
+ !newChatMessage.user_message &&
751
+ notificationSound
752
+ ) {
753
+ // Reset playback time in case it's played again quickly
754
+ notificationSound.currentTime = 0;
755
+ notificationSound.play().catch((e) => {
756
+ // Log error only if it's not the expected NotAllowedError
757
+ if (e.name !== "NotAllowedError") {
758
+ console.error("Error playing notification sound:", e);
759
+ } else {
760
+ // Optionally log that playback was blocked initially
761
+ // console.log("Audio playback blocked until user interaction.");
762
+ }
763
+ });
764
+ }
765
+ // --- End Play Sound ---
766
+
701
767
  const updatedChats = {
702
768
  ...prevState.chats,
703
769
  [roomId]: updatedChatHistory,
@@ -750,6 +816,7 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
750
816
  });
751
817
  }
752
818
  });
819
+
753
820
  return () => socket.close();
754
821
  }, [selectedAccount?.id]);
755
822
 
@@ -757,7 +824,13 @@ const useMessageKit = (affiliatesActive, selectedAccount, affiliateAccount) => {
757
824
  // send messages to account based on account type
758
825
 
759
826
  // Return the state and potentially the functions if they need to be called externally
760
- return { state, getIndividualChats, getMessageRoomsByCourses, sendMessage }; // Ensure sendMessage is returned
827
+ return {
828
+ state,
829
+ getIndividualChats,
830
+ getMessageRoomsByCourses,
831
+ sendMessage,
832
+ readRoomMessages,
833
+ };
761
834
  };
762
835
 
763
836
  export default useMessageKit;