mr-chat-bird 1.0.13 → 1.0.14

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/dist/index.css CHANGED
@@ -78,6 +78,9 @@
78
78
  display: none;
79
79
  }
80
80
  }
81
+ :where([data-mantine-color-scheme=dark]) .mantine-RichTextEditor-control {
82
+ background-color: var(--mantine-color-body);
83
+ }
81
84
 
82
85
  /* src/components/UserProfile/UserProfileDrawer.css */
83
86
  .mrchat-overlay {
@@ -127,7 +130,6 @@
127
130
  gap: 15px;
128
131
  padding: 0 16px;
129
132
  border-bottom: 1px solid var(--mantine-color-default-border);
130
- background-color: var(--mantine-color-default);
131
133
  }
132
134
  .mrchat-backBtn {
133
135
  cursor: pointer;
@@ -207,16 +209,12 @@
207
209
  display: flex;
208
210
  flex-direction: column;
209
211
  min-height: 0;
212
+ height: 100%;
210
213
  flex-shrink: 0;
211
214
  border-right: 1px solid color-mix(in srgb, var(--mantine-color-text) 12%, transparent);
212
215
  padding-top: 12px;
213
216
  background-color: var(--mantine-color-body);
214
217
  }
215
- @media (max-width: 760px) {
216
- .mrchat-sidebar {
217
- width: 180px;
218
- }
219
- }
220
218
  .mrchat-sidebarTop {
221
219
  padding: 0 12px;
222
220
  }
@@ -233,7 +231,16 @@
233
231
  .mrchat-scrollWrapper {
234
232
  flex: 1;
235
233
  min-height: 0;
236
- overflow: hidden;
234
+ height: 100%;
235
+ overflow-y: auto;
236
+ }
237
+ .mrchat-mainAreaWrapper {
238
+ flex: 1;
239
+ display: flex;
240
+ min-height: 0;
241
+ }
242
+ .mrchat-hiddenOnMobile {
243
+ display: none !important;
237
244
  }
238
245
  .mrchat-scrollArea {
239
246
  flex: 1;
@@ -284,6 +291,28 @@
284
291
  gap: 8px;
285
292
  padding: 0px 12px 12px;
286
293
  }
294
+ @media (max-width: 599px) {
295
+ .mrchat-chatContainer {
296
+ flex-direction: column;
297
+ min-height: 100%;
298
+ }
299
+ .mrchat-sidebar {
300
+ width: 100%;
301
+ height: 100%;
302
+ border-right: none;
303
+ border-bottom: 1px solid color-mix(in srgb, var(--mantine-color-text) 12%, transparent);
304
+ border-radius: 0;
305
+ }
306
+ .mrchat-chatItem {
307
+ margin: 2px 0;
308
+ }
309
+ .mrchat-messageArea {
310
+ padding: 12px;
311
+ }
312
+ .mrchat-mainArea {
313
+ min-height: calc(100vh - 74px);
314
+ }
315
+ }
287
316
  .mrchat-chatItem {
288
317
  display: flex;
289
318
  align-items: center;
@@ -303,15 +332,18 @@
303
332
  }
304
333
  .mrchat-chatHeader {
305
334
  display: flex;
306
- justify-content: space-between;
335
+ justify-content: flex-start;
307
336
  align-items: center;
308
337
  padding: 12px 16px;
309
338
  border-bottom: 1px solid color-mix(in srgb, var(--mantine-color-text) 12%, transparent);
310
- background-color: var(--mantine-color-default);
311
339
  position: sticky;
312
340
  top: 0;
313
341
  z-index: 2;
314
342
  min-height: 63px;
343
+ gap: 10px;
344
+ }
345
+ .mrchat-backButton {
346
+ padding: 4px;
315
347
  }
316
348
  .mrchat-receiverInfo {
317
349
  display: flex;
@@ -337,7 +369,6 @@
337
369
  }
338
370
  .mrchat-encryptionText {
339
371
  font-size: 16px;
340
- color: #666;
341
372
  margin-left: 3px;
342
373
  }
343
374
  .mrchat-messageContent {
package/dist/index.d.mts CHANGED
@@ -10,8 +10,10 @@ type ChatUserListProps = {
10
10
  currentUser?: UserData;
11
11
  onSearchUsers?: (query: string) => UserData[] | Promise<UserData[]>;
12
12
  colorScheme?: "light" | "dark";
13
+ primaryColor?: string;
14
+ darkColor?: string;
13
15
  };
14
16
 
15
- declare function MrChat({ colorScheme, ...props }: ChatUserListProps): React.JSX.Element;
17
+ declare function MrChat({ colorScheme, primaryColor, darkColor, ...props }: ChatUserListProps): React.JSX.Element;
16
18
 
17
19
  export { MrChat };
package/dist/index.d.ts CHANGED
@@ -10,8 +10,10 @@ type ChatUserListProps = {
10
10
  currentUser?: UserData;
11
11
  onSearchUsers?: (query: string) => UserData[] | Promise<UserData[]>;
12
12
  colorScheme?: "light" | "dark";
13
+ primaryColor?: string;
14
+ darkColor?: string;
13
15
  };
14
16
 
15
- declare function MrChat({ colorScheme, ...props }: ChatUserListProps): React.JSX.Element;
17
+ declare function MrChat({ colorScheme, primaryColor, darkColor, ...props }: ChatUserListProps): React.JSX.Element;
16
18
 
17
19
  export { MrChat };
package/dist/index.js CHANGED
@@ -111,12 +111,43 @@ var colorThemes = {
111
111
  sunset,
112
112
  ocean
113
113
  };
114
- var createAppTheme = (primaryColor) => (0, import_core.createTheme)({
115
- primaryColor,
116
- colors: {
114
+ var isValidHexColor = (value) => /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test(value);
115
+ var hexToRgb = (hex) => {
116
+ const normalized = hex.replace("#", "");
117
+ const fullHex = normalized.length === 3 ? normalized.split("").map((digit) => digit + digit).join("") : normalized;
118
+ return {
119
+ r: parseInt(fullHex.slice(0, 2), 16),
120
+ g: parseInt(fullHex.slice(2, 4), 16),
121
+ b: parseInt(fullHex.slice(4, 6), 16)
122
+ };
123
+ };
124
+ var rgbToHex = ({ r, g, b }) => `#${[r, g, b].map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
125
+ var clampColor = (value) => Math.min(255, Math.max(0, Math.round(value)));
126
+ var createColorPaletteFromHex = (hex) => {
127
+ const { r, g, b } = hexToRgb(hex);
128
+ const factors = [0.08, 0.18, 0.3, 0.42, 0.54, 0.66, 0.76, 0.86, 0.92, 0.98];
129
+ const palette = factors.map(
130
+ (factor) => rgbToHex({
131
+ r: clampColor(r * factor + 255 * (1 - factor)),
132
+ g: clampColor(g * factor + 255 * (1 - factor)),
133
+ b: clampColor(b * factor + 255 * (1 - factor))
134
+ })
135
+ );
136
+ return palette;
137
+ };
138
+ var createAppTheme = (primaryColor) => {
139
+ const colors = {
117
140
  ...colorThemes
141
+ };
142
+ const resolvedPrimaryColor = isValidHexColor(primaryColor) || !(primaryColor in colorThemes) ? "customBrand" : primaryColor;
143
+ if (isValidHexColor(primaryColor)) {
144
+ colors.customBrand = createColorPaletteFromHex(primaryColor);
118
145
  }
119
- });
146
+ return (0, import_core.createTheme)({
147
+ primaryColor: resolvedPrimaryColor,
148
+ colors
149
+ });
150
+ };
120
151
 
121
152
  // src/store/provider.tsx
122
153
  var import_react = __toESM(require("react"));
@@ -5116,7 +5147,9 @@ function ChatUserMessage({
5116
5147
  enableChat,
5117
5148
  senderDetails,
5118
5149
  receiverDetails,
5119
- onChatInitialized
5150
+ onChatInitialized,
5151
+ onBack,
5152
+ showBackButton
5120
5153
  }) {
5121
5154
  const dispatch = (0, import_react_redux2.useDispatch)();
5122
5155
  const messageList = (0, import_react_redux2.useSelector)(
@@ -5257,7 +5290,15 @@ function ChatUserMessage({
5257
5290
  deleteMessagesByChatId({ chatId, userId: senderDetails?.userId })
5258
5291
  );
5259
5292
  };
5260
- return /* @__PURE__ */ import_react8.default.createElement("div", { className: "mrchat-mainArea" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "mrchat-chatHeader" }, receiverDetails && /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement(
5293
+ return /* @__PURE__ */ import_react8.default.createElement("div", { className: "mrchat-mainArea" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "mrchat-chatHeader" }, showBackButton && onBack && /* @__PURE__ */ import_react8.default.createElement(
5294
+ import_core7.ActionIcon,
5295
+ {
5296
+ variant: "subtle",
5297
+ className: "mrchat-backButton",
5298
+ onClick: onBack
5299
+ },
5300
+ /* @__PURE__ */ import_react8.default.createElement(import_icons_react3.IconArrowLeft, { size: 20 })
5301
+ ), receiverDetails && /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement(
5261
5302
  "div",
5262
5303
  {
5263
5304
  className: "mrchat-receiverInfo",
@@ -5423,6 +5464,8 @@ function ChatUserList({
5423
5464
  const [searchResults, setSearchResults] = (0, import_react10.useState)([]);
5424
5465
  const [isSearching, setIsSearching] = (0, import_react10.useState)(false);
5425
5466
  const [senderDetails, setSenderDetails] = (0, import_react10.useState)(currentUser);
5467
+ const [isMobile, setIsMobile] = (0, import_react10.useState)(false);
5468
+ const [mobileChatOpen, setMobileChatOpen] = (0, import_react10.useState)(false);
5426
5469
  (0, import_react10.useEffect)(() => {
5427
5470
  if (!currentUser?.userId) return;
5428
5471
  setSenderDetails(currentUser);
@@ -5431,6 +5474,30 @@ function ChatUserList({
5431
5474
  if (!currentUser?.userId) return;
5432
5475
  dispatch(fetchMessageListByUserId({ userId: currentUser.userId, page: 0 }));
5433
5476
  }, [currentUser?.userId, dispatch]);
5477
+ (0, import_react10.useEffect)(() => {
5478
+ if (typeof window === "undefined") return;
5479
+ const mediaQuery = window.matchMedia("(max-width: 599px)");
5480
+ const handleMediaChange = (event) => {
5481
+ const matches = "matches" in event ? event.matches : mediaQuery.matches;
5482
+ setIsMobile(matches);
5483
+ if (!matches) {
5484
+ setMobileChatOpen(false);
5485
+ }
5486
+ };
5487
+ handleMediaChange(mediaQuery);
5488
+ if (mediaQuery.addEventListener) {
5489
+ mediaQuery.addEventListener("change", handleMediaChange);
5490
+ } else {
5491
+ mediaQuery.addListener(handleMediaChange);
5492
+ }
5493
+ return () => {
5494
+ if (mediaQuery.removeEventListener) {
5495
+ mediaQuery.removeEventListener("change", handleMediaChange);
5496
+ } else {
5497
+ mediaQuery.removeListener(handleMediaChange);
5498
+ }
5499
+ };
5500
+ }, []);
5434
5501
  const handleStartChat = () => {
5435
5502
  if (!receiverUserDetails?.userId) return;
5436
5503
  const existingChat = chatList?.rows?.data?.find(
@@ -5456,6 +5523,9 @@ function ChatUserList({
5456
5523
  dispatch(resetMessageList());
5457
5524
  setChatId("");
5458
5525
  setEnableChat(true);
5526
+ if (isMobile) {
5527
+ setMobileChatOpen(true);
5528
+ }
5459
5529
  };
5460
5530
  (0, import_react10.useEffect)(() => {
5461
5531
  if (!senderDetails?.userId) return;
@@ -5557,6 +5627,9 @@ function ChatUserList({
5557
5627
  const updatedList = chatList.rows.data.map(
5558
5628
  (chat) => chat.chatId === item.chatId ? { ...chat, unreadCount: 0 } : chat
5559
5629
  );
5630
+ if (isMobile) {
5631
+ setMobileChatOpen(true);
5632
+ }
5560
5633
  dispatch(
5561
5634
  setMessagedUserList({
5562
5635
  ...chatList,
@@ -5570,6 +5643,9 @@ function ChatUserList({
5570
5643
  const handleSearchUsers = (value) => {
5571
5644
  setReceiverSearchValue(value);
5572
5645
  };
5646
+ const handleBackToSidebar = () => {
5647
+ setMobileChatOpen(false);
5648
+ };
5573
5649
  (0, import_react10.useEffect)(() => {
5574
5650
  if (!receiverSearchValue.trim()) {
5575
5651
  setSearchResults([]);
@@ -5660,89 +5736,121 @@ function ChatUserList({
5660
5736
  },
5661
5737
  "Start Chat"
5662
5738
  )
5663
- ), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-chatContainer" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-sidebar" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-sidebarTop" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-topBar" }, /* @__PURE__ */ import_react10.default.createElement(import_core8.Text, { size: "xs", c: "dimmed", mt: "sm", mb: "xs", ml: 12 }, "All Messages"), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-topActions" }, /* @__PURE__ */ import_react10.default.createElement(
5664
- import_core8.ActionIcon,
5739
+ ), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-chatContainer" }, /* @__PURE__ */ import_react10.default.createElement(
5740
+ "div",
5665
5741
  {
5666
- variant: "subtle",
5667
- onClick: () => {
5668
- setReceiverUserDetails(null);
5669
- setReceiverSearchValue("");
5670
- setSearchResults([]);
5671
- open();
5672
- },
5673
- radius: "lg"
5742
+ className: "mrchat-sidebar " + (isMobile && mobileChatOpen ? "mrchat-hiddenOnMobile" : "")
5674
5743
  },
5675
- /* @__PURE__ */ import_react10.default.createElement(import_icons_react4.IconPlus, { size: 20, stroke: 3 })
5676
- )))), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-scrollWrapper" }, /* @__PURE__ */ import_react10.default.createElement(
5677
- VirtualizedList,
5678
- {
5679
- data: chatList?.rows?.data || [],
5680
- endReached: loadMoreChats,
5681
- itemContent: (_, item) => {
5682
- const isActive = item.chatId === chatId;
5683
- return /* @__PURE__ */ import_react10.default.createElement(
5684
- "div",
5685
- {
5686
- className: `${"mrchat-chatItem"} ${isActive ? "mrchat-activeChatItem" : ""}`,
5687
- onClick: () => {
5688
- if (isActive) return;
5689
- handleJoinChat(item);
5690
- }
5691
- },
5692
- item.avatar ? /* @__PURE__ */ import_react10.default.createElement(import_core8.Avatar, { src: item.avatar, size: 36, radius: "xl" }) : /* @__PURE__ */ import_react10.default.createElement(
5693
- import_core8.Avatar,
5694
- {
5695
- key: item.displayName || item.username,
5696
- name: item.displayName || item.username,
5697
- color: "initials"
5698
- }
5699
- ),
5700
- /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-chatInfo" }, /* @__PURE__ */ import_react10.default.createElement(import_core8.Text, { className: "mrchat-chatLabelItem", truncate: true }, item.displayName || item.username), item.unreadCount > 0 && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-unreadBadge" }, item.unreadCount || 10), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-messagePreview" }, /* @__PURE__ */ import_react10.default.createElement(
5701
- import_core8.Text,
5702
- {
5703
- truncate: true,
5704
- size: "xs",
5705
- c: "dimmed",
5706
- style: { maxWidth: 150 },
5707
- className: "mrchat-messagePreviewContent"
5708
- },
5709
- stripHtml(import_dompurify2.default.sanitize(item.message))
5710
- ), /* @__PURE__ */ import_react10.default.createElement(
5711
- import_core8.Text,
5744
+ /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-sidebarTop" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-topBar" }, /* @__PURE__ */ import_react10.default.createElement(import_core8.Text, { size: "xs", c: "dimmed", mt: "sm", mb: "xs", ml: 12 }, "All Messages"), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-topActions" }, /* @__PURE__ */ import_react10.default.createElement(
5745
+ import_core8.ActionIcon,
5746
+ {
5747
+ variant: "subtle",
5748
+ onClick: () => {
5749
+ setReceiverUserDetails(null);
5750
+ setReceiverSearchValue("");
5751
+ setSearchResults([]);
5752
+ open();
5753
+ },
5754
+ radius: "lg"
5755
+ },
5756
+ /* @__PURE__ */ import_react10.default.createElement(import_icons_react4.IconPlus, { size: 20, stroke: 3 })
5757
+ )))),
5758
+ /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-scrollWrapper" }, /* @__PURE__ */ import_react10.default.createElement(
5759
+ VirtualizedList,
5760
+ {
5761
+ data: chatList?.rows?.data || [],
5762
+ endReached: loadMoreChats,
5763
+ itemContent: (_, item) => {
5764
+ const isActive = item.chatId === chatId;
5765
+ return /* @__PURE__ */ import_react10.default.createElement(
5766
+ "div",
5712
5767
  {
5713
- size: "xs",
5714
- c: "dimmed",
5715
- className: "mrchat-messagePreviewTime"
5768
+ className: `${"mrchat-chatItem"} ${isActive ? "mrchat-activeChatItem" : ""}`,
5769
+ onClick: () => {
5770
+ if (isActive) return;
5771
+ handleJoinChat(item);
5772
+ }
5716
5773
  },
5717
- getChatDisplayTime(item.updatedAt || item.createdAt)
5718
- )))
5719
- );
5774
+ item.avatar ? /* @__PURE__ */ import_react10.default.createElement(import_core8.Avatar, { src: item.avatar, size: 36, radius: "xl" }) : /* @__PURE__ */ import_react10.default.createElement(
5775
+ import_core8.Avatar,
5776
+ {
5777
+ key: item.displayName || item.username,
5778
+ name: item.displayName || item.username,
5779
+ color: "initials"
5780
+ }
5781
+ ),
5782
+ /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-chatInfo" }, /* @__PURE__ */ import_react10.default.createElement(import_core8.Text, { className: "mrchat-chatLabelItem", truncate: true }, item.displayName || item.username), item.unreadCount > 0 && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-unreadBadge" }, item.unreadCount || 10), /* @__PURE__ */ import_react10.default.createElement("div", { className: "mrchat-messagePreview" }, /* @__PURE__ */ import_react10.default.createElement(
5783
+ import_core8.Text,
5784
+ {
5785
+ truncate: true,
5786
+ size: "xs",
5787
+ c: "dimmed",
5788
+ style: { maxWidth: 150 },
5789
+ className: "mrchat-messagePreviewContent"
5790
+ },
5791
+ stripHtml(import_dompurify2.default.sanitize(item.message))
5792
+ ), /* @__PURE__ */ import_react10.default.createElement(
5793
+ import_core8.Text,
5794
+ {
5795
+ size: "xs",
5796
+ c: "dimmed",
5797
+ className: "mrchat-messagePreviewTime"
5798
+ },
5799
+ getChatDisplayTime(item.updatedAt || item.createdAt)
5800
+ )))
5801
+ );
5802
+ }
5720
5803
  }
5721
- }
5722
- ))), /* @__PURE__ */ import_react10.default.createElement(
5723
- ChatUserMessage,
5804
+ ))
5805
+ ), /* @__PURE__ */ import_react10.default.createElement(
5806
+ "div",
5724
5807
  {
5725
- chatId,
5726
- enableChat,
5727
- senderDetails,
5728
- receiverDetails,
5729
- onChatInitialized: (data2) => {
5730
- handleJoinChat({
5731
- chatId: data2.chatId,
5732
- userId: receiverDetails?.userId,
5733
- username: receiverDetails?.username,
5734
- displayName: receiverDetails?.displayName,
5735
- avatar: receiverDetails?.avatar
5736
- });
5808
+ className: "mrchat-mainAreaWrapper " + (isMobile && !mobileChatOpen ? "mrchat-hiddenOnMobile" : "")
5809
+ },
5810
+ /* @__PURE__ */ import_react10.default.createElement(
5811
+ ChatUserMessage,
5812
+ {
5813
+ chatId,
5814
+ enableChat,
5815
+ senderDetails,
5816
+ receiverDetails,
5817
+ onBack: handleBackToSidebar,
5818
+ showBackButton: isMobile,
5819
+ onChatInitialized: (data2) => {
5820
+ handleJoinChat({
5821
+ chatId: data2.chatId,
5822
+ userId: receiverDetails?.userId,
5823
+ username: receiverDetails?.username,
5824
+ displayName: receiverDetails?.displayName,
5825
+ avatar: receiverDetails?.avatar
5826
+ });
5827
+ }
5737
5828
  }
5738
- }
5829
+ )
5739
5830
  )));
5740
5831
  }
5741
5832
 
5742
5833
  // src/components/MrChat/index.tsx
5743
- function MrChat({ colorScheme, ...props }) {
5744
- const [primaryColor, setPrimaryColor] = (0, import_react11.useState)("customBrand");
5834
+ function MrChat({
5835
+ colorScheme,
5836
+ primaryColor = "customBrand",
5837
+ darkColor,
5838
+ ...props
5839
+ }) {
5745
5840
  const theme = createAppTheme(primaryColor);
5841
+ (0, import_react11.useEffect)(() => {
5842
+ if (typeof document === "undefined" || !darkColor) return;
5843
+ const previousBodyBackground = document.body.style.backgroundColor;
5844
+ document.body.style.backgroundColor = colorScheme === "dark" ? darkColor : "";
5845
+ document.documentElement.style.setProperty(
5846
+ "--mantine-color-body",
5847
+ colorScheme === "dark" ? darkColor : ""
5848
+ );
5849
+ return () => {
5850
+ document.body.style.backgroundColor = previousBodyBackground;
5851
+ document.documentElement.style.removeProperty("--mantine-color-body");
5852
+ };
5853
+ }, [colorScheme, darkColor]);
5746
5854
  return /* @__PURE__ */ import_react11.default.createElement(ReduxProvider, null, /* @__PURE__ */ import_react11.default.createElement(SocketProvider, null, /* @__PURE__ */ import_react11.default.createElement(
5747
5855
  import_core9.MantineProvider,
5748
5856
  {
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import "@mantine/core/styles.css";
3
3
  import "@mantine/tiptap/styles.css";
4
4
  import "@mantine/notifications/styles.css";
5
- import React10, { useState as useState6 } from "react";
5
+ import React10, { useEffect as useEffect6 } from "react";
6
6
  import { MantineProvider } from "@mantine/core";
7
7
  import { Notifications } from "@mantine/notifications";
8
8
 
@@ -75,12 +75,43 @@ var colorThemes = {
75
75
  sunset,
76
76
  ocean
77
77
  };
78
- var createAppTheme = (primaryColor) => createTheme({
79
- primaryColor,
80
- colors: {
78
+ var isValidHexColor = (value) => /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test(value);
79
+ var hexToRgb = (hex) => {
80
+ const normalized = hex.replace("#", "");
81
+ const fullHex = normalized.length === 3 ? normalized.split("").map((digit) => digit + digit).join("") : normalized;
82
+ return {
83
+ r: parseInt(fullHex.slice(0, 2), 16),
84
+ g: parseInt(fullHex.slice(2, 4), 16),
85
+ b: parseInt(fullHex.slice(4, 6), 16)
86
+ };
87
+ };
88
+ var rgbToHex = ({ r, g, b }) => `#${[r, g, b].map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
89
+ var clampColor = (value) => Math.min(255, Math.max(0, Math.round(value)));
90
+ var createColorPaletteFromHex = (hex) => {
91
+ const { r, g, b } = hexToRgb(hex);
92
+ const factors = [0.08, 0.18, 0.3, 0.42, 0.54, 0.66, 0.76, 0.86, 0.92, 0.98];
93
+ const palette = factors.map(
94
+ (factor) => rgbToHex({
95
+ r: clampColor(r * factor + 255 * (1 - factor)),
96
+ g: clampColor(g * factor + 255 * (1 - factor)),
97
+ b: clampColor(b * factor + 255 * (1 - factor))
98
+ })
99
+ );
100
+ return palette;
101
+ };
102
+ var createAppTheme = (primaryColor) => {
103
+ const colors = {
81
104
  ...colorThemes
105
+ };
106
+ const resolvedPrimaryColor = isValidHexColor(primaryColor) || !(primaryColor in colorThemes) ? "customBrand" : primaryColor;
107
+ if (isValidHexColor(primaryColor)) {
108
+ colors.customBrand = createColorPaletteFromHex(primaryColor);
82
109
  }
83
- });
110
+ return createTheme({
111
+ primaryColor: resolvedPrimaryColor,
112
+ colors
113
+ });
114
+ };
84
115
 
85
116
  // src/store/provider.tsx
86
117
  import React from "react";
@@ -346,7 +377,7 @@ import {
346
377
  Text as Text3,
347
378
  Modal,
348
379
  Button,
349
- ActionIcon as ActionIcon2,
380
+ ActionIcon as ActionIcon3,
350
381
  Autocomplete,
351
382
  Group,
352
383
  Avatar as Avatar3,
@@ -356,8 +387,9 @@ import { IconPlus } from "@tabler/icons-react";
356
387
  import { useDisclosure } from "@mantine/hooks";
357
388
 
358
389
  // src/components/ChatUserList/ChatUserMessage.tsx
359
- import { Text as Text2, Avatar as Avatar2 } from "@mantine/core";
390
+ import { Text as Text2, Avatar as Avatar2, ActionIcon as ActionIcon2 } from "@mantine/core";
360
391
  import {
392
+ IconArrowLeft as IconArrowLeft2,
361
393
  IconLock
362
394
  } from "@tabler/icons-react";
363
395
 
@@ -5110,7 +5142,9 @@ function ChatUserMessage({
5110
5142
  enableChat,
5111
5143
  senderDetails,
5112
5144
  receiverDetails,
5113
- onChatInitialized
5145
+ onChatInitialized,
5146
+ onBack,
5147
+ showBackButton
5114
5148
  }) {
5115
5149
  const dispatch = useDispatch();
5116
5150
  const messageList = useSelector(
@@ -5251,7 +5285,15 @@ function ChatUserMessage({
5251
5285
  deleteMessagesByChatId({ chatId, userId: senderDetails?.userId })
5252
5286
  );
5253
5287
  };
5254
- return /* @__PURE__ */ React7.createElement("div", { className: "mrchat-mainArea" }, /* @__PURE__ */ React7.createElement("div", { className: "mrchat-chatHeader" }, receiverDetails && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
5288
+ return /* @__PURE__ */ React7.createElement("div", { className: "mrchat-mainArea" }, /* @__PURE__ */ React7.createElement("div", { className: "mrchat-chatHeader" }, showBackButton && onBack && /* @__PURE__ */ React7.createElement(
5289
+ ActionIcon2,
5290
+ {
5291
+ variant: "subtle",
5292
+ className: "mrchat-backButton",
5293
+ onClick: onBack
5294
+ },
5295
+ /* @__PURE__ */ React7.createElement(IconArrowLeft2, { size: 20 })
5296
+ ), receiverDetails && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
5255
5297
  "div",
5256
5298
  {
5257
5299
  className: "mrchat-receiverInfo",
@@ -5417,6 +5459,8 @@ function ChatUserList({
5417
5459
  const [searchResults, setSearchResults] = useState5([]);
5418
5460
  const [isSearching, setIsSearching] = useState5(false);
5419
5461
  const [senderDetails, setSenderDetails] = useState5(currentUser);
5462
+ const [isMobile, setIsMobile] = useState5(false);
5463
+ const [mobileChatOpen, setMobileChatOpen] = useState5(false);
5420
5464
  useEffect5(() => {
5421
5465
  if (!currentUser?.userId) return;
5422
5466
  setSenderDetails(currentUser);
@@ -5425,6 +5469,30 @@ function ChatUserList({
5425
5469
  if (!currentUser?.userId) return;
5426
5470
  dispatch(fetchMessageListByUserId({ userId: currentUser.userId, page: 0 }));
5427
5471
  }, [currentUser?.userId, dispatch]);
5472
+ useEffect5(() => {
5473
+ if (typeof window === "undefined") return;
5474
+ const mediaQuery = window.matchMedia("(max-width: 599px)");
5475
+ const handleMediaChange = (event) => {
5476
+ const matches = "matches" in event ? event.matches : mediaQuery.matches;
5477
+ setIsMobile(matches);
5478
+ if (!matches) {
5479
+ setMobileChatOpen(false);
5480
+ }
5481
+ };
5482
+ handleMediaChange(mediaQuery);
5483
+ if (mediaQuery.addEventListener) {
5484
+ mediaQuery.addEventListener("change", handleMediaChange);
5485
+ } else {
5486
+ mediaQuery.addListener(handleMediaChange);
5487
+ }
5488
+ return () => {
5489
+ if (mediaQuery.removeEventListener) {
5490
+ mediaQuery.removeEventListener("change", handleMediaChange);
5491
+ } else {
5492
+ mediaQuery.removeListener(handleMediaChange);
5493
+ }
5494
+ };
5495
+ }, []);
5428
5496
  const handleStartChat = () => {
5429
5497
  if (!receiverUserDetails?.userId) return;
5430
5498
  const existingChat = chatList?.rows?.data?.find(
@@ -5450,6 +5518,9 @@ function ChatUserList({
5450
5518
  dispatch(resetMessageList());
5451
5519
  setChatId("");
5452
5520
  setEnableChat(true);
5521
+ if (isMobile) {
5522
+ setMobileChatOpen(true);
5523
+ }
5453
5524
  };
5454
5525
  useEffect5(() => {
5455
5526
  if (!senderDetails?.userId) return;
@@ -5551,6 +5622,9 @@ function ChatUserList({
5551
5622
  const updatedList = chatList.rows.data.map(
5552
5623
  (chat) => chat.chatId === item.chatId ? { ...chat, unreadCount: 0 } : chat
5553
5624
  );
5625
+ if (isMobile) {
5626
+ setMobileChatOpen(true);
5627
+ }
5554
5628
  dispatch(
5555
5629
  setMessagedUserList({
5556
5630
  ...chatList,
@@ -5564,6 +5638,9 @@ function ChatUserList({
5564
5638
  const handleSearchUsers = (value) => {
5565
5639
  setReceiverSearchValue(value);
5566
5640
  };
5641
+ const handleBackToSidebar = () => {
5642
+ setMobileChatOpen(false);
5643
+ };
5567
5644
  useEffect5(() => {
5568
5645
  if (!receiverSearchValue.trim()) {
5569
5646
  setSearchResults([]);
@@ -5654,89 +5731,121 @@ function ChatUserList({
5654
5731
  },
5655
5732
  "Start Chat"
5656
5733
  )
5657
- ), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-chatContainer" }, /* @__PURE__ */ React9.createElement("div", { className: "mrchat-sidebar" }, /* @__PURE__ */ React9.createElement("div", { className: "mrchat-sidebarTop" }, /* @__PURE__ */ React9.createElement("div", { className: "mrchat-topBar" }, /* @__PURE__ */ React9.createElement(Text3, { size: "xs", c: "dimmed", mt: "sm", mb: "xs", ml: 12 }, "All Messages"), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-topActions" }, /* @__PURE__ */ React9.createElement(
5658
- ActionIcon2,
5734
+ ), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-chatContainer" }, /* @__PURE__ */ React9.createElement(
5735
+ "div",
5659
5736
  {
5660
- variant: "subtle",
5661
- onClick: () => {
5662
- setReceiverUserDetails(null);
5663
- setReceiverSearchValue("");
5664
- setSearchResults([]);
5665
- open();
5666
- },
5667
- radius: "lg"
5737
+ className: "mrchat-sidebar " + (isMobile && mobileChatOpen ? "mrchat-hiddenOnMobile" : "")
5668
5738
  },
5669
- /* @__PURE__ */ React9.createElement(IconPlus, { size: 20, stroke: 3 })
5670
- )))), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-scrollWrapper" }, /* @__PURE__ */ React9.createElement(
5671
- VirtualizedList,
5672
- {
5673
- data: chatList?.rows?.data || [],
5674
- endReached: loadMoreChats,
5675
- itemContent: (_, item) => {
5676
- const isActive = item.chatId === chatId;
5677
- return /* @__PURE__ */ React9.createElement(
5678
- "div",
5679
- {
5680
- className: `${"mrchat-chatItem"} ${isActive ? "mrchat-activeChatItem" : ""}`,
5681
- onClick: () => {
5682
- if (isActive) return;
5683
- handleJoinChat(item);
5684
- }
5685
- },
5686
- item.avatar ? /* @__PURE__ */ React9.createElement(Avatar3, { src: item.avatar, size: 36, radius: "xl" }) : /* @__PURE__ */ React9.createElement(
5687
- Avatar3,
5688
- {
5689
- key: item.displayName || item.username,
5690
- name: item.displayName || item.username,
5691
- color: "initials"
5692
- }
5693
- ),
5694
- /* @__PURE__ */ React9.createElement("div", { className: "mrchat-chatInfo" }, /* @__PURE__ */ React9.createElement(Text3, { className: "mrchat-chatLabelItem", truncate: true }, item.displayName || item.username), item.unreadCount > 0 && /* @__PURE__ */ React9.createElement("div", { className: "mrchat-unreadBadge" }, item.unreadCount || 10), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-messagePreview" }, /* @__PURE__ */ React9.createElement(
5695
- Text3,
5696
- {
5697
- truncate: true,
5698
- size: "xs",
5699
- c: "dimmed",
5700
- style: { maxWidth: 150 },
5701
- className: "mrchat-messagePreviewContent"
5702
- },
5703
- stripHtml(DOMPurify2.sanitize(item.message))
5704
- ), /* @__PURE__ */ React9.createElement(
5705
- Text3,
5739
+ /* @__PURE__ */ React9.createElement("div", { className: "mrchat-sidebarTop" }, /* @__PURE__ */ React9.createElement("div", { className: "mrchat-topBar" }, /* @__PURE__ */ React9.createElement(Text3, { size: "xs", c: "dimmed", mt: "sm", mb: "xs", ml: 12 }, "All Messages"), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-topActions" }, /* @__PURE__ */ React9.createElement(
5740
+ ActionIcon3,
5741
+ {
5742
+ variant: "subtle",
5743
+ onClick: () => {
5744
+ setReceiverUserDetails(null);
5745
+ setReceiverSearchValue("");
5746
+ setSearchResults([]);
5747
+ open();
5748
+ },
5749
+ radius: "lg"
5750
+ },
5751
+ /* @__PURE__ */ React9.createElement(IconPlus, { size: 20, stroke: 3 })
5752
+ )))),
5753
+ /* @__PURE__ */ React9.createElement("div", { className: "mrchat-scrollWrapper" }, /* @__PURE__ */ React9.createElement(
5754
+ VirtualizedList,
5755
+ {
5756
+ data: chatList?.rows?.data || [],
5757
+ endReached: loadMoreChats,
5758
+ itemContent: (_, item) => {
5759
+ const isActive = item.chatId === chatId;
5760
+ return /* @__PURE__ */ React9.createElement(
5761
+ "div",
5706
5762
  {
5707
- size: "xs",
5708
- c: "dimmed",
5709
- className: "mrchat-messagePreviewTime"
5763
+ className: `${"mrchat-chatItem"} ${isActive ? "mrchat-activeChatItem" : ""}`,
5764
+ onClick: () => {
5765
+ if (isActive) return;
5766
+ handleJoinChat(item);
5767
+ }
5710
5768
  },
5711
- getChatDisplayTime(item.updatedAt || item.createdAt)
5712
- )))
5713
- );
5769
+ item.avatar ? /* @__PURE__ */ React9.createElement(Avatar3, { src: item.avatar, size: 36, radius: "xl" }) : /* @__PURE__ */ React9.createElement(
5770
+ Avatar3,
5771
+ {
5772
+ key: item.displayName || item.username,
5773
+ name: item.displayName || item.username,
5774
+ color: "initials"
5775
+ }
5776
+ ),
5777
+ /* @__PURE__ */ React9.createElement("div", { className: "mrchat-chatInfo" }, /* @__PURE__ */ React9.createElement(Text3, { className: "mrchat-chatLabelItem", truncate: true }, item.displayName || item.username), item.unreadCount > 0 && /* @__PURE__ */ React9.createElement("div", { className: "mrchat-unreadBadge" }, item.unreadCount || 10), /* @__PURE__ */ React9.createElement("div", { className: "mrchat-messagePreview" }, /* @__PURE__ */ React9.createElement(
5778
+ Text3,
5779
+ {
5780
+ truncate: true,
5781
+ size: "xs",
5782
+ c: "dimmed",
5783
+ style: { maxWidth: 150 },
5784
+ className: "mrchat-messagePreviewContent"
5785
+ },
5786
+ stripHtml(DOMPurify2.sanitize(item.message))
5787
+ ), /* @__PURE__ */ React9.createElement(
5788
+ Text3,
5789
+ {
5790
+ size: "xs",
5791
+ c: "dimmed",
5792
+ className: "mrchat-messagePreviewTime"
5793
+ },
5794
+ getChatDisplayTime(item.updatedAt || item.createdAt)
5795
+ )))
5796
+ );
5797
+ }
5714
5798
  }
5715
- }
5716
- ))), /* @__PURE__ */ React9.createElement(
5717
- ChatUserMessage,
5799
+ ))
5800
+ ), /* @__PURE__ */ React9.createElement(
5801
+ "div",
5718
5802
  {
5719
- chatId,
5720
- enableChat,
5721
- senderDetails,
5722
- receiverDetails,
5723
- onChatInitialized: (data2) => {
5724
- handleJoinChat({
5725
- chatId: data2.chatId,
5726
- userId: receiverDetails?.userId,
5727
- username: receiverDetails?.username,
5728
- displayName: receiverDetails?.displayName,
5729
- avatar: receiverDetails?.avatar
5730
- });
5803
+ className: "mrchat-mainAreaWrapper " + (isMobile && !mobileChatOpen ? "mrchat-hiddenOnMobile" : "")
5804
+ },
5805
+ /* @__PURE__ */ React9.createElement(
5806
+ ChatUserMessage,
5807
+ {
5808
+ chatId,
5809
+ enableChat,
5810
+ senderDetails,
5811
+ receiverDetails,
5812
+ onBack: handleBackToSidebar,
5813
+ showBackButton: isMobile,
5814
+ onChatInitialized: (data2) => {
5815
+ handleJoinChat({
5816
+ chatId: data2.chatId,
5817
+ userId: receiverDetails?.userId,
5818
+ username: receiverDetails?.username,
5819
+ displayName: receiverDetails?.displayName,
5820
+ avatar: receiverDetails?.avatar
5821
+ });
5822
+ }
5731
5823
  }
5732
- }
5824
+ )
5733
5825
  )));
5734
5826
  }
5735
5827
 
5736
5828
  // src/components/MrChat/index.tsx
5737
- function MrChat({ colorScheme, ...props }) {
5738
- const [primaryColor, setPrimaryColor] = useState6("customBrand");
5829
+ function MrChat({
5830
+ colorScheme,
5831
+ primaryColor = "customBrand",
5832
+ darkColor,
5833
+ ...props
5834
+ }) {
5739
5835
  const theme = createAppTheme(primaryColor);
5836
+ useEffect6(() => {
5837
+ if (typeof document === "undefined" || !darkColor) return;
5838
+ const previousBodyBackground = document.body.style.backgroundColor;
5839
+ document.body.style.backgroundColor = colorScheme === "dark" ? darkColor : "";
5840
+ document.documentElement.style.setProperty(
5841
+ "--mantine-color-body",
5842
+ colorScheme === "dark" ? darkColor : ""
5843
+ );
5844
+ return () => {
5845
+ document.body.style.backgroundColor = previousBodyBackground;
5846
+ document.documentElement.style.removeProperty("--mantine-color-body");
5847
+ };
5848
+ }, [colorScheme, darkColor]);
5740
5849
  return /* @__PURE__ */ React10.createElement(ReduxProvider, null, /* @__PURE__ */ React10.createElement(SocketProvider, null, /* @__PURE__ */ React10.createElement(
5741
5850
  MantineProvider,
5742
5851
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mr-chat-bird",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",