@diffsome/react 1.2.10 → 1.2.12

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.js CHANGED
@@ -2805,6 +2805,7 @@ var ChatWidget = ({
2805
2805
 
2806
2806
  // src/components/chat/ChatBubble.tsx
2807
2807
  var import_jsx_runtime6 = require("react/jsx-runtime");
2808
+ var STORAGE_KEY = "diffsome_conversation_id";
2808
2809
  var ChatBubble = ({
2809
2810
  client,
2810
2811
  title = "Chat Support",
@@ -2828,58 +2829,92 @@ var ChatBubble = ({
2828
2829
  const [loading, setLoading] = (0, import_react24.useState)(false);
2829
2830
  const [typing, setTyping] = (0, import_react24.useState)(false);
2830
2831
  const [unreadCount, setUnreadCount] = (0, import_react24.useState)(0);
2832
+ const [initialized, setInitialized] = (0, import_react24.useState)(false);
2831
2833
  const seenMessageIds = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
2834
+ const connectionRef = (0, import_react24.useRef)(null);
2835
+ const setupListeners = (0, import_react24.useCallback)((conn) => {
2836
+ conn.onMessage((msg) => {
2837
+ if (seenMessageIds.current.has(msg.id)) {
2838
+ return;
2839
+ }
2840
+ seenMessageIds.current.add(msg.id);
2841
+ setMessages((prev) => [...prev, msg]);
2842
+ if (msg.sender_type !== "visitor") {
2843
+ setUnreadCount((c) => c + 1);
2844
+ }
2845
+ });
2846
+ conn.onTyping((senderType) => {
2847
+ if (senderType === "agent") {
2848
+ setTyping(true);
2849
+ setTimeout(() => setTyping(false), 3e3);
2850
+ }
2851
+ });
2852
+ }, []);
2832
2853
  const initChat = (0, import_react24.useCallback)(async () => {
2833
- if (conversationId) return;
2854
+ if (initialized || connectionRef.current) return;
2834
2855
  setLoading(true);
2835
2856
  try {
2857
+ let savedConvId = null;
2858
+ if (typeof localStorage !== "undefined") {
2859
+ const saved = localStorage.getItem(STORAGE_KEY);
2860
+ if (saved) {
2861
+ savedConvId = parseInt(saved, 10);
2862
+ }
2863
+ }
2864
+ if (savedConvId) {
2865
+ try {
2866
+ const conn2 = client.chat.connect(savedConvId);
2867
+ connectionRef.current = conn2;
2868
+ setConnection(conn2);
2869
+ setupListeners(conn2);
2870
+ const existingMessages2 = await conn2.getMessages();
2871
+ existingMessages2.forEach((m) => seenMessageIds.current.add(m.id));
2872
+ setMessages(existingMessages2);
2873
+ setConversationId(savedConvId);
2874
+ setInitialized(true);
2875
+ return;
2876
+ } catch (error) {
2877
+ console.log("Could not restore conversation, starting new one");
2878
+ localStorage.removeItem(STORAGE_KEY);
2879
+ }
2880
+ }
2836
2881
  const result = await client.chat.start({
2837
2882
  visitor_name: visitorName,
2838
2883
  visitor_email: visitorEmail,
2839
2884
  initial_message: greeting
2840
2885
  });
2841
- setConversationId(result.conversation_id);
2842
- const conn = client.chat.connect(result.conversation_id);
2886
+ const newConvId = result.conversation_id;
2887
+ setConversationId(newConvId);
2888
+ if (typeof localStorage !== "undefined") {
2889
+ localStorage.setItem(STORAGE_KEY, newConvId.toString());
2890
+ }
2891
+ const conn = client.chat.connect(newConvId);
2892
+ connectionRef.current = conn;
2843
2893
  setConnection(conn);
2894
+ setupListeners(conn);
2844
2895
  const existingMessages = await conn.getMessages();
2845
2896
  existingMessages.forEach((m) => seenMessageIds.current.add(m.id));
2846
2897
  setMessages(existingMessages);
2847
- conn.onMessage((msg) => {
2848
- if (seenMessageIds.current.has(msg.id)) {
2849
- return;
2850
- }
2851
- seenMessageIds.current.add(msg.id);
2852
- setMessages((prev) => [...prev, msg]);
2853
- if (!isOpen && msg.sender_type !== "visitor") {
2854
- setUnreadCount((c) => c + 1);
2855
- }
2856
- });
2857
- conn.onTyping((senderType) => {
2858
- if (senderType === "agent") {
2859
- setTyping(true);
2860
- setTimeout(() => setTyping(false), 3e3);
2861
- }
2862
- });
2898
+ setInitialized(true);
2863
2899
  } catch (error) {
2864
2900
  console.error("Failed to initialize chat:", error);
2865
2901
  } finally {
2866
2902
  setLoading(false);
2867
2903
  }
2868
- }, [client.chat, conversationId, visitorName, visitorEmail, greeting, isOpen]);
2904
+ }, [client.chat, initialized, setupListeners, visitorName, visitorEmail, greeting]);
2869
2905
  const handleOpen = () => {
2870
2906
  setIsOpen(true);
2871
2907
  setUnreadCount(0);
2872
2908
  onOpen?.();
2873
- if (!conversationId) {
2874
- initChat();
2875
- }
2909
+ initChat();
2876
2910
  };
2877
2911
  const handleClose = () => {
2878
2912
  setIsOpen(false);
2879
2913
  onClose?.();
2880
2914
  };
2881
2915
  const handleSend = async (content) => {
2882
- if (!connection) return;
2916
+ const conn = connectionRef.current;
2917
+ if (!conn) return;
2883
2918
  const tempId = -Date.now();
2884
2919
  const pendingMessage = {
2885
2920
  id: tempId,
@@ -2890,7 +2925,7 @@ var ChatBubble = ({
2890
2925
  };
2891
2926
  setMessages((prev) => [...prev, pendingMessage]);
2892
2927
  try {
2893
- const sentMessage = await connection.send(content);
2928
+ const sentMessage = await conn.send(content);
2894
2929
  if (sentMessage) {
2895
2930
  seenMessageIds.current.add(sentMessage.id);
2896
2931
  setMessages(
@@ -2905,13 +2940,13 @@ var ChatBubble = ({
2905
2940
  }
2906
2941
  };
2907
2942
  const handleTyping = () => {
2908
- connection?.sendTyping();
2943
+ connectionRef.current?.sendTyping();
2909
2944
  };
2910
2945
  (0, import_react24.useEffect)(() => {
2911
2946
  return () => {
2912
- connection?.disconnect();
2947
+ connectionRef.current?.disconnect();
2913
2948
  };
2914
- }, [connection]);
2949
+ }, []);
2915
2950
  const positionClass = position === "bottom-left" ? "diffsome-chat-bubble-left" : "diffsome-chat-bubble-right";
2916
2951
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2917
2952
  "div",
package/dist/index.mjs CHANGED
@@ -2713,6 +2713,7 @@ var ChatWidget = ({
2713
2713
 
2714
2714
  // src/components/chat/ChatBubble.tsx
2715
2715
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2716
+ var STORAGE_KEY = "diffsome_conversation_id";
2716
2717
  var ChatBubble = ({
2717
2718
  client,
2718
2719
  title = "Chat Support",
@@ -2736,58 +2737,92 @@ var ChatBubble = ({
2736
2737
  const [loading, setLoading] = useState22(false);
2737
2738
  const [typing, setTyping] = useState22(false);
2738
2739
  const [unreadCount, setUnreadCount] = useState22(0);
2740
+ const [initialized, setInitialized] = useState22(false);
2739
2741
  const seenMessageIds = useRef3(/* @__PURE__ */ new Set());
2742
+ const connectionRef = useRef3(null);
2743
+ const setupListeners = useCallback22((conn) => {
2744
+ conn.onMessage((msg) => {
2745
+ if (seenMessageIds.current.has(msg.id)) {
2746
+ return;
2747
+ }
2748
+ seenMessageIds.current.add(msg.id);
2749
+ setMessages((prev) => [...prev, msg]);
2750
+ if (msg.sender_type !== "visitor") {
2751
+ setUnreadCount((c) => c + 1);
2752
+ }
2753
+ });
2754
+ conn.onTyping((senderType) => {
2755
+ if (senderType === "agent") {
2756
+ setTyping(true);
2757
+ setTimeout(() => setTyping(false), 3e3);
2758
+ }
2759
+ });
2760
+ }, []);
2740
2761
  const initChat = useCallback22(async () => {
2741
- if (conversationId) return;
2762
+ if (initialized || connectionRef.current) return;
2742
2763
  setLoading(true);
2743
2764
  try {
2765
+ let savedConvId = null;
2766
+ if (typeof localStorage !== "undefined") {
2767
+ const saved = localStorage.getItem(STORAGE_KEY);
2768
+ if (saved) {
2769
+ savedConvId = parseInt(saved, 10);
2770
+ }
2771
+ }
2772
+ if (savedConvId) {
2773
+ try {
2774
+ const conn2 = client.chat.connect(savedConvId);
2775
+ connectionRef.current = conn2;
2776
+ setConnection(conn2);
2777
+ setupListeners(conn2);
2778
+ const existingMessages2 = await conn2.getMessages();
2779
+ existingMessages2.forEach((m) => seenMessageIds.current.add(m.id));
2780
+ setMessages(existingMessages2);
2781
+ setConversationId(savedConvId);
2782
+ setInitialized(true);
2783
+ return;
2784
+ } catch (error) {
2785
+ console.log("Could not restore conversation, starting new one");
2786
+ localStorage.removeItem(STORAGE_KEY);
2787
+ }
2788
+ }
2744
2789
  const result = await client.chat.start({
2745
2790
  visitor_name: visitorName,
2746
2791
  visitor_email: visitorEmail,
2747
2792
  initial_message: greeting
2748
2793
  });
2749
- setConversationId(result.conversation_id);
2750
- const conn = client.chat.connect(result.conversation_id);
2794
+ const newConvId = result.conversation_id;
2795
+ setConversationId(newConvId);
2796
+ if (typeof localStorage !== "undefined") {
2797
+ localStorage.setItem(STORAGE_KEY, newConvId.toString());
2798
+ }
2799
+ const conn = client.chat.connect(newConvId);
2800
+ connectionRef.current = conn;
2751
2801
  setConnection(conn);
2802
+ setupListeners(conn);
2752
2803
  const existingMessages = await conn.getMessages();
2753
2804
  existingMessages.forEach((m) => seenMessageIds.current.add(m.id));
2754
2805
  setMessages(existingMessages);
2755
- conn.onMessage((msg) => {
2756
- if (seenMessageIds.current.has(msg.id)) {
2757
- return;
2758
- }
2759
- seenMessageIds.current.add(msg.id);
2760
- setMessages((prev) => [...prev, msg]);
2761
- if (!isOpen && msg.sender_type !== "visitor") {
2762
- setUnreadCount((c) => c + 1);
2763
- }
2764
- });
2765
- conn.onTyping((senderType) => {
2766
- if (senderType === "agent") {
2767
- setTyping(true);
2768
- setTimeout(() => setTyping(false), 3e3);
2769
- }
2770
- });
2806
+ setInitialized(true);
2771
2807
  } catch (error) {
2772
2808
  console.error("Failed to initialize chat:", error);
2773
2809
  } finally {
2774
2810
  setLoading(false);
2775
2811
  }
2776
- }, [client.chat, conversationId, visitorName, visitorEmail, greeting, isOpen]);
2812
+ }, [client.chat, initialized, setupListeners, visitorName, visitorEmail, greeting]);
2777
2813
  const handleOpen = () => {
2778
2814
  setIsOpen(true);
2779
2815
  setUnreadCount(0);
2780
2816
  onOpen?.();
2781
- if (!conversationId) {
2782
- initChat();
2783
- }
2817
+ initChat();
2784
2818
  };
2785
2819
  const handleClose = () => {
2786
2820
  setIsOpen(false);
2787
2821
  onClose?.();
2788
2822
  };
2789
2823
  const handleSend = async (content) => {
2790
- if (!connection) return;
2824
+ const conn = connectionRef.current;
2825
+ if (!conn) return;
2791
2826
  const tempId = -Date.now();
2792
2827
  const pendingMessage = {
2793
2828
  id: tempId,
@@ -2798,7 +2833,7 @@ var ChatBubble = ({
2798
2833
  };
2799
2834
  setMessages((prev) => [...prev, pendingMessage]);
2800
2835
  try {
2801
- const sentMessage = await connection.send(content);
2836
+ const sentMessage = await conn.send(content);
2802
2837
  if (sentMessage) {
2803
2838
  seenMessageIds.current.add(sentMessage.id);
2804
2839
  setMessages(
@@ -2813,13 +2848,13 @@ var ChatBubble = ({
2813
2848
  }
2814
2849
  };
2815
2850
  const handleTyping = () => {
2816
- connection?.sendTyping();
2851
+ connectionRef.current?.sendTyping();
2817
2852
  };
2818
2853
  useEffect21(() => {
2819
2854
  return () => {
2820
- connection?.disconnect();
2855
+ connectionRef.current?.disconnect();
2821
2856
  };
2822
- }, [connection]);
2857
+ }, []);
2823
2858
  const positionClass = position === "bottom-left" ? "diffsome-chat-bubble-left" : "diffsome-chat-bubble-right";
2824
2859
  return /* @__PURE__ */ jsxs5(
2825
2860
  "div",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diffsome/react",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "description": "React hooks and providers for Diffsome SDK - Headless e-commerce & CMS",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",