@samparkchat/sampark-web-chat 0.1.3 → 0.1.4

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.
Files changed (60) hide show
  1. package/package.json +1 -1
  2. package/sampark/sampark-chat/components/GroupVideoCall.js +7 -7
  3. package/sampark/sampark-chat/components/Headers/ChatHeader.d.ts +3 -0
  4. package/sampark/sampark-chat/components/Headers/ChatHeader.js +18 -10
  5. package/sampark/sampark-chat/components/Headers/GroupChatHeader.js +16 -8
  6. package/sampark/sampark-chat/components/Headers/HeaderPanel/CallDetailsPanel.d.ts +11 -1
  7. package/sampark/sampark-chat/components/Headers/HeaderPanel/CallDetailsPanel.js +127 -73
  8. package/sampark/sampark-chat/components/Headers/HeaderPanel/CallHistory.d.ts +7 -0
  9. package/sampark/sampark-chat/components/Headers/HeaderPanel/CallHistory.js +7 -2
  10. package/sampark/sampark-chat/components/Headers/HeaderPanel/GroupList.js +67 -8
  11. package/sampark/sampark-chat/components/Headers/SamparkHeader.d.ts +2 -14
  12. package/sampark/sampark-chat/components/Headers/SamparkHeader.js +33 -25
  13. package/sampark/sampark-chat/components/OnlineIndicator.d.ts +4 -0
  14. package/sampark/sampark-chat/components/OnlineIndicator.js +37 -3
  15. package/sampark/sampark-chat/components/ProfileModal.d.ts +7 -0
  16. package/sampark/sampark-chat/components/ProfileModal.js +370 -34
  17. package/sampark/sampark-chat/components/VideoCall.js +19 -11
  18. package/sampark/sampark-chat/components/bottomsheets/GroupBottomSheet.js +21 -10
  19. package/sampark/sampark-chat/components/lists/CommonList.d.ts +6 -0
  20. package/sampark/sampark-chat/components/lists/CommonList.js +98 -9
  21. package/sampark/sampark-chat/components/lists/UserInfo.d.ts +7 -0
  22. package/sampark/sampark-chat/components/lists/UserInfo.js +206 -10
  23. package/sampark/sampark-chat/components/lists/ViewParticipents.d.ts +6 -0
  24. package/sampark/sampark-chat/components/lists/ViewParticipents.js +523 -239
  25. package/sampark/sampark-chat/components/modals/CustomStatusModal.d.ts +10 -0
  26. package/sampark/sampark-chat/components/modals/CustomStatusModal.js +225 -0
  27. package/sampark/sampark-chat/components/modals/ProfileAvatar.d.ts +4 -0
  28. package/sampark/sampark-chat/components/modals/ProfileAvatar.js +3 -3
  29. package/sampark/sampark-chat/components/modals/UnbanRequestModal.d.ts +32 -0
  30. package/sampark/sampark-chat/components/modals/UnbanRequestModal.js +343 -0
  31. package/sampark/sampark-chat/models/ConfirmActionModal.d.ts +6 -0
  32. package/sampark/sampark-chat/models/ConfirmActionModal.js +39 -2
  33. package/sampark/sampark-chat/screens/PeerChatScreen.d.ts +3 -0
  34. package/sampark/sampark-chat/screens/PeerChatScreen.js +37 -31
  35. package/sampark/sampark-chat/screens/SamparkChatsScreen.js +675 -178
  36. package/sampark/sampark-chat/screens/groupChatScreen.d.ts +5 -0
  37. package/sampark/sampark-chat/screens/groupChatScreen.js +338 -39
  38. package/sampark/sampark-chat/sdk/client/GroupCall.d.ts +1 -0
  39. package/sampark/sampark-chat/sdk/client/GroupCall.js +29 -0
  40. package/sampark/sampark-chat/sdk/client/Groupchat.d.ts +139 -7
  41. package/sampark/sampark-chat/sdk/client/Groupchat.js +727 -50
  42. package/sampark/sampark-chat/sdk/client/PeerChat.d.ts +27 -0
  43. package/sampark/sampark-chat/sdk/client/PeerChat.js +74 -0
  44. package/sampark/sampark-chat/sdk/enum/ActionTypes.d.ts +2 -1
  45. package/sampark/sampark-chat/sdk/enum/ActionTypes.js +1 -0
  46. package/sampark/sampark-chat/sdk/interface/SamparkGroupChatService.d.ts +12 -0
  47. package/sampark/sampark-chat/sdk/types/BanParticipantRequest.d.ts +12 -0
  48. package/sampark/sampark-chat/sdk/types/BanParticipantRequest.js +15 -0
  49. package/sampark/sampark-chat/sdk/types/GetAllParticipantStatusesRequest.d.ts +9 -0
  50. package/sampark/sampark-chat/sdk/types/GetAllParticipantStatusesRequest.js +19 -0
  51. package/sampark/sampark-chat/sdk/types/MuteParticipantRequest.d.ts +12 -0
  52. package/sampark/sampark-chat/sdk/types/MuteParticipantRequest.js +15 -0
  53. package/sampark/sampark-chat/sdk/types/ProcessUnbanRequest.d.ts +13 -0
  54. package/sampark/sampark-chat/sdk/types/ProcessUnbanRequest.js +16 -0
  55. package/sampark/sampark-chat/sdk/types/SetParticipantApplicationDataRequest.d.ts +14 -0
  56. package/sampark/sampark-chat/sdk/types/SetParticipantApplicationDataRequest.js +19 -0
  57. package/sampark/sampark-chat/sdk/types/SubmitUnbanRequest.d.ts +12 -0
  58. package/sampark/sampark-chat/sdk/types/SubmitUnbanRequest.js +16 -0
  59. package/sampark/sampark-chat/theme/icons.d.ts +10 -0
  60. package/sampark/sampark-chat/theme/icons.js +4 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samparkchat/sampark-web-chat",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "main": "sampark/sampark-web-chat/index.js",
5
5
  "types": "sampark/sampark-web-chat/index.d.ts",
6
6
  "private": false,
@@ -2534,11 +2534,11 @@ var GroupVideoCall = function (_a) {
2534
2534
  React.createElement("div", { className: "control-button-wrapper" },
2535
2535
  React.createElement("button", { style: __assign(__assign({}, styles.controlButton), { color: cameraEnabled ? '#fff' : '#e50d0dff' }), onClick: toggleCamera },
2536
2536
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: cameraEnabled ? faVideo : faVideoSlash })),
2537
- React.createElement("span", { className: "custom-tooltip" }, cameraEnabled ? "Turn off camera" : "Turn on camera")),
2537
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, cameraEnabled ? "Turn off camera" : "Turn on camera")),
2538
2538
  React.createElement("div", { className: "control-button-wrapper" },
2539
2539
  React.createElement("button", { style: __assign(__assign({}, styles.controlButton), { color: micEnabled ? '#fff' : '#e50d0dff' }), onClick: toggleMic },
2540
2540
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: micEnabled ? faMicrophone : faMicrophoneSlash })),
2541
- React.createElement("span", { className: "custom-tooltip" }, micEnabled ? "Mute microphone" : "Unmute microphone")),
2541
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, micEnabled ? "Mute microphone" : "Unmute microphone")),
2542
2542
  React.createElement("div", { className: "control-button-wrapper" },
2543
2543
  React.createElement("button", { style: isScreenSharing ? __assign(__assign({}, styles.controlButton), styles.screenShareActive) : styles.controlButton, ref: screenShareButtonRef, onClick: function () {
2544
2544
  if (isScreenSharing) {
@@ -2556,25 +2556,25 @@ var GroupVideoCall = function (_a) {
2556
2556
  }
2557
2557
  } },
2558
2558
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: faDesktop })),
2559
- React.createElement("span", { className: "custom-tooltip" }, isScreenSharing ? "Screen share options" : "Start screen share")),
2559
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, isScreenSharing ? "Screen share options" : "Start screen share")),
2560
2560
  React.createElement("div", { className: "control-button-wrapper" },
2561
2561
  React.createElement("button", { style: styles.controlButton, onClick: function () {
2562
2562
  setIsMinimized(true);
2563
2563
  setWasDragged(false);
2564
2564
  } },
2565
2565
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: faCompress })),
2566
- React.createElement("span", { className: "custom-tooltip" }, "Minimize call")),
2566
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, "Minimize call")),
2567
2567
  React.createElement("div", { className: "control-button-wrapper" },
2568
2568
  React.createElement("button", { style: styles.controlButton, onClick: function () {
2569
2569
  setShowInvitePanel(true);
2570
2570
  setShowAvailableUsers(false);
2571
2571
  } },
2572
2572
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: faUserPlus })),
2573
- React.createElement("span", { className: "custom-tooltip" }, "Invite participants")),
2573
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, "Invite participants")),
2574
2574
  React.createElement("div", { className: "control-button-wrapper" },
2575
2575
  React.createElement("button", { style: __assign(__assign({}, styles.controlButton), styles.endCallButton), onClick: handleEndCall },
2576
2576
  React.createElement(FontAwesomeIcon, { style: { fontSize: '20px' }, icon: faPhoneSlash })),
2577
- React.createElement("span", { className: "custom-tooltip" }, "End call")))),
2577
+ React.createElement("span", { className: "custom-tooltip tooltip-top" }, "End call")))),
2578
2578
  showScreenSharePopup && (React.createElement("div", { style: styles.screenSharePopupOverlay, onClick: function () { return setShowScreenSharePopup(false); } },
2579
2579
  React.createElement("div", { style: __assign(__assign({}, styles.screenSharePopup), { top: popupPosition.top, left: popupPosition.left }), onClick: function (e) { return e.stopPropagation(); } },
2580
2580
  React.createElement("button", { style: styles.popupButton, onClick: function () {
@@ -3533,5 +3533,5 @@ var styles = {
3533
3533
  fontSize: "14px",
3534
3534
  },
3535
3535
  };
3536
- var inviteKeyframes = "\n/* Custom Tooltip Styling - Hide native tooltip and show custom one */\n.control-button-wrapper {\n position: relative;\n display: inline-block;\n}\n\n.control-button-wrapper .custom-tooltip {\n visibility: hidden;\n opacity: 0;\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n background-color: #000;\n color: #fff;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 12px;\n white-space: nowrap;\n z-index: 10000;\n pointer-events: none;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;\n}\n\n.control-button-wrapper .custom-tooltip::after {\n content: '';\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 6px solid transparent;\n border-top-color: #000;\n}\n\n.control-button-wrapper:hover .custom-tooltip {\n visibility: visible;\n opacity: 1;\n}\n\n@keyframes fadeIn {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n@keyframes slideInRight {\n 0% {\n transform: translateX(100%);\n opacity: 0;\n }\n 100% {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes slideDown {\n 0% {\n opacity: 0;\n transform: translateY(-12px) scale(0.95);\n }\n 100% {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes invitePulse {\n 0% {\n transform: scale(1.05);\n box-shadow: 0 0 20px rgba(16,185,129,0.4), inset 0 1px 0 rgba(255,255,255,0.1);\n }\n 50% {\n transform: scale(1.08);\n box-shadow: 0 0 30px rgba(16,185,129,0.6), inset 0 1px 0 rgba(255,255,255,0.2);\n }\n 100% {\n transform: scale(1.05);\n box-shadow: 0 0 20px rgba(16,185,129,0.4), inset 0 1px 0 rgba(255,255,255,0.1);\n }\n}\n\n@keyframes speakingPulse {\n 0% {\n transform: scale(1);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.6);\n }\n 50% {\n transform: scale(1.2);\n box-shadow: 0 0 20px rgba(16, 185, 129, 0.8);\n }\n 100% {\n transform: scale(1);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.6);\n }\n}\n\n@keyframes microphoneGreenBlink {\n 0% {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.2);\n text-shadow: 0 0 5px rgba(34, 197, 94, 0.6);\n box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);\n }\n 50% {\n color: #16a34a;\n background: rgba(34, 197, 94, 0.4);\n text-shadow: 0 0 10px rgba(34, 197, 94, 0.8);\n transform: scale(1.1);\n box-shadow: 0 0 15px rgba(34, 197, 94, 0.7);\n }\n 100% {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.2);\n text-shadow: 0 0 5px rgba(34, 197, 94, 0.6);\n box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);\n }\n}\n\n@keyframes microphoneSilentBlink {\n 0% {\n background: rgba(107, 114, 128, 0.1);\n box-shadow: 0 0 5px rgba(107, 114, 128, 0.3);\n }\n 50% {\n background: rgba(107, 114, 128, 0.3);\n transform: scale(1.05);\n box-shadow: 0 0 10px rgba(107, 114, 128, 0.5);\n }\n 100% {\n background: rgba(107, 114, 128, 0.1);\n box-shadow: 0 0 5px rgba(107, 114, 128, 0.3);\n }\n}\n\n@keyframes fadeOut {\n 0% {\n opacity: 1;\n transform: translateX(0);\n }\n 100% {\n opacity: 0;\n transform: translateX(20px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n * {\n animation: none !important;\n transition: none !important;\n }\n}\n\n/* Search Input Interactions */\ninput[type=\"text\"]:focus {\n border-color: #007bff !important;\n box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);\n}\n\nbutton[aria-label=\"Clear search\"]:hover {\n color: #333 !important;\n}\n";
3536
+ var inviteKeyframes = "\n@keyframes fadeIn {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n@keyframes slideInRight {\n 0% {\n transform: translateX(100%);\n opacity: 0;\n }\n 100% {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes slideDown {\n 0% {\n opacity: 0;\n transform: translateY(-12px) scale(0.95);\n }\n 100% {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes invitePulse {\n 0% {\n transform: scale(1.05);\n box-shadow: 0 0 20px rgba(16,185,129,0.4), inset 0 1px 0 rgba(255,255,255,0.1);\n }\n 50% {\n transform: scale(1.08);\n box-shadow: 0 0 30px rgba(16,185,129,0.6), inset 0 1px 0 rgba(255,255,255,0.2);\n }\n 100% {\n transform: scale(1.05);\n box-shadow: 0 0 20px rgba(16,185,129,0.4), inset 0 1px 0 rgba(255,255,255,0.1);\n }\n}\n\n@keyframes speakingPulse {\n 0% {\n transform: scale(1);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.6);\n }\n 50% {\n transform: scale(1.2);\n box-shadow: 0 0 20px rgba(16, 185, 129, 0.8);\n }\n 100% {\n transform: scale(1);\n box-shadow: 0 0 10px rgba(16, 185, 129, 0.6);\n }\n}\n\n@keyframes microphoneGreenBlink {\n 0% {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.2);\n text-shadow: 0 0 5px rgba(34, 197, 94, 0.6);\n box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);\n }\n 50% {\n color: #16a34a;\n background: rgba(34, 197, 94, 0.4);\n text-shadow: 0 0 10px rgba(34, 197, 94, 0.8);\n transform: scale(1.1);\n box-shadow: 0 0 15px rgba(34, 197, 94, 0.7);\n }\n 100% {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.2);\n text-shadow: 0 0 5px rgba(34, 197, 94, 0.6);\n box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);\n }\n}\n\n@keyframes microphoneSilentBlink {\n 0% {\n background: rgba(107, 114, 128, 0.1);\n box-shadow: 0 0 5px rgba(107, 114, 128, 0.3);\n }\n 50% {\n background: rgba(107, 114, 128, 0.3);\n transform: scale(1.05);\n box-shadow: 0 0 10px rgba(107, 114, 128, 0.5);\n }\n 100% {\n background: rgba(107, 114, 128, 0.1);\n box-shadow: 0 0 5px rgba(107, 114, 128, 0.3);\n }\n}\n\n@keyframes fadeOut {\n 0% {\n opacity: 1;\n transform: translateX(0);\n }\n 100% {\n opacity: 0;\n transform: translateX(20px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n * {\n animation: none !important;\n transition: none !important;\n }\n}\n\n/* Search Input Interactions */\ninput[type=\"text\"]:focus {\n border-color: #007bff !important;\n box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);\n}\n\nbutton[aria-label=\"Clear search\"]:hover {\n color: #333 !important;\n}\n";
3537
3537
  export default React.memo(GroupVideoCall);
@@ -18,6 +18,9 @@ type PeerChatHeaderProps = {
18
18
  secondaryColor?: string;
19
19
  busyCallusersList?: string[];
20
20
  peerUserId?: string;
21
+ participantStatuses?: {
22
+ [userId: string]: string;
23
+ };
21
24
  };
22
25
  declare const PeerChatHeader: React.FC<PeerChatHeaderProps>;
23
26
  export default PeerChatHeader;
@@ -16,7 +16,7 @@ import colors from "../../theme/colors";
16
16
  import fonts from "../../theme/fonts";
17
17
  import ProfileAvatar from "../modals/ProfileAvatar";
18
18
  var PeerChatHeader = function (_a) {
19
- var userProfilePic = _a.userProfilePic, onclick = _a.onclick, _b = _a.showBackButton, showBackButton = _b === void 0 ? true : _b, mainHeading = _a.mainHeading, _c = _a.headingStyle, headingStyle = _c === void 0 ? {} : _c, isPeerOnline = _a.isPeerOnline, _d = _a.showActionButtons, showActionButtons = _d === void 0 ? true : _d, onVideoCall = _a.onVideoCall, onAudioCall = _a.onAudioCall, onUserClick = _a.onUserClick, _e = _a.showVideoCall, showVideoCall = _e === void 0 ? false : _e, onSearch = _a.onSearch, _f = _a.showOptions, showOptions = _f === void 0 ? false : _f, onOptionsClick = _a.onOptionsClick, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, busyCallusersList = _a.busyCallusersList, peerUserId = _a.peerUserId;
19
+ var userProfilePic = _a.userProfilePic, onclick = _a.onclick, _b = _a.showBackButton, showBackButton = _b === void 0 ? true : _b, mainHeading = _a.mainHeading, _c = _a.headingStyle, headingStyle = _c === void 0 ? {} : _c, isPeerOnline = _a.isPeerOnline, _d = _a.showActionButtons, showActionButtons = _d === void 0 ? true : _d, onVideoCall = _a.onVideoCall, onAudioCall = _a.onAudioCall, onUserClick = _a.onUserClick, _e = _a.showVideoCall, showVideoCall = _e === void 0 ? false : _e, onSearch = _a.onSearch, _f = _a.showOptions, showOptions = _f === void 0 ? false : _f, onOptionsClick = _a.onOptionsClick, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, busyCallusersList = _a.busyCallusersList, peerUserId = _a.peerUserId, _g = _a.participantStatuses, participantStatuses = _g === void 0 ? {} : _g;
20
20
  var getHeaderGradient = function () {
21
21
  var primary = primaryColor || colors.blue;
22
22
  var secondary = secondaryColor || colors.blueLight;
@@ -27,7 +27,7 @@ var PeerChatHeader = function (_a) {
27
27
  React.createElement(FontAwesomeIcon, { icon: CustomIcons.BackArrow.icon, style: { fontSize: CustomIcons.BackArrow.size, color: CustomIcons.BackArrow.color } }))),
28
28
  React.createElement("div", { style: styles.userInfo },
29
29
  React.createElement("div", { style: styles.profilePicContainer },
30
- React.createElement(ProfileAvatar, { userName: mainHeading || '', profilePic: userProfilePic, size: 45, showOnlineIndicator: true, isOnline: isPeerOnline || false, isBusy: busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""), primaryColor: primaryColor, secondaryColor: secondaryColor })),
30
+ React.createElement(ProfileAvatar, { userName: mainHeading || '', profilePic: userProfilePic, size: 45, showOnlineIndicator: true, isOnline: isPeerOnline || false, isBusy: busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""), userId: peerUserId, participantStatuses: participantStatuses, primaryColor: primaryColor, secondaryColor: secondaryColor })),
31
31
  React.createElement("div", { style: styles.userDetails },
32
32
  React.createElement("h2", { style: styles.userName, onClick: onUserClick },
33
33
  " ",
@@ -35,14 +35,22 @@ var PeerChatHeader = function (_a) {
35
35
  React.createElement("span", { style: __assign(__assign({}, styles.onlineStatus), { color: isPeerOnline ? colors.onlineColor : colors.disabledColor }) }))),
36
36
  (showActionButtons || showOptions) && (React.createElement("div", { style: styles.actionButtons },
37
37
  showActionButtons && (React.createElement(React.Fragment, null,
38
- React.createElement("button", { disabled: !isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || "")), style: __assign(__assign({}, styles.actionButton), { opacity: (!isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""))) ? 0.5 : 1 }), "aria-label": "Call", onClick: onAudioCall },
39
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faPhone.icon, style: { fontSize: CustomIcons.faPhone.size, color: colors.white } })),
40
- React.createElement("button", { disabled: !isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || "")), style: __assign(__assign({}, styles.actionButton), { opacity: (!isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""))) ? 0.5 : 1 }), "aria-label": "Video Call", onClick: onVideoCall },
41
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: colors.white } })),
42
- React.createElement("button", { style: styles.actionButton, "aria-label": "Search", onClick: onSearch },
43
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faSearch.icon, style: { fontSize: CustomIcons.faSearch.size, color: colors.white } })))),
44
- showOptions && (React.createElement("button", { style: styles.actionButton, "aria-label": "Options", onClick: onOptionsClick },
45
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faEllipsisV.icon, style: { fontSize: CustomIcons.faEllipsisV.size, color: colors.white } })))))));
38
+ React.createElement("div", { className: "control-button-wrapper" },
39
+ React.createElement("button", { disabled: !isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || "")), style: __assign(__assign({}, styles.actionButton), { opacity: (!isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""))) ? 0.5 : 1 }), "aria-label": "Call", onClick: onAudioCall },
40
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faPhone.icon, style: { fontSize: CustomIcons.faPhone.size, color: colors.white } })),
41
+ React.createElement("span", { className: "custom-tooltip" }, "Audio Call")),
42
+ React.createElement("div", { className: "control-button-wrapper" },
43
+ React.createElement("button", { disabled: !isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || "")), style: __assign(__assign({}, styles.actionButton), { opacity: (!isPeerOnline || showVideoCall || (busyCallusersList === null || busyCallusersList === void 0 ? void 0 : busyCallusersList.includes(peerUserId || ""))) ? 0.5 : 1 }), "aria-label": "Video Call", onClick: onVideoCall },
44
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: colors.white } })),
45
+ React.createElement("span", { className: "custom-tooltip" }, "Video Call")),
46
+ React.createElement("div", { className: "control-button-wrapper" },
47
+ React.createElement("button", { style: styles.actionButton, "aria-label": "Search", onClick: onSearch },
48
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faSearch.icon, style: { fontSize: CustomIcons.faSearch.size, color: colors.white } })),
49
+ React.createElement("span", { className: "custom-tooltip" }, "Search")))),
50
+ showOptions && (React.createElement("div", { className: "control-button-wrapper" },
51
+ React.createElement("button", { style: styles.actionButton, "aria-label": "Options", onClick: onOptionsClick },
52
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faEllipsisV.icon, style: { fontSize: CustomIcons.faEllipsisV.size, color: colors.white } })),
53
+ React.createElement("span", { className: "custom-tooltip" }, "Options")))))));
46
54
  };
47
55
  var styles = {
48
56
  headerContainer: {
@@ -115,14 +115,22 @@ var GroupChatHeader = function (_a) {
115
115
  React.createElement("h3", { style: __assign(__assign({}, headingStyle), styles.groupName) }, mainHeading),
116
116
  React.createElement("p", { style: styles.statusText }, participantsCount > 0 ? "".concat(participantsCount, " participants") : '')))),
117
117
  showBackButton && (React.createElement("div", { style: styles.rightSection },
118
- !showJoinGroupCallBtn && React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: handleAudioCall },
119
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faPhone.icon, style: { fontSize: CustomIcons.faPhone.size, color: colors.white } })),
120
- !showJoinGroupCallBtn && React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: handleVideoCall },
121
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: colors.white } })),
122
- showJoinGroupCallBtn && React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: rejoinGroupCall },
123
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: 'red' } })),
124
- React.createElement("button", { onClick: function () { return onSearch && onSearch(); }, style: styles.actionButton, "aria-label": "Search" },
125
- React.createElement(FontAwesomeIcon, { icon: CustomIcons.faSearch.icon, style: { fontSize: CustomIcons.faSearch.size, color: colors.white } }))))),
118
+ !showJoinGroupCallBtn && (React.createElement("div", { className: "control-button-wrapper" },
119
+ React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: handleAudioCall },
120
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faPhone.icon, style: { fontSize: CustomIcons.faPhone.size, color: colors.white } })),
121
+ React.createElement("span", { className: "custom-tooltip" }, "Audio Call"))),
122
+ !showJoinGroupCallBtn && (React.createElement("div", { className: "control-button-wrapper" },
123
+ React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: handleVideoCall },
124
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: colors.white } })),
125
+ React.createElement("span", { className: "custom-tooltip" }, "Video Call"))),
126
+ showJoinGroupCallBtn && (React.createElement("div", { className: "control-button-wrapper" },
127
+ React.createElement("button", { style: __assign(__assign({}, styles.actionButton), { opacity: showVideoCall ? 0.5 : 1 }), disabled: showVideoCall, onClick: rejoinGroupCall },
128
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faVideo.icon, style: { fontSize: CustomIcons.faVideo.size, color: 'red' } })),
129
+ React.createElement("span", { className: "custom-tooltip" }, "Rejoin Call"))),
130
+ React.createElement("div", { className: "control-button-wrapper" },
131
+ React.createElement("button", { onClick: function () { return onSearch && onSearch(); }, style: styles.actionButton, "aria-label": "Search" },
132
+ React.createElement(FontAwesomeIcon, { icon: CustomIcons.faSearch.icon, style: { fontSize: CustomIcons.faSearch.size, color: colors.white } })),
133
+ React.createElement("span", { className: "custom-tooltip" }, "Search"))))),
126
134
  React.createElement(InfoModal, { open: showInfoModal, message: infoModalMessage, onClose: function () { return setShowInfoModal(false); } })));
127
135
  };
128
136
  var styles = {
@@ -1,4 +1,9 @@
1
1
  import React from "react";
2
+ interface User {
3
+ user_id: string;
4
+ user_name: string;
5
+ profile_pic?: string;
6
+ }
2
7
  export type CallRecord = {
3
8
  id: string;
4
9
  user_name: string;
@@ -14,7 +19,6 @@ export type CallRecord = {
14
19
  };
15
20
  interface Props {
16
21
  call: CallRecord;
17
- calls?: CallRecord[];
18
22
  onClose: () => void;
19
23
  formatMessageTime: (t: any) => string;
20
24
  primaryColor?: string;
@@ -22,6 +26,12 @@ interface Props {
22
26
  currentUserName?: string;
23
27
  client?: any;
24
28
  currentUserId?: string;
29
+ users: User[];
30
+ onlineUsers: string[];
31
+ busyCallusersList: string[];
32
+ handleVideoCall: () => void;
33
+ handleAudioCall: () => void;
34
+ showVideoCall: boolean;
25
35
  }
26
36
  declare const CallDetailsPanel: React.FC<Props>;
27
37
  export default CallDetailsPanel;
@@ -45,18 +45,35 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
45
45
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
46
  }
47
47
  };
48
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
50
+ if (ar || !(i in from)) {
51
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
52
+ ar[i] = from[i];
53
+ }
54
+ }
55
+ return to.concat(ar || Array.prototype.slice.call(from));
56
+ };
48
57
  import React, { useState } from "react";
49
58
  import fonts from "../../../theme/fonts";
50
59
  import colors from "../../../theme/colors";
51
60
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
52
61
  import CustomIcons, { AppIcons } from "../../../theme/icons";
53
- import { getInitials } from "../../../services/Common";
62
+ import ProfileAvatar from "../../modals/ProfileAvatar";
54
63
  var CallDetailsPanel = function (_a) {
55
- var call = _a.call, _b = _a.calls, calls = _b === void 0 ? [] : _b, onClose = _a.onClose, formatMessageTime = _a.formatMessageTime, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, currentUserName = _a.currentUserName, client = _a.client, currentUserId = _a.currentUserId;
64
+ var _b, _c, _d;
65
+ var call = _a.call, onClose = _a.onClose, formatMessageTime = _a.formatMessageTime, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, currentUserName = _a.currentUserName, client = _a.client, currentUserId = _a.currentUserId, users = _a.users, onlineUsers = _a.onlineUsers, busyCallusersList = _a.busyCallusersList, handleVideoCall = _a.handleVideoCall, handleAudioCall = _a.handleAudioCall, showVideoCall = _a.showVideoCall;
56
66
  var headerGradient = "linear-gradient(115deg, ".concat(primaryColor || colors.blue, " 0%, ").concat(secondaryColor || colors.blueLight, " 100%)");
57
- var _c = useState('History'), activeTab = _c[0], setActiveTab = _c[1];
58
- var _d = useState([]), participantsCallHistory = _d[0], setParticipantsCallHistory = _d[1];
59
- var _e = useState(false), loadingHistory = _e[0], setLoadingHistory = _e[1];
67
+ var _e = useState('Participants'), activeTab = _e[0], setActiveTab = _e[1];
68
+ var _f = useState([]), participantsCallHistory = _f[0], setParticipantsCallHistory = _f[1];
69
+ var _g = useState(false), loadingHistory = _g[0], setLoadingHistory = _g[1];
70
+ var _h = useState(1), currentPage = _h[0], setCurrentPage = _h[1];
71
+ var _j = useState(true), hasMoreData = _j[0], setHasMoreData = _j[1];
72
+ var _k = useState(false), isLoadingMore = _k[0], setIsLoadingMore = _k[1];
73
+ var historyListRef = React.useRef(null);
74
+ var isCallerOnline = onlineUsers.includes(call.caller_id || '');
75
+ var isCallerBusy = busyCallusersList.includes(call.caller_id || '');
76
+ var isCallDisabled = !isCallerOnline || isCallerBusy || showVideoCall;
60
77
  var formatCallDuration = function (duration) {
61
78
  if (!duration)
62
79
  return "00:00";
@@ -67,57 +84,92 @@ var CallDetailsPanel = function (_a) {
67
84
  var seconds = durationNum % 60;
68
85
  return "".concat(minutes.toString().padStart(2, '0'), ":").concat(seconds.toString().padStart(2, '0'));
69
86
  };
70
- var fetchParticipantsCallHistory = function () { return __awaiter(void 0, void 0, void 0, function () {
71
- var response, mappedHistory, error_1;
72
- return __generator(this, function (_a) {
73
- switch (_a.label) {
74
- case 0:
75
- if (!client || !currentUserId || !call.caller_id) {
76
- console.log('Missing required data:', { currentUserId: currentUserId, caller_id: call.caller_id, call: call });
77
- return [2 /*return*/];
78
- }
79
- setLoadingHistory(true);
80
- _a.label = 1;
81
- case 1:
82
- _a.trys.push([1, 3, 4, 5]);
83
- console.log('Fetching call history between current user:', currentUserId, 'and other participant:', call.caller_id);
84
- return [4 /*yield*/, client.groupVideoCall.getParticipantsCallHistory(currentUserId, call.caller_id, 1, 50)];
85
- case 2:
86
- response = _a.sent();
87
- mappedHistory = response.map(function (historyCall) { return ({
88
- id: historyCall._id || historyCall.id || "".concat(historyCall.caller_id, "-").concat(historyCall.time || Date.now()),
89
- user_name: historyCall.caller_name || call.user_name,
90
- profile_pic: historyCall.profile_pic || call.profile_pic,
91
- time: historyCall.created_at || historyCall.time,
92
- direction: historyCall.call_history_status === 'Missed' || historyCall.call_status === 'missed' ? 'missed' :
93
- (historyCall.call_history_status === 'Outgoing' || historyCall.caller_id === currentUserId) ? 'out' : 'in',
94
- note: historyCall.call_history_status === 'Missed' || historyCall.call_status === 'missed' ? 'Missed Call' :
95
- historyCall.call_history_status || 'Call',
96
- call_type: historyCall.call_type,
97
- call_mode: historyCall.call_mode,
98
- caller_id: historyCall.caller_id,
99
- user_id: historyCall.user_id,
100
- duration: historyCall.duration || historyCall.call_duration
101
- }); });
102
- setParticipantsCallHistory(mappedHistory);
103
- return [3 /*break*/, 5];
104
- case 3:
105
- error_1 = _a.sent();
106
- console.error('Error fetching participants call history:', error_1);
107
- setParticipantsCallHistory([]);
108
- return [3 /*break*/, 5];
109
- case 4:
110
- setLoadingHistory(false);
111
- return [7 /*endfinally*/];
112
- case 5: return [2 /*return*/];
113
- }
87
+ var fetchParticipantsCallHistory = function (page, append) {
88
+ if (page === void 0) { page = 1; }
89
+ if (append === void 0) { append = false; }
90
+ return __awaiter(void 0, void 0, void 0, function () {
91
+ var response, mappedHistory_1, error_1;
92
+ return __generator(this, function (_a) {
93
+ switch (_a.label) {
94
+ case 0:
95
+ if (!client || !currentUserId || !call.caller_id) {
96
+ console.log('Missing required data:', { currentUserId: currentUserId, caller_id: call.caller_id, call: call });
97
+ return [2 /*return*/];
98
+ }
99
+ if (append) {
100
+ setIsLoadingMore(true);
101
+ }
102
+ else {
103
+ setLoadingHistory(true);
104
+ }
105
+ _a.label = 1;
106
+ case 1:
107
+ _a.trys.push([1, 3, 4, 5]);
108
+ return [4 /*yield*/, client.groupVideoCall.getParticipantsCallHistory(currentUserId, call.caller_id, page, 50)];
109
+ case 2:
110
+ response = _a.sent();
111
+ if (!response || response.length === 0) {
112
+ setHasMoreData(false);
113
+ return [2 /*return*/];
114
+ }
115
+ mappedHistory_1 = response.map(function (historyCall) { return ({
116
+ id: historyCall._id || historyCall.id || "".concat(historyCall.caller_id, "-").concat(historyCall.time || Date.now()),
117
+ user_name: historyCall.caller_name || call.user_name,
118
+ profile_pic: historyCall.profile_pic || call.profile_pic,
119
+ time: historyCall.created_at || historyCall.time,
120
+ direction: historyCall.call_history_status === 'Missed' || historyCall.call_status === 'missed' ? 'missed' :
121
+ (historyCall.call_history_status === 'Outgoing' || historyCall.caller_id === currentUserId) ? 'out' : 'in',
122
+ note: historyCall.call_history_status === 'Missed' || historyCall.call_status === 'missed' ? 'Missed Call' :
123
+ historyCall.call_history_status || 'Call',
124
+ call_type: historyCall.call_type,
125
+ call_mode: historyCall.call_mode,
126
+ caller_id: historyCall.caller_id,
127
+ user_id: historyCall.user_id,
128
+ duration: historyCall.duration || historyCall.call_duration
129
+ }); });
130
+ if (append) {
131
+ setParticipantsCallHistory(function (prev) { return __spreadArray(__spreadArray([], prev, true), mappedHistory_1, true); });
132
+ }
133
+ else {
134
+ setParticipantsCallHistory(mappedHistory_1);
135
+ }
136
+ if (response.length < 50) {
137
+ setHasMoreData(false);
138
+ }
139
+ return [3 /*break*/, 5];
140
+ case 3:
141
+ error_1 = _a.sent();
142
+ console.error('Error fetching participants call history:', error_1);
143
+ if (!append) {
144
+ setParticipantsCallHistory([]);
145
+ }
146
+ return [3 /*break*/, 5];
147
+ case 4:
148
+ setLoadingHistory(false);
149
+ setIsLoadingMore(false);
150
+ return [7 /*endfinally*/];
151
+ case 5: return [2 /*return*/];
152
+ }
153
+ });
114
154
  });
115
- }); };
155
+ };
116
156
  React.useEffect(function () {
117
157
  if (activeTab === 'History' && client && currentUserId && call.caller_id) {
118
- fetchParticipantsCallHistory();
158
+ setCurrentPage(1);
159
+ setHasMoreData(true);
160
+ setParticipantsCallHistory([]);
161
+ fetchParticipantsCallHistory(1, false);
119
162
  }
120
- }, [activeTab, client, currentUserId, call.caller_id]);
163
+ }, [activeTab, client, currentUserId, call.caller_id, showVideoCall]);
164
+ var handleScroll = function (e) {
165
+ var target = e.currentTarget;
166
+ var bottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 50;
167
+ if (bottom && !isLoadingMore && !loadingHistory && hasMoreData) {
168
+ var nextPage = currentPage + 1;
169
+ setCurrentPage(nextPage);
170
+ fetchParticipantsCallHistory(nextPage, true);
171
+ }
172
+ };
121
173
  return (React.createElement("div", { style: panelStyles.container, role: "dialog", "aria-label": "Call details panel" },
122
174
  React.createElement("div", { style: __assign(__assign({}, panelStyles.headerRow), { background: headerGradient, padding: '16px 20px' }) },
123
175
  React.createElement("button", { onClick: onClose, style: panelStyles.backButton, "aria-label": "Back" },
@@ -125,14 +177,13 @@ var CallDetailsPanel = function (_a) {
125
177
  React.createElement("div", { style: __assign(__assign(__assign({}, panelStyles.title), fonts.groupTitle), { color: colors.white }) }, "Call Details"),
126
178
  React.createElement("div", { style: { width: 40 } })),
127
179
  React.createElement("div", { style: __assign(__assign({}, panelStyles.topInfo), { padding: '14px 20px' }) },
128
- React.createElement("div", { style: panelStyles.avatarWrapper }, call.profile_pic ? (React.createElement("img", { src: call.profile_pic, alt: call.user_name, style: panelStyles.avatar })) : (React.createElement("div", { style: __assign(__assign({}, panelStyles.avatarPlaceholder), { background: "linear-gradient(115deg, ".concat(primaryColor || colors.blue, " 0%, ").concat(secondaryColor || colors.blueLight, " 100%)") }) },
129
- React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { color: colors.white, fontWeight: 700 }) }, getInitials(call.user_name))))),
180
+ React.createElement(ProfileAvatar, { userName: call.user_name, profilePic: ((_b = users.find(function (u) { return u.user_id === (call.caller_id); })) === null || _b === void 0 ? void 0 : _b.profile_pic) || call.profile_pic || '', size: 45, primaryColor: primaryColor, secondaryColor: secondaryColor, showOnlineIndicator: true, isOnline: isCallerOnline, onlineIndicatorVariant: "avatar", isBusy: busyCallusersList.includes(call.caller_id || '') }),
130
181
  React.createElement("div", { style: panelStyles.topText },
131
182
  React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { fontWeight: 700 }) }, call.user_name)),
132
183
  React.createElement("div", { style: panelStyles.actions },
133
- React.createElement("button", { style: panelStyles.iconBtn, "aria-label": "Voice call" },
184
+ React.createElement("button", { style: __assign(__assign({}, panelStyles.iconBtn), { opacity: isCallDisabled ? 0.5 : 1, cursor: isCallDisabled ? 'not-allowed' : 'pointer' }), "aria-label": "Voice call", onClick: handleAudioCall, disabled: isCallDisabled },
134
185
  React.createElement(FontAwesomeIcon, { icon: AppIcons.Calls.icon, style: { color: colors.muted } })),
135
- React.createElement("button", { style: panelStyles.iconBtn, "aria-label": "Video call" },
186
+ React.createElement("button", { style: __assign(__assign({}, panelStyles.iconBtn), { opacity: isCallDisabled ? 0.5 : 1, cursor: isCallDisabled ? 'not-allowed' : 'pointer' }), "aria-label": "Video call", onClick: handleVideoCall, disabled: isCallDisabled },
136
187
  React.createElement(FontAwesomeIcon, { icon: AppIcons.Video.icon, style: { color: colors.muted } })))),
137
188
  React.createElement("div", { style: panelStyles.callStatusRow },
138
189
  React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 8 } },
@@ -140,7 +191,7 @@ var CallDetailsPanel = function (_a) {
140
191
  React.createElement("div", null,
141
192
  React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { fontWeight: 700 }) }, call.note || 'Call'),
142
193
  React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, formatMessageTime(call.time)))),
143
- React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, "13:08")),
194
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, call.duration)),
144
195
  React.createElement("div", { style: panelStyles.divider }),
145
196
  React.createElement("div", { style: panelStyles.sectionTabs },
146
197
  React.createElement("div", { onClick: function () { return setActiveTab('Participants'); }, style: __assign(__assign(__assign(__assign({}, panelStyles.tab), fonts.tabStyles), { cursor: 'pointer' }), (activeTab === 'Participants' ? panelStyles.activeTab : {})) }, "Participants"),
@@ -149,28 +200,31 @@ var CallDetailsPanel = function (_a) {
149
200
  activeTab === 'Participants' && (React.createElement("div", { style: { padding: '8px 20px' } },
150
201
  React.createElement("div", { style: { display: 'flex', flexDirection: 'column', gap: 12 } },
151
202
  React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 12 } },
152
- React.createElement("div", { style: __assign(__assign({}, panelStyles.avatarPlaceholder), { background: "linear-gradient(115deg, ".concat(primaryColor || colors.blue, " 0%, ").concat(secondaryColor || colors.blueLight, " 100%)"), width: 44, height: 44, borderRadius: 44 }) },
153
- React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { color: colors.white }) }, getInitials(call.user_name))),
203
+ React.createElement(ProfileAvatar, { userName: call.user_name, profilePic: ((_c = users.find(function (u) { return u.user_id === (call.caller_id); })) === null || _c === void 0 ? void 0 : _c.profile_pic) || call.profile_pic || '', size: 45, primaryColor: primaryColor, secondaryColor: secondaryColor, showOnlineIndicator: true, isOnline: isCallerOnline, onlineIndicatorVariant: "avatar", isBusy: busyCallusersList.includes(call.caller_id || '') }),
154
204
  React.createElement("div", null,
155
205
  React.createElement("div", { style: __assign({}, fonts.listsStyle) }, call.user_name))),
156
- React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 12 } },
157
- React.createElement("div", { style: __assign(__assign({}, panelStyles.avatarPlaceholder), { background: "linear-gradient(115deg, ".concat(secondaryColor || colors.blueLight, " 0%, ").concat(primaryColor || colors.blue, " 100%)"), width: 44, height: 44, borderRadius: 44 }) },
158
- React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { color: colors.white }) }, getInitials(currentUserName || ''))),
206
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 12, marginTop: 8 } },
207
+ React.createElement(ProfileAvatar, { userName: currentUserName || 'You', profilePic: ((_d = users.find(function (u) { return u.user_id === (call.user_id); })) === null || _d === void 0 ? void 0 : _d.profile_pic) || call.profile_pic || '', size: 45, primaryColor: primaryColor, secondaryColor: secondaryColor, showOnlineIndicator: true, isOnline: true, onlineIndicatorVariant: "avatar", isBusy: busyCallusersList.includes(call.user_id || '') }),
159
208
  React.createElement("div", null,
160
209
  React.createElement("div", { style: __assign({}, fonts.listsStyle) }, currentUserName || 'You')))))),
161
210
  activeTab === 'History' && (React.createElement(React.Fragment, null,
162
211
  React.createElement("style", null, ".cdp-history-list { -ms-overflow-style: none; scrollbar-width: none; }\n.cdp-history-list::-webkit-scrollbar { display: none; }"),
163
- React.createElement("div", { className: "cdp-history-list", style: panelStyles.historyList }, loadingHistory ? (React.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px' } },
212
+ React.createElement("div", { className: "cdp-history-list", style: panelStyles.historyList, onScroll: handleScroll, ref: historyListRef }, loadingHistory ? (React.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px' } },
164
213
  React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, "Loading call history..."))) : participantsCallHistory.length === 0 ? (React.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px' } },
165
- React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, "No call history found"))) : (participantsCallHistory.map(function (c) { return (React.createElement("div", { key: c.id, style: panelStyles.historyRow },
166
- React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } },
167
- React.createElement(FontAwesomeIcon, { icon: c.direction === "missed" ? AppIcons.MissedCall.icon : c.direction === "in" ? AppIcons.IncomingCall.icon : AppIcons.OutgoingCall.icon, color: c.direction === "missed" ? AppIcons.MissedCall.color : AppIcons.IncomingCall.color, style: { fontSize: 14 } }),
168
- React.createElement("div", null,
169
- React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { fontWeight: 700 }) }, c.note || "Call"),
170
- React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, formatMessageTime(c.time)))),
171
- React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 8 } },
172
- React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, formatCallDuration(c.duration)),
173
- React.createElement(FontAwesomeIcon, { icon: (c.call_mode === 'video' || c.call_type === 'video') ? AppIcons.Video.icon : AppIcons.Calls.icon, style: { fontSize: 14, color: colors.muted } })))); }))))),
214
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, "No call history found"))) : (React.createElement(React.Fragment, null,
215
+ participantsCallHistory.map(function (c) { return (React.createElement("div", { key: c.id, style: panelStyles.historyRow },
216
+ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } },
217
+ React.createElement(FontAwesomeIcon, { icon: c.direction === "missed" ? AppIcons.MissedCall.icon : c.direction === "in" ? AppIcons.IncomingCall.icon : AppIcons.OutgoingCall.icon, color: c.direction === "missed" ? AppIcons.MissedCall.color : AppIcons.IncomingCall.color, style: { fontSize: 14 } }),
218
+ React.createElement("div", null,
219
+ React.createElement("div", { style: __assign(__assign({}, fonts.listsStyle), { fontWeight: 700 }) }, c.note || "Call"),
220
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, formatMessageTime(c.time)))),
221
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 8 } },
222
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted }) }, c.duration),
223
+ React.createElement(FontAwesomeIcon, { icon: (c.call_mode === 'video' || c.call_type === 'video') ? AppIcons.Video.icon : AppIcons.Calls.icon, style: { fontSize: 14, color: colors.muted } })))); }),
224
+ isLoadingMore && (React.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '12px' } },
225
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted, fontSize: 12 }) }, "Loading more..."))),
226
+ !hasMoreData && participantsCallHistory.length === 0 && (React.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '12px' } },
227
+ React.createElement("div", { style: __assign(__assign({}, fonts.content), { color: colors.muted, fontSize: 12 }) }, "No more call history")))))))),
174
228
  activeTab === 'Recording' && (React.createElement("div", { style: { padding: '8px 20px' } },
175
229
  React.createElement("a", { href: "https://example.com/recording", style: { color: colors.blue, textDecoration: 'none' } }, "https://example.com/recording")))));
176
230
  };
@@ -217,7 +271,7 @@ var panelStyles = {
217
271
  actions: { display: "flex", gap: 8 },
218
272
  iconBtn: { width: 40, height: 40, borderRadius: 8, border: "1px solid rgba(0,0,0,0.06)", background: colors.white, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" },
219
273
  sectionTabs: { display: "flex", justifyContent: 'space-between', gap: 24, borderTop: "1px solid #f1f3f5", paddingTop: 12, marginTop: 4, paddingLeft: 36, paddingRight: 36, alignItems: 'center' },
220
- tab: { color: colors.muted, fontSize: 16, padding: '12px 8px', minWidth: 120, textAlign: 'center' },
274
+ tab: { color: colors.muted, fontSize: 16, paddingTop: '12px', paddingBottom: '12px', paddingLeft: '8px', paddingRight: '8px', minWidth: 120, textAlign: 'center' },
221
275
  activeTab: { color: colors.blue, borderBottom: "3px solid ".concat(colors.blue), paddingBottom: 8 },
222
276
  callStatusRow: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 20px' },
223
277
  divider: { height: 1, background: '#f1f3f5' },
@@ -1,4 +1,9 @@
1
1
  import React from "react";
2
+ interface User {
3
+ user_id: string;
4
+ user_name: string;
5
+ profile_pic?: string;
6
+ }
2
7
  export type CallRecord = {
3
8
  id: string;
4
9
  user_name: string;
@@ -22,6 +27,8 @@ interface CallHistoryProps {
22
27
  secondaryColor?: string;
23
28
  onlineUsers?: string[];
24
29
  busyCallusersList?: string[];
30
+ users: User[];
31
+ showVideoCall: boolean;
25
32
  }
26
33
  declare const CallHistory: React.FC<CallHistoryProps>;
27
34
  export default CallHistory;
@@ -61,7 +61,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
61
61
  import { AppIcons } from "../../../theme/icons";
62
62
  import ProfileAvatar from "../../modals/ProfileAvatar";
63
63
  var CallHistory = function (_a) {
64
- var _b = _a.calls, calls = _b === void 0 ? [] : _b, onCallPress = _a.onCallPress, formatMessageTime = _a.formatMessageTime, client = _a.client, userId = _a.userId, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, _c = _a.onlineUsers, onlineUsers = _c === void 0 ? [] : _c, _d = _a.busyCallusersList, busyCallusersList = _d === void 0 ? [] : _d;
64
+ var _b = _a.calls, calls = _b === void 0 ? [] : _b, onCallPress = _a.onCallPress, formatMessageTime = _a.formatMessageTime, client = _a.client, userId = _a.userId, primaryColor = _a.primaryColor, secondaryColor = _a.secondaryColor, _c = _a.onlineUsers, onlineUsers = _c === void 0 ? [] : _c, _d = _a.busyCallusersList, busyCallusersList = _d === void 0 ? [] : _d, users = _a.users, showVideoCall = _a.showVideoCall;
65
65
  var _e = useState(null), hoveredId = _e[0], setHoveredId = _e[1];
66
66
  var _f = useState(null), selectedId = _f[0], setSelectedId = _f[1];
67
67
  var _g = useState([]), callHistory = _g[0], setCallHistory = _g[1];
@@ -141,6 +141,10 @@ var CallHistory = function (_a) {
141
141
  }
142
142
  };
143
143
  }, [userId, client, initialLoadDone]); // Include initialLoadDone to prevent re-running
144
+ useEffect(function () {
145
+ setInitialLoadDone(false);
146
+ paginationInProgressRef.current = false;
147
+ }, [showVideoCall]);
144
148
  // Reset state when userId or client changes
145
149
  useEffect(function () {
146
150
  var prevUserId = initialLoadDone ? userId : null;
@@ -172,13 +176,14 @@ var CallHistory = function (_a) {
172
176
  React.createElement("div", { style: styles.listContainer, onScroll: handleScroll },
173
177
  displayCalls.length === 0 && !loading && React.createElement("div", { style: styles.empty }, "No calls yet"),
174
178
  displayCalls.map(function (c) {
179
+ var _a;
175
180
  var isHovered = hoveredId === c.id;
176
181
  var isSelected = selectedId === c.id;
177
182
  var isCallerOnline = onlineUsers.includes(c.caller_id || c.user_id || '');
178
183
  return (React.createElement("div", { key: c.id, onMouseEnter: function () { return setHoveredId(c.id); }, onMouseLeave: function () { return setHoveredId(null); }, onClick: function () { return handleClick(c); }, style: __assign(__assign(__assign({}, styles.rowWrapper), (isHovered ? styles.rowHover : {})), (isSelected ? styles.rowSelected : {})) },
179
184
  React.createElement("div", { style: styles.row },
180
185
  React.createElement("div", { style: styles.left },
181
- React.createElement(ProfileAvatar, { userName: c.user_name, profilePic: c.profile_pic, size: 45, primaryColor: primaryColor, secondaryColor: secondaryColor, showOnlineIndicator: true, isOnline: isCallerOnline, onlineIndicatorVariant: "avatar", isBusy: busyCallusersList.includes(c.caller_id || c.user_id || '') })),
186
+ React.createElement(ProfileAvatar, { userName: c.user_name, profilePic: ((_a = users.find(function (u) { return u.user_id === (c.caller_id); })) === null || _a === void 0 ? void 0 : _a.profile_pic) || c.profile_pic || '', size: 45, primaryColor: primaryColor, secondaryColor: secondaryColor, showOnlineIndicator: true, isOnline: isCallerOnline, onlineIndicatorVariant: "avatar", isBusy: busyCallusersList.includes(c.caller_id || '') })),
182
187
  React.createElement("div", { style: styles.center },
183
188
  React.createElement("div", { style: styles.nameRow },
184
189
  React.createElement("div", { style: __assign(__assign({}, styles.nameText), fonts.listsStyle) }, c.user_name),