rn-erxes-sdk 0.3.4 → 0.4.2

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 (68) hide show
  1. package/README.md +23 -0
  2. package/ios/RnErxesSdk.swift +20 -1
  3. package/lib/commonjs/App.js +3 -2
  4. package/lib/commonjs/App.js.map +1 -1
  5. package/lib/commonjs/ErxesMessenger.js +91 -17
  6. package/lib/commonjs/ErxesMessenger.js.map +1 -1
  7. package/lib/commonjs/Widget.js +6 -5
  8. package/lib/commonjs/Widget.js.map +1 -1
  9. package/lib/commonjs/components/InputTools.js +2 -1
  10. package/lib/commonjs/components/InputTools.js.map +1 -1
  11. package/lib/commonjs/graphql/ApolloContainer.js +3 -2
  12. package/lib/commonjs/graphql/ApolloContainer.js.map +1 -1
  13. package/lib/commonjs/index.js +13 -0
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/nativeIos.js +13 -0
  16. package/lib/commonjs/nativeIos.js.map +1 -1
  17. package/lib/commonjs/screen/conversation/ConversationDetail.js +4 -2
  18. package/lib/commonjs/screen/conversation/ConversationDetail.js.map +1 -1
  19. package/lib/commonjs/screen/home/Home.js +4 -2
  20. package/lib/commonjs/screen/home/Home.js.map +1 -1
  21. package/lib/commonjs/utils/logger.js +55 -0
  22. package/lib/commonjs/utils/logger.js.map +1 -0
  23. package/lib/module/App.js +3 -2
  24. package/lib/module/App.js.map +1 -1
  25. package/lib/module/ErxesMessenger.js +92 -18
  26. package/lib/module/ErxesMessenger.js.map +1 -1
  27. package/lib/module/Widget.js +6 -5
  28. package/lib/module/Widget.js.map +1 -1
  29. package/lib/module/components/InputTools.js +2 -1
  30. package/lib/module/components/InputTools.js.map +1 -1
  31. package/lib/module/graphql/ApolloContainer.js +3 -2
  32. package/lib/module/graphql/ApolloContainer.js.map +1 -1
  33. package/lib/module/index.js +1 -0
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/module/nativeIos.js +13 -0
  36. package/lib/module/nativeIos.js.map +1 -1
  37. package/lib/module/screen/conversation/ConversationDetail.js +4 -2
  38. package/lib/module/screen/conversation/ConversationDetail.js.map +1 -1
  39. package/lib/module/screen/home/Home.js +4 -2
  40. package/lib/module/screen/home/Home.js.map +1 -1
  41. package/lib/module/utils/logger.js +46 -0
  42. package/lib/module/utils/logger.js.map +1 -0
  43. package/lib/typescript/App.d.ts.map +1 -1
  44. package/lib/typescript/ErxesMessenger.d.ts +11 -2
  45. package/lib/typescript/ErxesMessenger.d.ts.map +1 -1
  46. package/lib/typescript/Widget.d.ts.map +1 -1
  47. package/lib/typescript/components/InputTools.d.ts.map +1 -1
  48. package/lib/typescript/graphql/ApolloContainer.d.ts.map +1 -1
  49. package/lib/typescript/index.d.ts +1 -0
  50. package/lib/typescript/index.d.ts.map +1 -1
  51. package/lib/typescript/nativeIos.d.ts +7 -0
  52. package/lib/typescript/nativeIos.d.ts.map +1 -1
  53. package/lib/typescript/screen/conversation/ConversationDetail.d.ts.map +1 -1
  54. package/lib/typescript/screen/home/Home.d.ts.map +1 -1
  55. package/lib/typescript/utils/logger.d.ts +18 -0
  56. package/lib/typescript/utils/logger.d.ts.map +1 -0
  57. package/package.json +1 -1
  58. package/rn-erxes-sdk.podspec +2 -2
  59. package/src/App.tsx +3 -2
  60. package/src/ErxesMessenger.tsx +105 -19
  61. package/src/Widget.tsx +6 -5
  62. package/src/components/InputTools.tsx +2 -1
  63. package/src/graphql/ApolloContainer.tsx +3 -2
  64. package/src/index.tsx +2 -0
  65. package/src/nativeIos.ts +15 -0
  66. package/src/screen/conversation/ConversationDetail.tsx +4 -2
  67. package/src/screen/home/Home.tsx +4 -2
  68. package/src/utils/logger.ts +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["enabled","__DEV__","setDebugLogging","value","isDebugLogging","PREFIX","logger","info","_len","arguments","length","args","Array","_key","console","log","warn","_len2","_key2","error","_len3","_key3"],"sourceRoot":"../../../src","sources":["utils/logger.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,IAAIA,OAAO,GAAG,OAAOC,OAAO,KAAK,WAAW,GAAGA,OAAO,GAAG,KAAK;;AAE9D;AACA,OAAO,MAAMC,eAAe,GAAIC,KAAc,IAAK;EACjDH,OAAO,GAAGG,KAAK;AACjB,CAAC;;AAED;AACA,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAMJ,OAAO;AAE3C,MAAMK,MAAM,GAAG,SAAS;AAExB,OAAO,MAAMC,MAAM,GAAG;EACpBC,IAAI,EAAE,SAAAA,CAAA,EAAwB;IAC5B,IAAIP,OAAO,EAAE;MAAA,SAAAQ,IAAA,GAAAC,SAAA,CAAAC,MAAA,EADLC,IAAI,OAAAC,KAAA,CAAAJ,IAAA,GAAAK,IAAA,MAAAA,IAAA,GAAAL,IAAA,EAAAK,IAAA;QAAJF,IAAI,CAAAE,IAAA,IAAAJ,SAAA,CAAAI,IAAA;MAAA;MAEVC,OAAO,CAACC,GAAG,CAACV,MAAM,EAAE,GAAGM,IAAI,CAAC;IAC9B;EACF,CAAC;EACDK,IAAI,EAAE,SAAAA,CAAA,EAAwB;IAC5B,IAAIhB,OAAO,EAAE;MAAA,SAAAiB,KAAA,GAAAR,SAAA,CAAAC,MAAA,EADLC,IAAI,OAAAC,KAAA,CAAAK,KAAA,GAAAC,KAAA,MAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA;QAAJP,IAAI,CAAAO,KAAA,IAAAT,SAAA,CAAAS,KAAA;MAAA;MAEVJ,OAAO,CAACE,IAAI,CAACX,MAAM,EAAE,GAAGM,IAAI,CAAC;IAC/B;EACF,CAAC;EACDQ,KAAK,EAAE,SAAAA,CAAA,EAAwB;IAC7B,IAAInB,OAAO,EAAE;MAAA,SAAAoB,KAAA,GAAAX,SAAA,CAAAC,MAAA,EADJC,IAAI,OAAAC,KAAA,CAAAQ,KAAA,GAAAC,KAAA,MAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA;QAAJV,IAAI,CAAAU,KAAA,IAAAZ,SAAA,CAAAY,KAAA;MAAA;MAEXP,OAAO,CAACK,KAAK,CAACd,MAAM,EAAE,GAAGM,IAAI,CAAC;IAChC;EACF;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/App.tsx"],"names":[],"mappings":"AAAA,OAAO,gCAAgC,CAAC;AACxC,OAAO,KAAoB,MAAM,OAAO,CAAC;AAMzC,MAAM,MAAM,SAAS,GAAG;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB,CAAC;AAEF,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAmGjC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/App.tsx"],"names":[],"mappings":"AAAA,OAAO,gCAAgC,CAAC;AACxC,OAAO,KAAoB,MAAM,OAAO,CAAC;AAOzC,MAAM,MAAM,SAAS,GAAG;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB,CAAC;AAEF,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAmGjC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { type ReactNode } from 'react';
1
2
  import { type NativeIOSUser } from './nativeIos';
2
3
  /**
3
4
  * The identified end user. Same shape the native bridge expects — passing
@@ -61,10 +62,18 @@ export type ErxesMessengerProps = {
61
62
  homeActions?: ErxesAction[];
62
63
  /** Chat-mode drawer top action rows. Ignored in `'classic'`. */
63
64
  drawerActions?: ErxesAction[];
65
+ /**
66
+ * Rendered while the SDK is configuring (between `onLoad` and
67
+ * `onReady`/`onError`), e.g. a spinner shown before the native messenger
68
+ * appears. Returns `null` otherwise. Defaults to rendering nothing.
69
+ */
70
+ renderLoading?: () => ReactNode;
64
71
  /** Fired when setup starts. */
65
72
  onLoad?: () => void;
66
- /** Fired after native `configure` succeeds. */
73
+ /** Fired when the connection handshake completes (the messenger is ready). */
67
74
  onReady?: () => void;
75
+ /** Fired when the loading state changes (`true` while configuring). */
76
+ onLoadingChange?: (loading: boolean) => void;
68
77
  /** Fired when the messenger is shown. */
69
78
  onOpen?: () => void;
70
79
  /** Fired when the messenger is hidden. */
@@ -82,5 +91,5 @@ export type ErxesMessengerProps = {
82
91
  *
83
92
  * For advanced/imperative control, use `ErxesNativeIOS` directly.
84
93
  */
85
- export declare function ErxesMessenger({ integrationId, endpoint, serverUrl, subDomain, displayMode, user, cachedCustomerId, primaryColor, visible, autoOpen, autoHideOnUnmount, launcherVisible, homeActions, drawerActions, onLoad, onReady, onOpen, onClose, onError, onAction, }: ErxesMessengerProps): null;
94
+ export declare function ErxesMessenger({ integrationId, endpoint, serverUrl, subDomain, displayMode, user, cachedCustomerId, primaryColor, visible, autoOpen, autoHideOnUnmount, launcherVisible, homeActions, drawerActions, renderLoading, onLoad, onReady, onOpen, onClose, onError, onAction, onLoadingChange, }: ErxesMessengerProps): ReactNode;
86
95
  //# sourceMappingURL=ErxesMessenger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ErxesMessenger.d.ts","sourceRoot":"","sources":["../../src/ErxesMessenger.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ErxesMessenger.d.ts","sourceRoot":"","sources":["../../src/ErxesMessenger.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widget.d.ts","sourceRoot":"","sources":["../../src/Widget.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAyCzC,QAAA,MAAM,MAAM,UAAW,GAAG,6BA+TzB,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Widget.d.ts","sourceRoot":"","sources":["../../src/Widget.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAoB,MAAM,OAAO,CAAC;AA0CzC,QAAA,MAAM,MAAM,UAAW,GAAG,6BA+TzB,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"InputTools.d.ts","sourceRoot":"","sources":["../../../src/components/InputTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAoCpE,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAwO7B,CAAC;AA0IF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"InputTools.d.ts","sourceRoot":"","sources":["../../../src/components/InputTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAqCpE,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAwO7B,CAAC;AA0IF,eAAe,UAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ApolloContainer.d.ts","sourceRoot":"","sources":["../../../src/graphql/ApolloContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,QAAA,MAAM,eAAe,4BAA6B,GAAG,sBAmDpD,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ApolloContainer.d.ts","sourceRoot":"","sources":["../../../src/graphql/ApolloContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,QAAA,MAAM,eAAe,4BAA6B,GAAG,sBAmDpD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { ErxesNativeIOS } from './nativeIos';
2
2
  export type { NativeIOSAction, NativeIOSConfig, NativeIOSUser, } from './nativeIos';
3
+ export { setDebugLogging, isDebugLogging } from './utils/logger';
3
4
  export { ErxesMessenger } from './ErxesMessenger';
4
5
  export type { ErxesUser, ErxesAction, ErxesMessengerHelpers, ErxesMessengerProps, } from './ErxesMessenger';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EACV,SAAS,EACT,WAAW,EACX,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EACV,SAAS,EACT,WAAW,EACX,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
@@ -48,6 +48,13 @@ export declare const ErxesNativeIOS: {
48
48
  * to stop listening.
49
49
  */
50
50
  addActionListener(handler: (id: string) => void): EmitterSubscription;
51
+ /**
52
+ * Listen for the connect handshake completing — i.e. the messenger is ready
53
+ * (`MessengerSDK.isReady`). Fires once per connection; if already connected
54
+ * when you subscribe via a fresh `configure`, it fires again. Returns a
55
+ * subscription — call `.remove()` to stop listening.
56
+ */
57
+ addReadyListener(handler: () => void): EmitterSubscription;
51
58
  };
52
59
  export type { NativeIOSAction, NativeIOSConfig, NativeIOSUser };
53
60
  //# sourceMappingURL=nativeIos.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativeIos.d.ts","sourceRoot":"","sources":["../../src/nativeIos.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,cAAc,CAAC;AAEtB;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACrB,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,gEAAgE;IAChE,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC3E,CAAC;AAgCF,eAAO,MAAM,cAAc;uBACN,eAAe;qBAGjB,aAAa;;;;;;IA2B9B;;;;;OAKG;oCAC6B,MAAM,KAAK,IAAI,GAAG,mBAAmB;CAQtE,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"nativeIos.d.ts","sourceRoot":"","sources":["../../src/nativeIos.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,cAAc,CAAC;AAEtB;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACrB,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,gEAAgE;IAChE,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC3E,CAAC;AAmCF,eAAO,MAAM,cAAc;uBACN,eAAe;qBAGjB,aAAa;;;;;;IA2B9B;;;;;OAKG;oCAC6B,MAAM,KAAK,IAAI,GAAG,mBAAmB;IAQrE;;;;;OAKG;8BACuB,MAAM,IAAI,GAAG,mBAAmB;CAM3D,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationDetail.d.ts","sourceRoot":"","sources":["../../../../src/screen/conversation/ConversationDetail.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAgFxE,QAAA,MAAM,kBAAkB,yBA8TvB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"ConversationDetail.d.ts","sourceRoot":"","sources":["../../../../src/screen/conversation/ConversationDetail.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAiFxE,QAAA,MAAM,kBAAkB,yBA+TvB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Home.d.ts","sourceRoot":"","sources":["../../../../src/screen/home/Home.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAkB1C,QAAA,MAAM,IAAI,yBA8MT,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Home.d.ts","sourceRoot":"","sources":["../../../../src/screen/home/Home.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAmB1C,QAAA,MAAM,IAAI,yBA+MT,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Debug-gated logger for the SDK.
3
+ *
4
+ * A published SDK should not write to the host app's console in production. All
5
+ * internal logging goes through here so it can be silenced. By default logging
6
+ * follows React Native's `__DEV__` flag (on in development, off in release
7
+ * builds); hosts can override either way via {@link setDebugLogging}.
8
+ */
9
+ /** Enable or disable SDK debug logging at runtime. */
10
+ export declare const setDebugLogging: (value: boolean) => void;
11
+ /** Whether SDK debug logging is currently active. */
12
+ export declare const isDebugLogging: () => boolean;
13
+ export declare const logger: {
14
+ info: (...args: unknown[]) => void;
15
+ warn: (...args: unknown[]) => void;
16
+ error: (...args: unknown[]) => void;
17
+ };
18
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,sDAAsD;AACtD,eAAO,MAAM,eAAe,UAAW,OAAO,SAE7C,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,cAAc,eAAgB,CAAC;AAI5C,eAAO,MAAM,MAAM;oBACD,OAAO,EAAE;oBAKT,OAAO,EAAE;qBAKR,OAAO,EAAE;CAK3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-erxes-sdk",
3
- "version": "0.3.4",
3
+ "version": "0.4.2",
4
4
  "description": "react-native erxes sdk",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -36,10 +36,10 @@ Pod::Spec.new do |s|
36
36
  spm_dependency(
37
37
  s,
38
38
  url: 'https://github.com/erxes/erxes-ios-sdk.git',
39
- requirement: { :kind => 'exactVersion', :version => '0.30.7' },
39
+ requirement: { :kind => 'exactVersion', :version => '0.30.9' },
40
40
  products: ['MessengerSDK']
41
41
  )
42
42
  else
43
- raise 'rn-erxes-sdk requires React Native 0.81+ CocoaPods SPM support to install MessengerSDK 0.30.7'
43
+ raise 'rn-erxes-sdk requires React Native 0.81+ CocoaPods SPM support to install MessengerSDK 0.30.9'
44
44
  end
45
45
  end
package/src/App.tsx CHANGED
@@ -3,6 +3,7 @@ import React, { useEffect } from 'react';
3
3
  import Widget from './Widget';
4
4
  import AsyncStorage from '@react-native-async-storage/async-storage';
5
5
  import { createObjectIdLikeString } from './utils/objectId';
6
+ import { logger } from './utils/logger';
6
7
  import ApolloContainer from './graphql/ApolloContainer';
7
8
 
8
9
  export type PropTypes = {
@@ -69,7 +70,7 @@ const ErxesSDK: React.FC<PropTypes> = ({
69
70
  })
70
71
  .catch((e) => {
71
72
  setLoading(false);
72
- console.log('Failed on cachedConversationId', e.message);
73
+ logger.error('Failed on cachedConversationId', e.message);
73
74
  });
74
75
  })
75
76
  .catch((e) => {
@@ -78,7 +79,7 @@ const ErxesSDK: React.FC<PropTypes> = ({
78
79
  visitorId: createObjectIdLikeString(),
79
80
  });
80
81
  setLoading(false);
81
- console.log('Failed on cachedCustomerId', e.message);
82
+ logger.error('Failed on cachedCustomerId', e.message);
82
83
  });
83
84
  }, []);
84
85
 
@@ -1,4 +1,4 @@
1
- import { useEffect, useRef } from 'react';
1
+ import { useEffect, useRef, useState, type ReactNode } from 'react';
2
2
  import { Platform } from 'react-native';
3
3
 
4
4
  import { ErxesNativeIOS, type NativeIOSUser } from './nativeIos';
@@ -75,10 +75,19 @@ export type ErxesMessengerProps = {
75
75
  /** Chat-mode drawer top action rows. Ignored in `'classic'`. */
76
76
  drawerActions?: ErxesAction[];
77
77
 
78
+ /**
79
+ * Rendered while the SDK is configuring (between `onLoad` and
80
+ * `onReady`/`onError`), e.g. a spinner shown before the native messenger
81
+ * appears. Returns `null` otherwise. Defaults to rendering nothing.
82
+ */
83
+ renderLoading?: () => ReactNode;
84
+
78
85
  /** Fired when setup starts. */
79
86
  onLoad?: () => void;
80
- /** Fired after native `configure` succeeds. */
87
+ /** Fired when the connection handshake completes (the messenger is ready). */
81
88
  onReady?: () => void;
89
+ /** Fired when the loading state changes (`true` while configuring). */
90
+ onLoadingChange?: (loading: boolean) => void;
82
91
  /** Fired when the messenger is shown. */
83
92
  onOpen?: () => void;
84
93
  /** Fired when the messenger is hidden. */
@@ -124,17 +133,41 @@ export function ErxesMessenger({
124
133
  launcherVisible,
125
134
  homeActions = [],
126
135
  drawerActions = [],
136
+ renderLoading,
127
137
  onLoad,
128
138
  onReady,
129
139
  onOpen,
130
140
  onClose,
131
141
  onError,
132
142
  onAction,
143
+ onLoadingChange,
133
144
  }: ErxesMessengerProps) {
134
145
  // Keep the latest actions/callback in refs so the action listener (registered
135
146
  // once below) always dispatches against current props without re-subscribing.
136
147
  const actionsRef = useRef<ErxesAction[]>([]);
137
148
  const onActionRef = useRef(onAction);
149
+ const onLoadingChangeRef = useRef(onLoadingChange);
150
+ // Tracks whether we believe the messenger is currently presented, so we never
151
+ // double-present (chat mode auto-presents inside `configure()`) or fire a
152
+ // redundant show/hide. Native gives us no presentation callback, so this is our
153
+ // best-effort intent mirror.
154
+ const shownRef = useRef(false);
155
+
156
+ // Flips true only after native `configure()` resolves. The controlled-`visible`
157
+ // effect gates on this so it never calls `showMessenger()` before `configure()`
158
+ // (the native SDK asserts on that ordering).
159
+ const [configured, setConfigured] = useState(false);
160
+ // True while configuring (between `onLoad` and `onReady`/`onError`); drives
161
+ // `renderLoading`.
162
+ const [loading, setLoading] = useState(false);
163
+
164
+ useEffect(() => {
165
+ onLoadingChangeRef.current = onLoadingChange;
166
+ }, [onLoadingChange]);
167
+
168
+ useEffect(() => {
169
+ onLoadingChangeRef.current?.(loading);
170
+ }, [loading]);
138
171
 
139
172
  useEffect(() => {
140
173
  actionsRef.current = [...homeActions, ...drawerActions];
@@ -146,9 +179,17 @@ export function ErxesMessenger({
146
179
  return;
147
180
  }
148
181
 
182
+ setConfigured(false);
183
+
149
184
  const helpers: ErxesMessengerHelpers = {
150
- show: () => ErxesNativeIOS.showMessenger(),
151
- hide: () => ErxesNativeIOS.hideMessenger(),
185
+ show: async () => {
186
+ await ErxesNativeIOS.showMessenger();
187
+ shownRef.current = true;
188
+ },
189
+ hide: async () => {
190
+ await ErxesNativeIOS.hideMessenger();
191
+ shownRef.current = false;
192
+ },
152
193
  showLauncher: () => ErxesNativeIOS.showLauncher(),
153
194
  hideLauncher: () => ErxesNativeIOS.hideLauncher(),
154
195
  setUser: (nextUser) => ErxesNativeIOS.setUser(nextUser),
@@ -166,8 +207,16 @@ export function ErxesMessenger({
166
207
  await onActionRef.current?.(id, helpers);
167
208
  });
168
209
 
210
+ // Connection complete (native `MessengerSDK.isReady`): the messenger is
211
+ // truly ready, so end the loading state and notify the host.
212
+ const readySub = ErxesNativeIOS.addReadyListener(() => {
213
+ setLoading(false);
214
+ onReady?.();
215
+ });
216
+
169
217
  async function setup() {
170
218
  try {
219
+ setLoading(true);
171
220
  onLoad?.();
172
221
 
173
222
  if (user) {
@@ -186,19 +235,45 @@ export function ErxesMessenger({
186
235
  drawerActions: stripActions(drawerActions),
187
236
  });
188
237
 
189
- onReady?.();
190
-
191
- if (autoOpen) {
192
- await ErxesNativeIOS.showMessenger();
193
- onOpen?.();
238
+ // `configure()` only kicks off the async connect; `onReady` and the end
239
+ // of `loading` are driven by the ready listener above, not here.
240
+
241
+ // Decide the initial open state. If `visible` is controlled it wins;
242
+ // otherwise fall back to `autoOpen` (defaults to true in chat mode).
243
+ const shouldOpen = visible ?? autoOpen;
244
+
245
+ if (displayMode === 'chat') {
246
+ // Chat mode auto-presents itself inside `configure()` — never call
247
+ // `showMessenger()` for the initial open or we'd present a second one.
248
+ if (shouldOpen) {
249
+ shownRef.current = true;
250
+ onOpen?.();
251
+ } else {
252
+ // Caller wants it closed: undo the native auto-present.
253
+ await ErxesNativeIOS.hideMessenger();
254
+ shownRef.current = false;
255
+ }
256
+ } else {
257
+ // Classic mode: configure does not open anything. Show the launcher
258
+ // and/or present the sheet explicitly.
259
+ if (launcherVisible === true) {
260
+ await ErxesNativeIOS.showLauncher();
261
+ } else if (launcherVisible === false) {
262
+ await ErxesNativeIOS.hideLauncher();
263
+ }
264
+
265
+ if (shouldOpen) {
266
+ await ErxesNativeIOS.showMessenger();
267
+ shownRef.current = true;
268
+ onOpen?.();
269
+ }
194
270
  }
195
271
 
196
- if (launcherVisible === true) {
197
- await ErxesNativeIOS.showLauncher();
198
- } else if (launcherVisible === false) {
199
- await ErxesNativeIOS.hideLauncher();
200
- }
272
+ setConfigured(true);
201
273
  } catch (error) {
274
+ // Setup failed before the connection could complete — end loading here
275
+ // since the ready listener will never fire.
276
+ setLoading(false);
202
277
  onError?.(error);
203
278
  }
204
279
  }
@@ -207,9 +282,11 @@ export function ErxesMessenger({
207
282
 
208
283
  return () => {
209
284
  sub.remove();
285
+ readySub.remove();
210
286
 
211
- if (autoHideOnUnmount) {
287
+ if (autoHideOnUnmount && shownRef.current) {
212
288
  ErxesNativeIOS.hideMessenger();
289
+ shownRef.current = false;
213
290
  onClose?.();
214
291
  }
215
292
  };
@@ -219,19 +296,28 @@ export function ErxesMessenger({
219
296
  }, [integrationId, endpoint, serverUrl, subDomain, displayMode]);
220
297
 
221
298
  useEffect(() => {
222
- if (Platform.OS !== 'ios' || visible === undefined) {
299
+ // Wait until `configure()` has resolved otherwise `showMessenger()` would
300
+ // race ahead of it and trip the native configure-before-show assertion. The
301
+ // initial open is handled in `setup()`; this only reacts to later changes.
302
+ if (Platform.OS !== 'ios' || visible === undefined || !configured) {
223
303
  return;
224
304
  }
225
305
 
226
- if (visible) {
306
+ if (visible && !shownRef.current) {
227
307
  ErxesNativeIOS.showMessenger();
308
+ shownRef.current = true;
228
309
  onOpen?.();
229
- } else {
310
+ } else if (!visible && shownRef.current) {
230
311
  ErxesNativeIOS.hideMessenger();
312
+ shownRef.current = false;
231
313
  onClose?.();
232
314
  }
233
315
  // eslint-disable-next-line react-hooks/exhaustive-deps
234
- }, [visible]);
316
+ }, [visible, configured]);
317
+
318
+ if (loading && renderLoading) {
319
+ return renderLoading();
320
+ }
235
321
 
236
322
  return null;
237
323
  }
package/src/Widget.tsx CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  widgetsSaveBrowserInfo,
10
10
  } from './graphql/mutation';
11
11
  import AppContext from './context/Context';
12
+ import { logger } from './utils/logger';
12
13
  import ConversationDetail from './screen/conversation/ConversationDetail';
13
14
  import MessengerShell from './components/MessengerShell';
14
15
  import { TouchableOpacity } from 'react-native';
@@ -119,7 +120,7 @@ const Widget = (props: any) => {
119
120
  return res;
120
121
  })
121
122
  .catch((err) => {
122
- console.log(err);
123
+ logger.error('readConversationMessages failed', err);
123
124
  return null;
124
125
  });
125
126
  },
@@ -210,7 +211,7 @@ const Widget = (props: any) => {
210
211
  refetchUnreadConversations();
211
212
  },
212
213
  error(err) {
213
- console.log(err);
214
+ logger.error('unread conversations subscription error', err);
214
215
  },
215
216
  });
216
217
 
@@ -248,7 +249,7 @@ const Widget = (props: any) => {
248
249
  }
249
250
  })
250
251
  .catch((err) => {
251
- console.log(err);
252
+ logger.error('connect failed', err);
252
253
  });
253
254
  }, []);
254
255
 
@@ -261,10 +262,10 @@ const Widget = (props: any) => {
261
262
  },
262
263
  })
263
264
  .then(() => {
264
- console.log('browser info saved');
265
+ logger.info('browser info saved');
265
266
  })
266
267
  .catch((err) => {
267
- console.log(err);
268
+ logger.error('saveBrowserInfo failed', err);
268
269
  });
269
270
  }
270
271
  }, [connection]);
@@ -11,6 +11,7 @@ import {
11
11
  Platform,
12
12
  } from 'react-native';
13
13
  import { messengerTheme } from '../theme';
14
+ import { logger } from '../utils/logger';
14
15
  import {
15
16
  SendIcon,
16
17
  AttachmentIcon,
@@ -107,7 +108,7 @@ const InputTools: React.FC<any> = (props: any) => {
107
108
  const uploaded = await uploadFile(file, subDomain);
108
109
  setAttachments((prev) => [...prev, uploaded]);
109
110
  } catch (err) {
110
- console.log('attachment upload failed', err);
111
+ logger.error('attachment upload failed', err);
111
112
  const message = err instanceof Error ? err.message : '';
112
113
  showUploadError(
113
114
  message.includes('Invalid configured file type')
@@ -10,6 +10,7 @@ import {
10
10
  import { getMainDefinition } from '@apollo/client/utilities';
11
11
  import { onError } from '@apollo/client/link/error';
12
12
  import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
13
+ import { logger } from '../utils/logger';
13
14
  import { createClient } from 'graphql-ws';
14
15
 
15
16
  const ApolloContainer = ({ children, subDomain }: any) => {
@@ -28,8 +29,8 @@ const ApolloContainer = ({ children, subDomain }: any) => {
28
29
  );
29
30
 
30
31
  const logoutLink = onError(({ networkError, graphQLErrors }) => {
31
- console.log('--netError', networkError);
32
- console.log('--gqlError', graphQLErrors);
32
+ logger.error('network error', networkError);
33
+ logger.error('graphQL errors', graphQLErrors);
33
34
  });
34
35
 
35
36
  const httpLink = createHttpLink({
package/src/index.tsx CHANGED
@@ -5,6 +5,8 @@ export type {
5
5
  NativeIOSUser,
6
6
  } from './nativeIos';
7
7
 
8
+ export { setDebugLogging, isDebugLogging } from './utils/logger';
9
+
8
10
  export { ErxesMessenger } from './ErxesMessenger';
9
11
  export type {
10
12
  ErxesUser,
package/src/nativeIos.ts CHANGED
@@ -56,6 +56,9 @@ type NativeIOSModule = {
56
56
  /** Native event name emitted when a chat-mode action is tapped. */
57
57
  const ACTION_EVENT = 'onErxesAction';
58
58
 
59
+ /** Native event name emitted when the connect handshake completes. */
60
+ const READY_EVENT = 'onErxesReady';
61
+
59
62
  const LINKING_ERROR =
60
63
  "The rn-erxes-sdk native iOS module is not linked. Run `pod install` in your app's ios directory and rebuild the app.";
61
64
 
@@ -118,6 +121,18 @@ export const ErxesNativeIOS = {
118
121
  handler(event.id)
119
122
  );
120
123
  },
124
+ /**
125
+ * Listen for the connect handshake completing — i.e. the messenger is ready
126
+ * (`MessengerSDK.isReady`). Fires once per connection; if already connected
127
+ * when you subscribe via a fresh `configure`, it fires again. Returns a
128
+ * subscription — call `.remove()` to stop listening.
129
+ */
130
+ addReadyListener(handler: () => void): EmitterSubscription {
131
+ const emitter = new NativeEventEmitter(
132
+ getNativeModule() as unknown as NativeModule
133
+ );
134
+ return emitter.addListener(READY_EVENT, () => handler());
135
+ },
121
136
  };
122
137
 
123
138
  export type { NativeIOSAction, NativeIOSConfig, NativeIOSUser };
@@ -32,6 +32,7 @@ import { BackIcon } from '../../components/Icons';
32
32
  import DateSeparator from '../../components/conversation/DateSeparator';
33
33
  import WelcomeMessage from '../../components/conversation/WelcomeMessage';
34
34
  import TypingStatus from '../../components/conversation/TypingStatus';
35
+ import { logger } from '../../utils/logger';
35
36
 
36
37
  const hasUserDetails = (user: any): boolean =>
37
38
  Boolean(user?.details?.fullName || user?.details?.avatar);
@@ -301,7 +302,8 @@ const ConversationDetail = () => {
301
302
  })
302
303
  .then((res: any) => {
303
304
  if (res.errors) {
304
- return console.log(res.errors);
305
+ logger.error('insertMessage errors', res.errors);
306
+ return;
305
307
  }
306
308
 
307
309
  const insertedMessage = res.data.widgetsInsertMessage;
@@ -326,7 +328,7 @@ const ConversationDetail = () => {
326
328
  }
327
329
  })
328
330
  .catch((err: any) => {
329
- console.log(err);
331
+ logger.error('insertMessage failed', err);
330
332
  })
331
333
  .finally(() => {
332
334
  sendingRef.current = false;
@@ -14,6 +14,7 @@ import React, { useContext } from 'react';
14
14
  import AsyncStorage from '@react-native-async-storage/async-storage';
15
15
  import { useMutation } from '@apollo/client';
16
16
  import AppContext from '../../context/Context';
17
+ import { logger } from '../../utils/logger';
17
18
  import Supporters from '../greetings/Supporters';
18
19
  import Social from '../greetings/Social';
19
20
  import { messengerTheme } from '../../theme';
@@ -92,7 +93,8 @@ const Home = () => {
92
93
  })
93
94
  .then((res: any) => {
94
95
  if (res.errors) {
95
- return console.log(res.errors);
96
+ logger.error('insertMessage errors', res.errors);
97
+ return;
96
98
  }
97
99
 
98
100
  const insertedMessage = res.data.widgetsInsertMessage;
@@ -104,7 +106,7 @@ const Home = () => {
104
106
  }
105
107
  })
106
108
  .catch((err: any) => {
107
- console.log(err);
109
+ logger.error('insertMessage failed', err);
108
110
  })
109
111
  .finally(() => {
110
112
  sendingRef.current = false;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Debug-gated logger for the SDK.
3
+ *
4
+ * A published SDK should not write to the host app's console in production. All
5
+ * internal logging goes through here so it can be silenced. By default logging
6
+ * follows React Native's `__DEV__` flag (on in development, off in release
7
+ * builds); hosts can override either way via {@link setDebugLogging}.
8
+ */
9
+
10
+ declare const __DEV__: boolean;
11
+
12
+ let enabled = typeof __DEV__ !== 'undefined' ? __DEV__ : false;
13
+
14
+ /** Enable or disable SDK debug logging at runtime. */
15
+ export const setDebugLogging = (value: boolean) => {
16
+ enabled = value;
17
+ };
18
+
19
+ /** Whether SDK debug logging is currently active. */
20
+ export const isDebugLogging = () => enabled;
21
+
22
+ const PREFIX = '[erxes]';
23
+
24
+ export const logger = {
25
+ info: (...args: unknown[]) => {
26
+ if (enabled) {
27
+ console.log(PREFIX, ...args);
28
+ }
29
+ },
30
+ warn: (...args: unknown[]) => {
31
+ if (enabled) {
32
+ console.warn(PREFIX, ...args);
33
+ }
34
+ },
35
+ error: (...args: unknown[]) => {
36
+ if (enabled) {
37
+ console.error(PREFIX, ...args);
38
+ }
39
+ },
40
+ };