vdb-ai-chat 1.0.3 → 1.0.5

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 (35) hide show
  1. package/dist/chat-widget.js +1 -1
  2. package/lib/commonjs/api.js +19 -4
  3. package/lib/commonjs/api.js.map +1 -1
  4. package/lib/commonjs/components/ChatWidget.js +27 -13
  5. package/lib/commonjs/components/ChatWidget.js.map +1 -1
  6. package/lib/commonjs/components/LazyProductsFetcher.js +3 -2
  7. package/lib/commonjs/components/LazyProductsFetcher.js.map +1 -1
  8. package/lib/commonjs/components/utils.js +38 -2
  9. package/lib/commonjs/components/utils.js.map +1 -1
  10. package/lib/commonjs/storage.js +13 -0
  11. package/lib/commonjs/storage.js.map +1 -1
  12. package/lib/module/api.js +19 -4
  13. package/lib/module/api.js.map +1 -1
  14. package/lib/module/components/ChatWidget.js +28 -14
  15. package/lib/module/components/ChatWidget.js.map +1 -1
  16. package/lib/module/components/LazyProductsFetcher.js +3 -2
  17. package/lib/module/components/LazyProductsFetcher.js.map +1 -1
  18. package/lib/module/components/utils.js +34 -0
  19. package/lib/module/components/utils.js.map +1 -1
  20. package/lib/module/storage.js +13 -0
  21. package/lib/module/storage.js.map +1 -1
  22. package/lib/typescript/api.d.ts +1 -1
  23. package/lib/typescript/api.d.ts.map +1 -1
  24. package/lib/typescript/components/ChatWidget.d.ts.map +1 -1
  25. package/lib/typescript/components/LazyProductsFetcher.d.ts +1 -0
  26. package/lib/typescript/components/LazyProductsFetcher.d.ts.map +1 -1
  27. package/lib/typescript/components/utils.d.ts +9 -0
  28. package/lib/typescript/components/utils.d.ts.map +1 -1
  29. package/lib/typescript/storage.d.ts.map +1 -1
  30. package/package.json +7 -6
  31. package/src/api.ts +31 -4
  32. package/src/components/ChatWidget.tsx +30 -8
  33. package/src/components/LazyProductsFetcher.tsx +3 -1
  34. package/src/components/utils.ts +34 -4
  35. package/src/storage.ts +13 -0
@@ -38,6 +38,7 @@ import {
38
38
  FeedbackAction,
39
39
  formatToTime,
40
40
  getUserDetails,
41
+ useDeviceType,
41
42
  UserDetails,
42
43
  } from "./utils";
43
44
  import { useUserAnalytics } from "../hooks/useAnalytics";
@@ -86,13 +87,19 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
86
87
  const theme = useMemo(() => mergeTheme(themeOverrides), [themeOverrides]);
87
88
  const { _identify } = useUserAnalytics();
88
89
  const betaActive = Boolean(isBetaModeProp);
90
+ const { isTablet } = useDeviceType();
89
91
  const noResultsText =
90
92
  "No results found for your search. Try adjusting your filters or query.";
91
93
  useEffect(() => {
92
94
  const loadAuthData = async () => {
93
95
  try {
94
96
  if (!userTokenProp) {
95
- const token = await Storage.getItem("token");
97
+ const userInfo = await Storage.getJSON<UserDetails>(
98
+ "persist:userInfo",
99
+ {}
100
+ );
101
+ const userData = JSON.parse(userInfo?.user || "{}");
102
+ const token = userData?.token || "";
96
103
  if (token) {
97
104
  setUserToken(token);
98
105
  }
@@ -305,7 +312,8 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
305
312
  Object.keys(latestAssistant.search_payload).length > 0
306
313
  ) {
307
314
  const productsResult = await getProducts(
308
- latestAssistant.search_payload
315
+ latestAssistant.search_payload,
316
+ priceMode as string
309
317
  );
310
318
 
311
319
  const hasDiamonds =
@@ -425,7 +433,7 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
425
433
  setReloadLoadingIds((prev) => new Set(prev).add(id));
426
434
  const payload = msg?.search_payload;
427
435
  if (!payload || Object.keys(payload).length === 0) return;
428
- const productsResult = await getProducts(payload);
436
+ const productsResult = await getProducts(payload, priceMode as string);
429
437
  setProductsByMsg((prev) => ({ ...prev, [id]: productsResult }));
430
438
  } catch (e) {
431
439
  console.error("Reload results failed", e);
@@ -598,13 +606,13 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
598
606
  <View
599
607
  style={[styles.container, { backgroundColor: theme.backgroundColor }]}
600
608
  >
601
- {Platform.OS === "web" && (
609
+ {/* {Platform.OS === "web" && (
602
610
  <ChatHeader
603
611
  onClose={onClose}
604
612
  onClearChat={handleClearChat}
605
613
  isBetaMode={betaActive}
606
614
  />
607
- )}
615
+ )} */}
608
616
  <KeyboardAvoidingView
609
617
  style={{ flex: 1 }}
610
618
  behavior={Platform.OS === "ios" ? "padding" : "height"}
@@ -625,6 +633,9 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
625
633
  ...styles.listContent,
626
634
  justifyContent: messages.length === 0 ? "center" : "flex-end",
627
635
  minHeight: modalHeight ? modalHeight : undefined,
636
+ ...(isTablet
637
+ ? { maxWidth: 608, alignSelf: "center", width: "100%" }
638
+ : {}),
628
639
  }}
629
640
  onContentSizeChange={() => {
630
641
  scrollRef.current?.scrollToEnd({ animated: false });
@@ -673,6 +684,7 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
673
684
  Object.keys(item.search_payload).length > 0 &&
674
685
  !productsByMsg[item.id] && (
675
686
  <LazyProductsFetcher
687
+ priceMode={priceMode as string}
676
688
  messageId={item.id}
677
689
  payload={item.search_payload}
678
690
  onFetched={(id, result) => {
@@ -735,7 +747,15 @@ export const ChatWidget = forwardRef<ChatWidgetRef, ChatWidgetProps>(
735
747
  });
736
748
  })()}
737
749
  </ScrollView>
738
- <View style={styles.bottomContainer}>
750
+ <View style={styles.borderTop} />
751
+ <View
752
+ style={[
753
+ styles.bottomContainer,
754
+ isTablet
755
+ ? { maxWidth: 608, alignSelf: "center", width: "100%" }
756
+ : {},
757
+ ]}
758
+ >
739
759
  <ChatInput
740
760
  value={input}
741
761
  onChangeText={setInput}
@@ -783,12 +803,14 @@ const styles = StyleSheet.create({
783
803
  bottomContainer: {
784
804
  paddingVertical: 12,
785
805
  paddingHorizontal: 16,
786
- borderTopColor: "#E0E0E0",
787
- borderTopWidth: 1,
788
806
  flexDirection: "column",
789
807
  justifyContent: "space-between",
790
808
  alignItems: "center",
791
809
  alignSelf: "stretch",
792
810
  gap: 12,
793
811
  },
812
+ borderTop: {
813
+ borderTopColor: "#E0E0E0",
814
+ borderTopWidth: 1,
815
+ },
794
816
  });
@@ -7,12 +7,14 @@ interface LazyProductsFetcherProps {
7
7
  messageId: string;
8
8
  payload: Record<string, any> | undefined | null;
9
9
  onFetched: (messageId: string, data: any) => void;
10
+ priceMode: string;
10
11
  }
11
12
 
12
13
  const LazyProductsFetcher: React.FC<LazyProductsFetcherProps> = ({
13
14
  messageId,
14
15
  payload,
15
16
  onFetched,
17
+ priceMode,
16
18
  }) => {
17
19
  const { ref, inView } = useInViewport<HTMLDivElement>();
18
20
  const fetchedRef = useRef(false);
@@ -25,7 +27,7 @@ const LazyProductsFetcher: React.FC<LazyProductsFetcherProps> = ({
25
27
  fetchedRef.current = true;
26
28
  (async () => {
27
29
  try {
28
- const result = await getProducts(payload);
30
+ const result = await getProducts(payload, priceMode as string);
29
31
  onFetched(messageId, result);
30
32
  } catch (e) {
31
33
  // eslint-disable-next-line no-console
@@ -1,4 +1,8 @@
1
+ import { Dimensions } from "react-native";
1
2
  import { Storage } from "../storage";
3
+ import { useMediaQuery } from "react-responsive";
4
+
5
+ export const DEVICE_SIZE = Dimensions.get("window");
2
6
 
3
7
  export function formatToTime(timestamp: number): string {
4
8
  const date = new Date(timestamp);
@@ -32,10 +36,7 @@ export const fetchConversationId = async (
32
36
 
33
37
  let priceMode = _priceMode;
34
38
  if (priceMode === undefined) {
35
- const userInfo = await Storage.getJSON<UserDetails>(
36
- "persist:userInfo",
37
- {}
38
- );
39
+ const userInfo = await Storage.getJSON<UserDetails>("persist:userInfo", {});
39
40
  const userData = userInfo?.user as UserDetails;
40
41
  priceMode = String(userData?.price_mode) || "";
41
42
  }
@@ -53,6 +54,7 @@ export interface UserDetails {
53
54
  price_mode?: string | number;
54
55
  plan_details?: any;
55
56
  user?: any;
57
+ searchResultViewType?: string;
56
58
  }
57
59
 
58
60
  export const getUserDetails = async (): Promise<UserDetails | null> => {
@@ -102,3 +104,31 @@ export enum AnalyticsEventNames {
102
104
  WIDGET_CLOSED = "ai_chat_widget_closed",
103
105
  CHAT_CLEARED = "ai_chat_cleared",
104
106
  }
107
+
108
+ export const isIpad = () => {
109
+ // const userAgent = navigator.userAgent || navigator.vendor || window.opera;
110
+ // return (
111
+ // /iPad/.test(userAgent) ||
112
+ // (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)
113
+ // );
114
+ const userAgent =
115
+ navigator.userAgent || navigator.vendor || (window as any).opera;
116
+ return (
117
+ /iPad/.test(userAgent) ||
118
+ (/\bMac/.test(userAgent) &&
119
+ navigator.maxTouchPoints > 0 &&
120
+ !/iPhone/.test(userAgent))
121
+ );
122
+ };
123
+
124
+ export const useDeviceType = () => {
125
+ const { width } = DEVICE_SIZE;
126
+ const isMobile = useMediaQuery({ maxWidth: 767 }) || width < 767;
127
+ const isTablet =
128
+ useMediaQuery({ minWidth: 767, maxWidth: 1279 }) ||
129
+ (width > 767 && width <= 1279) ||
130
+ isIpad();
131
+ const isDesktop = useMediaQuery({ minWidth: 1279 }) || width > 1279;
132
+ const isLargeScreen = isDesktop && !isTablet && !isMobile;
133
+ return { isMobile, isTablet, isDesktop, isLargeScreen };
134
+ };
package/src/storage.ts CHANGED
@@ -15,10 +15,23 @@ function getLocalStorage(): Storage | null {
15
15
  return null;
16
16
  }
17
17
 
18
+ // Helper to safely get sessionStorage (only available on web)
19
+ function getSessionStorage(): Storage | null {
20
+ if (typeof window !== "undefined" && window.sessionStorage) {
21
+ return window.sessionStorage;
22
+ }
23
+ return null;
24
+ }
25
+
18
26
  // Web storage implementation using localStorage (lazy access)
19
27
  const webStorage: StorageInterface = {
20
28
  getItem: async (key: string) => {
21
29
  try {
30
+ // Use sessionStorage for persist:searchFilters key
31
+ if (key === "persist:searchFilters") {
32
+ const sessionStore = getSessionStorage();
33
+ return sessionStore ? sessionStore.getItem(key) : null;
34
+ }
22
35
  const storage = getLocalStorage();
23
36
  return storage ? storage.getItem(key) : null;
24
37
  } catch {