@rematter/pylon-react-native 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 (40) hide show
  1. package/README.md +503 -0
  2. package/RNPylonChat.podspec +33 -0
  3. package/android/build.gradle +74 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +4 -0
  6. package/android/src/main/java/com/pylon/chatwidget/Pylon.kt +149 -0
  7. package/android/src/main/java/com/pylon/chatwidget/PylonChat.kt +715 -0
  8. package/android/src/main/java/com/pylon/chatwidget/PylonChatController.kt +63 -0
  9. package/android/src/main/java/com/pylon/chatwidget/PylonChatListener.kt +76 -0
  10. package/android/src/main/java/com/pylon/chatwidget/PylonChatView.kt +7 -0
  11. package/android/src/main/java/com/pylon/chatwidget/PylonConfig.kt +62 -0
  12. package/android/src/main/java/com/pylon/chatwidget/PylonDebugView.kt +76 -0
  13. package/android/src/main/java/com/pylon/chatwidget/PylonUser.kt +41 -0
  14. package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatPackage.kt +17 -0
  15. package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatView.kt +298 -0
  16. package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatViewManager.kt +201 -0
  17. package/ios/PylonChat/PylonChat.swift +865 -0
  18. package/ios/RNPylonChatView.swift +332 -0
  19. package/ios/RNPylonChatViewManager.m +55 -0
  20. package/ios/RNPylonChatViewManager.swift +23 -0
  21. package/lib/PylonChatView.d.ts +27 -0
  22. package/lib/PylonChatView.js +78 -0
  23. package/lib/PylonChatWidget.android.d.ts +19 -0
  24. package/lib/PylonChatWidget.android.js +144 -0
  25. package/lib/PylonChatWidget.ios.d.ts +14 -0
  26. package/lib/PylonChatWidget.ios.js +79 -0
  27. package/lib/PylonModule.d.ts +32 -0
  28. package/lib/PylonModule.js +44 -0
  29. package/lib/index.d.ts +5 -0
  30. package/lib/index.js +15 -0
  31. package/lib/types.d.ts +34 -0
  32. package/lib/types.js +2 -0
  33. package/package.json +39 -0
  34. package/src/PylonChatView.tsx +170 -0
  35. package/src/PylonChatWidget.android.tsx +165 -0
  36. package/src/PylonChatWidget.d.ts +15 -0
  37. package/src/PylonChatWidget.ios.tsx +79 -0
  38. package/src/PylonModule.ts +52 -0
  39. package/src/index.ts +15 -0
  40. package/src/types.ts +37 -0
@@ -0,0 +1,79 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ useRef,
6
+ } from "react";
7
+ import { StyleSheet } from "react-native";
8
+ import type {
9
+ PylonChatViewInternalRef,
10
+ PylonChatViewRef,
11
+ } from "./PylonChatView";
12
+ import { PylonChatView } from "./PylonChatView";
13
+ import type { PylonChatWidgetProps } from "./PylonChatWidget";
14
+
15
+ /**
16
+ * iOS implementation - simple passthrough.
17
+ *
18
+ * iOS uses native hitTest for touch pass-through, so no proxy logic needed.
19
+ *
20
+ * State Management:
21
+ * - State lives entirely in native layer (no React state needed for iOS)
22
+ * - Imperative methods call native, which handles everything
23
+ * - Events are simply forwarded to user's listener
24
+ */
25
+ export const PylonChatWidget = forwardRef<
26
+ PylonChatViewRef,
27
+ PylonChatWidgetProps
28
+ >(({ config, user, listener, style, topInset }, ref) => {
29
+ // Internal ref - typed as any since iOS doesn't need clickElementAtSelector.
30
+ const chatRef = useRef<PylonChatViewInternalRef>(null);
31
+
32
+ // Forward ref methods - all state managed in native layer
33
+ useImperativeHandle(ref, () => ({
34
+ openChat: () => chatRef.current?.openChat(),
35
+ closeChat: () => chatRef.current?.closeChat(),
36
+ showChatBubble: () => chatRef.current?.showChatBubble(),
37
+ hideChatBubble: () => chatRef.current?.hideChatBubble(),
38
+ showNewMessage: (message: string, isHtml?: boolean) =>
39
+ chatRef.current?.showNewMessage(message, isHtml),
40
+ setNewIssueCustomFields: (fields: Record<string, any>) =>
41
+ chatRef.current?.setNewIssueCustomFields(fields),
42
+ setTicketFormFields: (fields: Record<string, any>) =>
43
+ chatRef.current?.setTicketFormFields(fields),
44
+ updateEmailHash: (emailHash: string | null) =>
45
+ chatRef.current?.updateEmailHash(emailHash),
46
+ showTicketForm: (slug: string) => chatRef.current?.showTicketForm(slug),
47
+ showKnowledgeBaseArticle: (articleId: string) =>
48
+ chatRef.current?.showKnowledgeBaseArticle(articleId),
49
+ }));
50
+
51
+ // Event handlers - forward to user's listener
52
+ const handleChatOpened = useCallback(() => {
53
+ listener?.onChatOpened?.();
54
+ }, [listener]);
55
+
56
+ const handleChatClosed = useCallback(
57
+ (wasOpen: boolean) => {
58
+ listener?.onChatClosed?.(wasOpen);
59
+ },
60
+ [listener]
61
+ );
62
+
63
+ return (
64
+ <PylonChatView
65
+ ref={chatRef}
66
+ style={style || StyleSheet.absoluteFillObject}
67
+ config={config}
68
+ user={user}
69
+ topInset={topInset}
70
+ listener={{
71
+ ...listener,
72
+ onChatOpened: handleChatOpened,
73
+ onChatClosed: handleChatClosed,
74
+ }}
75
+ />
76
+ );
77
+ });
78
+
79
+ PylonChatWidget.displayName = "PylonChatWidget";
@@ -0,0 +1,52 @@
1
+ import type { PylonConfig, PylonUser } from "./types";
2
+
3
+ /**
4
+ * Pylon SDK - Singleton for managing global configuration.
5
+ *
6
+ * Note: This is optional - you can also pass config directly to PylonChatView.
7
+ * This singleton is useful if you want to initialize once and reuse across multiple views.
8
+ */
9
+ export class Pylon {
10
+ private static instance: Pylon;
11
+ private _config?: PylonConfig;
12
+ private _user?: PylonUser;
13
+
14
+ private constructor() {}
15
+
16
+ static get shared(): Pylon {
17
+ if (!Pylon.instance) {
18
+ Pylon.instance = new Pylon();
19
+ }
20
+ return Pylon.instance;
21
+ }
22
+
23
+ /**
24
+ * Initialize the Pylon SDK with configuration.
25
+ */
26
+ initialize(config: PylonConfig): void {
27
+ this._config = config;
28
+ }
29
+
30
+ /**
31
+ * Set the current user for the chat.
32
+ */
33
+ setUser(user: PylonUser): void {
34
+ this._user = user;
35
+ }
36
+
37
+ /**
38
+ * Get the current configuration.
39
+ */
40
+ get config(): PylonConfig | undefined {
41
+ return this._config;
42
+ }
43
+
44
+ /**
45
+ * Get the current user.
46
+ */
47
+ get user(): PylonUser | undefined {
48
+ return this._user;
49
+ }
50
+ }
51
+
52
+ export default Pylon.shared;
package/src/index.ts ADDED
@@ -0,0 +1,15 @@
1
+ export { PylonChatView } from "./PylonChatView";
2
+ export type {
3
+ PylonChatViewRef,
4
+ PylonChatViewInternalRef,
5
+ } from "./PylonChatView";
6
+ // React Native will automatically resolve to .ios.tsx or .android.tsx at runtime
7
+ // TypeScript just needs to find the types from one of them
8
+ export { PylonChatWidget } from "./PylonChatWidget";
9
+ export { Pylon, default as PylonSDK } from "./PylonModule";
10
+ export type {
11
+ InteractiveBound,
12
+ PylonChatListener,
13
+ PylonConfig,
14
+ PylonUser,
15
+ } from "./types";
package/src/types.ts ADDED
@@ -0,0 +1,37 @@
1
+ export interface PylonConfig {
2
+ appId: string;
3
+ enableLogging?: boolean;
4
+ primaryColor?: string;
5
+ debugMode?: boolean;
6
+ widgetBaseUrl?: string;
7
+ widgetScriptUrl?: string;
8
+ }
9
+
10
+ export interface PylonUser {
11
+ email: string;
12
+ name: string;
13
+ avatarUrl?: string;
14
+ emailHash?: string;
15
+ accountId?: string;
16
+ accountExternalId?: string;
17
+ }
18
+
19
+ export interface InteractiveBound {
20
+ selector: string;
21
+ left: number;
22
+ top: number;
23
+ right: number;
24
+ bottom: number;
25
+ }
26
+
27
+ export interface PylonChatListener {
28
+ onPylonLoaded?: () => void;
29
+ onPylonInitialized?: () => void;
30
+ onPylonReady?: () => void;
31
+ onMessageReceived?: (message: string) => void;
32
+ onChatOpened?: () => void;
33
+ onChatClosed?: (wasOpen: boolean) => void;
34
+ onPylonError?: (error: string) => void;
35
+ onUnreadCountChanged?: (count: number) => void;
36
+ onInteractiveBoundsChanged?: (bounds: InteractiveBound) => void;
37
+ }