@rematter/pylon-react-native 0.1.4 → 0.1.6

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.
@@ -18,96 +18,107 @@ import com.pylon.chatwidget.PylonUser
18
18
  * This is kept as minimal as possible to avoid interfering with touch pass-through.
19
19
  */
20
20
  class RNPylonChatView(context: Context) : FrameLayout(context) {
21
-
21
+
22
22
  private var pylonChatView: PylonChatView? = null
23
23
  private var config: PylonConfig? = null
24
24
  private var user: PylonUser? = null
25
-
25
+
26
26
  // Config properties
27
27
  var appId: String? = null
28
28
  set(value) {
29
29
  field = value
30
30
  updateConfig()
31
31
  }
32
-
32
+
33
33
  var widgetBaseUrl: String? = null
34
34
  set(value) {
35
35
  field = value
36
36
  updateConfig()
37
37
  }
38
-
38
+
39
39
  var widgetScriptUrl: String? = null
40
40
  set(value) {
41
41
  field = value
42
42
  updateConfig()
43
43
  }
44
-
44
+
45
45
  var enableLogging: Boolean = true
46
46
  set(value) {
47
47
  field = value
48
48
  updateConfig()
49
49
  }
50
-
50
+
51
51
  var debugMode: Boolean = false
52
52
  set(value) {
53
53
  field = value
54
54
  updateConfig()
55
55
  }
56
-
56
+
57
57
  var primaryColor: String? = null
58
58
  set(value) {
59
59
  field = value
60
60
  updateConfig()
61
61
  }
62
-
62
+
63
63
  // User properties
64
64
  var userEmail: String? = null
65
65
  set(value) {
66
66
  field = value
67
67
  updateUser()
68
68
  }
69
-
69
+
70
70
  var userName: String? = null
71
71
  set(value) {
72
72
  field = value
73
73
  updateUser()
74
74
  }
75
-
75
+
76
76
  var userAvatarUrl: String? = null
77
77
  set(value) {
78
78
  field = value
79
79
  updateUser()
80
80
  }
81
-
81
+
82
82
  var userEmailHash: String? = null
83
83
  set(value) {
84
84
  field = value
85
85
  updateUser()
86
86
  }
87
-
87
+
88
88
  var userAccountId: String? = null
89
89
  set(value) {
90
90
  field = value
91
91
  updateUser()
92
92
  }
93
-
93
+
94
94
  var userAccountExternalId: String? = null
95
95
  set(value) {
96
96
  field = value
97
97
  updateUser()
98
98
  }
99
99
 
100
+ // Safe area top inset for coordinate space adjustment
101
+ var topInset: Float = 0f
102
+ set(value) {
103
+ field = value
104
+ // Apply to pylonChatView if it exists
105
+ pylonChatView?.let {
106
+ // Note: Android PylonChat doesn't have topInset support yet,
107
+ // but we store it here for future use or coordinate adjustments
108
+ }
109
+ }
110
+
100
111
  init {
101
112
  layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
102
113
  }
103
-
114
+
104
115
  // Track pointer events setting
105
116
  private var pointerEventsMode = "auto"
106
-
117
+
107
118
  fun setPointerEventsMode(mode: String) {
108
119
  pointerEventsMode = mode
109
120
  }
110
-
121
+
111
122
  /**
112
123
  * This is the CRITICAL method for pointerEvents.
113
124
  * By returning false here when pointerEvents="none", we tell React Native's
@@ -139,7 +150,7 @@ class RNPylonChatView(context: Context) : FrameLayout(context) {
139
150
 
140
151
  private fun updateConfig() {
141
152
  val id = appId ?: return
142
-
153
+
143
154
  config = PylonConfig.build(id) {
144
155
  this.enableLogging = this@RNPylonChatView.enableLogging
145
156
  this.primaryColor = this@RNPylonChatView.primaryColor
@@ -147,14 +158,14 @@ class RNPylonChatView(context: Context) : FrameLayout(context) {
147
158
  this@RNPylonChatView.widgetBaseUrl?.let { this.widgetBaseUrl = it }
148
159
  this@RNPylonChatView.widgetScriptUrl?.let { this.widgetScriptUrl = it }
149
160
  }
150
-
161
+
151
162
  recreatePylonView()
152
163
  }
153
-
164
+
154
165
  private fun updateUser() {
155
166
  val email = userEmail ?: return
156
167
  val name = userName ?: return
157
-
168
+
158
169
  user = PylonUser(
159
170
  email = email,
160
171
  name = name,
@@ -163,48 +174,48 @@ class RNPylonChatView(context: Context) : FrameLayout(context) {
163
174
  accountId = userAccountId,
164
175
  accountExternalId = userAccountExternalId
165
176
  )
166
-
177
+
167
178
  recreatePylonView()
168
179
  }
169
-
180
+
170
181
  private fun recreatePylonView() {
171
182
  val cfg = config ?: return
172
183
  val usr = user ?: return
173
-
184
+
174
185
  // Remove old view
175
186
  pylonChatView?.let { removeView(it) }
176
-
187
+
177
188
  // Create new PylonChatView
178
189
  val newView = PylonChatView(context, cfg, usr)
179
190
  newView.setListener(object : PylonChatListener {
180
191
  override fun onPylonLoaded() {
181
192
  sendEvent("onPylonLoaded", Arguments.createMap())
182
193
  }
183
-
194
+
184
195
  override fun onPylonInitialized() {
185
196
  sendEvent("onPylonInitialized", Arguments.createMap())
186
197
  }
187
-
198
+
188
199
  override fun onPylonReady() {
189
200
  sendEvent("onPylonReady", Arguments.createMap())
190
201
  }
191
-
202
+
192
203
  override fun onMessageReceived(message: String) {
193
204
  val params = Arguments.createMap()
194
205
  params.putString("message", message)
195
206
  sendEvent("onMessageReceived", params)
196
207
  }
197
-
208
+
198
209
  override fun onChatOpened() {
199
210
  sendEvent("onChatOpened", Arguments.createMap())
200
211
  }
201
-
212
+
202
213
  override fun onChatClosed() {
203
214
  val params = Arguments.createMap()
204
215
  params.putBoolean("wasOpen", true)
205
216
  sendEvent("onChatClosed", params)
206
217
  }
207
-
218
+
208
219
  override fun onInteractiveBoundsChanged(selector: String, left: Float, top: Float, right: Float, bottom: Float) {
209
220
  // Convert pixels to density-independent pixels (dp) for React Native.
210
221
  val density = resources.displayMetrics.density
@@ -216,57 +227,57 @@ class RNPylonChatView(context: Context) : FrameLayout(context) {
216
227
  params.putDouble("bottom", (bottom / density).toDouble())
217
228
  sendEvent("onInteractiveBoundsChanged", params)
218
229
  }
219
-
230
+
220
231
  override fun onPylonError(error: String) {
221
232
  val params = Arguments.createMap()
222
233
  params.putString("error", error)
223
234
  sendEvent("onPylonError", params)
224
235
  }
225
-
236
+
226
237
  override fun onUnreadCountChanged(count: Int) {
227
238
  val params = Arguments.createMap()
228
239
  params.putInt("count", count)
229
240
  sendEvent("onUnreadCountChanged", params)
230
241
  }
231
-
242
+
232
243
  override fun onFileChooserLaunched(requestCode: Int) {
233
244
  // Handle file chooser if needed
234
245
  }
235
246
  })
236
-
247
+
237
248
  newView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
238
249
  addView(newView)
239
250
  pylonChatView = newView
240
251
  }
241
-
252
+
242
253
  private fun sendEvent(eventName: String, params: WritableMap) {
243
254
  val reactContext = context as ReactContext
244
255
  reactContext
245
256
  .getJSModule(RCTEventEmitter::class.java)
246
257
  .receiveEvent(id, eventName, params)
247
258
  }
248
-
259
+
249
260
  // Imperative methods
250
261
  fun openChat() {
251
262
  pylonChatView?.openChat()
252
263
  }
253
-
264
+
254
265
  fun closeChat() {
255
266
  pylonChatView?.closeChat()
256
267
  }
257
-
268
+
258
269
  fun showChatBubble() {
259
270
  pylonChatView?.showChatBubble()
260
271
  }
261
-
272
+
262
273
  fun hideChatBubble() {
263
274
  pylonChatView?.hideChatBubble()
264
275
  }
265
-
276
+
266
277
  fun showNewMessage(message: String, isHtml: Boolean) {
267
278
  pylonChatView?.showNewMessage(message, isHtml)
268
279
  }
269
-
280
+
270
281
  fun setNewIssueCustomFields(fields: Map<String, Any?>) {
271
282
  @Suppress("UNCHECKED_CAST")
272
283
  pylonChatView?.setNewIssueCustomFields(fields as Map<String, Any>)
@@ -276,19 +287,19 @@ class RNPylonChatView(context: Context) : FrameLayout(context) {
276
287
  @Suppress("UNCHECKED_CAST")
277
288
  pylonChatView?.setTicketFormFields(fields as Map<String, Any>)
278
289
  }
279
-
290
+
280
291
  fun updateEmailHash(emailHash: String?) {
281
292
  pylonChatView?.setEmailHash(emailHash)
282
293
  }
283
-
294
+
284
295
  fun showTicketForm(slug: String) {
285
296
  pylonChatView?.showTicketForm(slug)
286
297
  }
287
-
298
+
288
299
  fun showKnowledgeBaseArticle(articleId: String) {
289
300
  pylonChatView?.showKnowledgeBaseArticle(articleId)
290
301
  }
291
-
302
+
292
303
  fun clickElementAtSelector(selector: String) {
293
304
  // Trigger a click on the element with the given ID selector.
294
305
  // This is used for Android's proxy-based touch pass-through system.
@@ -15,7 +15,7 @@ import com.pylon.chatwidget.PylonConfig
15
15
  import com.pylon.chatwidget.PylonUser
16
16
 
17
17
  class RNPylonChatViewManager : SimpleViewManager<RNPylonChatView>() {
18
-
18
+
19
19
  companion object {
20
20
  const val REACT_CLASS = "RNPylonChatView"
21
21
  const val COMMAND_OPEN_CHAT = 1
@@ -67,7 +67,7 @@ class RNPylonChatViewManager : SimpleViewManager<RNPylonChatView>() {
67
67
  fun setPointerEvents(view: RNPylonChatView, pointerEvents: String?) {
68
68
  val mode = pointerEvents ?: "auto"
69
69
  view.setPointerEventsMode(mode)
70
-
70
+
71
71
  when (mode) {
72
72
  "none" -> {
73
73
  // Don't handle any touches - let them pass through
@@ -128,6 +128,12 @@ class RNPylonChatViewManager : SimpleViewManager<RNPylonChatView>() {
128
128
  view.userAccountExternalId = id
129
129
  }
130
130
 
131
+ // Coordinate space adjustment
132
+ @ReactProp(name = "topInset", defaultFloat = 0f)
133
+ fun setTopInset(view: RNPylonChatView, inset: Float) {
134
+ view.topInset = inset
135
+ }
136
+
131
137
  // Event names
132
138
  override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
133
139
  return MapBuilder.builder<String, Any>()
@@ -14,61 +14,61 @@ import WebKit
14
14
  // Note: PylonChat files will be added to Xcode project from ../../ios/PylonChat/
15
15
 
16
16
  class RNPylonChatView: UIView {
17
-
17
+
18
18
  private var pylonChatView: PylonChatView?
19
19
  private var config: PylonConfig?
20
20
  private var user: PylonUser?
21
-
21
+
22
22
  // Config properties
23
23
  @objc var appId: NSString = "" {
24
24
  didSet { updateConfig() }
25
25
  }
26
-
26
+
27
27
  @objc var widgetBaseUrl: NSString? {
28
28
  didSet { updateConfig() }
29
29
  }
30
-
30
+
31
31
  @objc var widgetScriptUrl: NSString? {
32
32
  didSet { updateConfig() }
33
33
  }
34
-
34
+
35
35
  @objc var enableLogging: Bool = true {
36
36
  didSet { updateConfig() }
37
37
  }
38
-
38
+
39
39
  @objc var debugMode: Bool = false {
40
40
  didSet { updateConfig() }
41
41
  }
42
-
42
+
43
43
  @objc var primaryColor: NSString? {
44
44
  didSet { updateConfig() }
45
45
  }
46
-
46
+
47
47
  // User properties
48
48
  @objc var userEmail: NSString? {
49
49
  didSet { updateUser() }
50
50
  }
51
-
51
+
52
52
  @objc var userName: NSString? {
53
53
  didSet { updateUser() }
54
54
  }
55
-
55
+
56
56
  @objc var userAvatarUrl: NSString? {
57
57
  didSet { updateUser() }
58
58
  }
59
-
59
+
60
60
  @objc var userEmailHash: NSString? {
61
61
  didSet { updateUser() }
62
62
  }
63
-
63
+
64
64
  @objc var userAccountId: NSString? {
65
65
  didSet { updateUser() }
66
66
  }
67
-
67
+
68
68
  @objc var userAccountExternalId: NSString? {
69
69
  didSet { updateUser() }
70
70
  }
71
-
71
+
72
72
  // Safe area top inset for coordinate space adjustment
73
73
  @objc var topInset: NSNumber = 0 {
74
74
  didSet {
@@ -77,7 +77,7 @@ class RNPylonChatView: UIView {
77
77
  }
78
78
  }
79
79
  }
80
-
80
+
81
81
  // Event callbacks - renamed to avoid collision with PylonChatListener methods
82
82
  @objc var rctOnPylonLoaded: RCTBubblingEventBlock?
83
83
  @objc var rctOnPylonInitialized: RCTBubblingEventBlock?
@@ -87,28 +87,28 @@ class RNPylonChatView: UIView {
87
87
  @objc var rctOnUnreadCountChanged: RCTBubblingEventBlock?
88
88
  @objc var rctOnMessageReceived: RCTBubblingEventBlock?
89
89
  @objc var rctOnPylonError: RCTBubblingEventBlock?
90
-
90
+
91
91
  override init(frame: CGRect) {
92
92
  super.init(frame: frame)
93
93
  setupView()
94
94
  }
95
-
95
+
96
96
  required init?(coder: NSCoder) {
97
97
  super.init(coder: coder)
98
98
  setupView()
99
99
  }
100
-
100
+
101
101
  private func setupView() {
102
102
  backgroundColor = .clear
103
103
  }
104
-
104
+
105
105
  // Override pointInside to make React Native call hitTest
106
106
  public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
107
107
  // Always return true so React Native will call hitTest
108
108
  // The actual hit detection happens in hitTest
109
109
  return true
110
110
  }
111
-
111
+
112
112
  // Forward hit testing to the embedded PylonChatView
113
113
  public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
114
114
  // If we have a PylonChatView, let it handle hit testing
@@ -117,14 +117,14 @@ class RNPylonChatView: UIView {
117
117
  let convertedPoint = convert(point, to: pylonView)
118
118
  return pylonView.hitTest(convertedPoint, with: event)
119
119
  }
120
-
120
+
121
121
  // If no PylonChatView yet, pass through (return nil)
122
122
  return nil
123
123
  }
124
-
124
+
125
125
  private func updateConfig() {
126
126
  guard (appId as String).isEmpty == false else { return }
127
-
127
+
128
128
  config = PylonConfig(
129
129
  appId: appId as String,
130
130
  enableLogging: enableLogging,
@@ -133,14 +133,14 @@ class RNPylonChatView: UIView {
133
133
  widgetBaseUrl: widgetBaseUrl as String?,
134
134
  widgetScriptUrl: widgetScriptUrl as String?
135
135
  )
136
-
136
+
137
137
  recreatePylonView()
138
138
  }
139
-
139
+
140
140
  private func updateUser() {
141
141
  guard let email = userEmail as String?,
142
142
  let name = userName as String? else { return }
143
-
143
+
144
144
  user = PylonUser(
145
145
  email: email,
146
146
  name: name,
@@ -149,75 +149,75 @@ class RNPylonChatView: UIView {
149
149
  accountId: userAccountId as String?,
150
150
  accountExternalId: userAccountExternalId as String?
151
151
  )
152
-
152
+
153
153
  recreatePylonView()
154
154
  }
155
-
155
+
156
156
  private func recreatePylonView() {
157
157
  guard let config = config, let user = user else { return }
158
-
158
+
159
159
  // Remove old view
160
160
  pylonChatView?.removeFromSuperview()
161
-
161
+
162
162
  // Create new PylonChatView
163
163
  let newView = PylonChatView(config: config, user: user)
164
164
  newView.listener = self
165
165
  newView.topInset = CGFloat(truncating: topInset)
166
166
  newView.translatesAutoresizingMaskIntoConstraints = false
167
-
167
+
168
168
  addSubview(newView)
169
-
169
+
170
170
  NSLayoutConstraint.activate([
171
171
  newView.topAnchor.constraint(equalTo: topAnchor),
172
172
  newView.leadingAnchor.constraint(equalTo: leadingAnchor),
173
173
  newView.trailingAnchor.constraint(equalTo: trailingAnchor),
174
174
  newView.bottomAnchor.constraint(equalTo: bottomAnchor)
175
175
  ])
176
-
176
+
177
177
  pylonChatView = newView
178
-
178
+
179
179
  // Force layout
180
180
  setNeedsLayout()
181
181
  layoutIfNeeded()
182
182
  }
183
-
183
+
184
184
  // Imperative methods (called from React Native)
185
185
  func openChat() {
186
186
  pylonChatView?.openChat()
187
187
  }
188
-
188
+
189
189
  func closeChat() {
190
190
  pylonChatView?.closeChat()
191
191
  }
192
-
192
+
193
193
  func showChatBubble() {
194
194
  pylonChatView?.showChatBubble()
195
195
  }
196
-
196
+
197
197
  func hideChatBubble() {
198
198
  pylonChatView?.hideChatBubble()
199
199
  }
200
-
200
+
201
201
  func showNewMessage(_ message: String, isHtml: Bool) {
202
202
  pylonChatView?.showNewMessage(message, isHtml: isHtml)
203
203
  }
204
-
204
+
205
205
  func setNewIssueCustomFields(_ fields: [String: Any]) {
206
206
  pylonChatView?.setNewIssueCustomFields(fields)
207
207
  }
208
-
208
+
209
209
  func setTicketFormFields(_ fields: [String: Any]) {
210
210
  pylonChatView?.setTicketFormFields(fields)
211
211
  }
212
-
212
+
213
213
  func updateEmailHash(_ emailHash: String?) {
214
214
  pylonChatView?.updateEmailHash(emailHash)
215
215
  }
216
-
216
+
217
217
  func showTicketForm(_ slug: String) {
218
218
  pylonChatView?.showTicketForm(slug)
219
219
  }
220
-
220
+
221
221
  func showKnowledgeBaseArticle(_ articleId: String) {
222
222
  pylonChatView?.showKnowledgeBaseArticle(articleId)
223
223
  }
@@ -228,31 +228,31 @@ extension RNPylonChatView: PylonChatListener {
228
228
  func onPylonLoaded() {
229
229
  rctOnPylonLoaded?([:])
230
230
  }
231
-
231
+
232
232
  func onPylonInitialized() {
233
233
  rctOnPylonInitialized?([:])
234
234
  }
235
-
235
+
236
236
  func onPylonReady() {
237
237
  rctOnPylonReady?([:])
238
238
  }
239
-
239
+
240
240
  func onMessageReceived(message: String) {
241
241
  rctOnMessageReceived?(["message": message])
242
242
  }
243
-
243
+
244
244
  func onChatOpened() {
245
245
  rctOnChatOpened?([:])
246
246
  }
247
-
247
+
248
248
  func onChatClosed(wasOpen: Bool) {
249
249
  rctOnChatClosed?(["wasOpen": wasOpen])
250
250
  }
251
-
251
+
252
252
  func onPylonError(error: String) {
253
253
  rctOnPylonError?(["error": error])
254
254
  }
255
-
255
+
256
256
  func onUnreadCountChanged(count: Int) {
257
257
  rctOnUnreadCountChanged?(["count": count])
258
258
  }
@@ -261,71 +261,90 @@ extension RNPylonChatView: PylonChatListener {
261
261
  // MARK: - Imperative method helpers
262
262
  extension RNPylonChatViewManager {
263
263
  @objc func openChat(_ reactTag: NSNumber) {
264
- bridge.uiManager.addUIBlock { _, viewRegistry in
265
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
264
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
265
+ // Use uiManager.view(forReactTag:) instead of viewRegistry
266
+ guard let uiManager = uiManager else {
267
+ print("⚠️ RNPylonChat: uiManager is nil")
268
+ return
269
+ }
270
+
271
+ guard let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else {
272
+ print("⚠️ RNPylonChat: Could not find view for reactTag: \(reactTag)")
273
+ return
274
+ }
275
+
266
276
  view.openChat()
267
277
  }
268
278
  }
269
-
279
+
270
280
  @objc func closeChat(_ reactTag: NSNumber) {
271
- bridge.uiManager.addUIBlock { _, viewRegistry in
272
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
281
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
282
+ guard let uiManager = uiManager,
283
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
273
284
  view.closeChat()
274
285
  }
275
286
  }
276
-
287
+
277
288
  @objc func showChatBubble(_ reactTag: NSNumber) {
278
- bridge.uiManager.addUIBlock { _, viewRegistry in
279
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
289
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
290
+ guard let uiManager = uiManager,
291
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
280
292
  view.showChatBubble()
281
293
  }
282
294
  }
283
-
295
+
284
296
  @objc func hideChatBubble(_ reactTag: NSNumber) {
285
- bridge.uiManager.addUIBlock { _, viewRegistry in
286
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
297
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
298
+ guard let uiManager = uiManager,
299
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
287
300
  view.hideChatBubble()
288
301
  }
289
302
  }
290
-
303
+
291
304
  @objc func showNewMessage(_ reactTag: NSNumber, message: NSString, isHtml: Bool) {
292
- bridge.uiManager.addUIBlock { _, viewRegistry in
293
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
305
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
306
+ guard let uiManager = uiManager,
307
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
294
308
  view.showNewMessage(message as String, isHtml: isHtml)
295
309
  }
296
310
  }
297
-
311
+
298
312
  @objc func setNewIssueCustomFields(_ reactTag: NSNumber, fields: NSDictionary) {
299
- bridge.uiManager.addUIBlock { _, viewRegistry in
300
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
313
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
314
+ guard let uiManager = uiManager,
315
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
301
316
  view.setNewIssueCustomFields(fields as! [String: Any])
302
317
  }
303
318
  }
304
-
319
+
305
320
  @objc func setTicketFormFields(_ reactTag: NSNumber, fields: NSDictionary) {
306
- bridge.uiManager.addUIBlock { _, viewRegistry in
307
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
321
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
322
+ guard let uiManager = uiManager,
323
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
308
324
  view.setTicketFormFields(fields as! [String: Any])
309
325
  }
310
326
  }
311
-
327
+
312
328
  @objc func updateEmailHash(_ reactTag: NSNumber, emailHash: NSString?) {
313
- bridge.uiManager.addUIBlock { _, viewRegistry in
314
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
329
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
330
+ guard let uiManager = uiManager,
331
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
315
332
  view.updateEmailHash(emailHash as String?)
316
333
  }
317
334
  }
318
-
335
+
319
336
  @objc func showTicketForm(_ reactTag: NSNumber, slug: NSString) {
320
- bridge.uiManager.addUIBlock { _, viewRegistry in
321
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
337
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
338
+ guard let uiManager = uiManager,
339
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
322
340
  view.showTicketForm(slug as String)
323
341
  }
324
342
  }
325
-
343
+
326
344
  @objc func showKnowledgeBaseArticle(_ reactTag: NSNumber, articleId: NSString) {
327
- bridge.uiManager.addUIBlock { _, viewRegistry in
328
- guard let view = viewRegistry?[reactTag] as? RNPylonChatView else { return }
345
+ self.bridge.uiManager.addUIBlock { uiManager, _ in
346
+ guard let uiManager = uiManager,
347
+ let view = uiManager.view(forReactTag: reactTag) as? RNPylonChatView else { return }
329
348
  view.showKnowledgeBaseArticle(articleId as String)
330
349
  }
331
350
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rematter/pylon-react-native",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Pylon Chat SDK for React Native",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",