react-native-tpstreams 1.0.0 → 1.0.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.
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
21
21
  'DEFINES_MODULE' => 'YES',
22
22
  'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
23
23
  }
24
- s.dependency "TPStreamsSDK"
24
+ s.dependency "TPStreamsSDK" , "1.2.8"
25
25
 
26
26
 
27
27
  # Ensure the module is not built as a framework to avoid bridging header conflicts
@@ -11,15 +11,26 @@ private enum PlayerConstants {
11
11
  static let statusUnknown = "Unknown"
12
12
  }
13
13
 
14
+ protocol TokenRequestDelegate: AnyObject {
15
+ func requestToken(for assetId: String, completion: @escaping (String?) -> Void)
16
+ }
17
+
14
18
  @objc(TPStreamsDownload)
15
19
  class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
16
20
 
17
21
  private let downloadManager = TPStreamsDownloadManager.shared
18
22
  private var isListening = false
23
+ private var tokenDelegate: TokenRequestDelegate?
24
+ static var shared: TPStreamsDownloadModule?
19
25
 
20
26
  override init() {
21
27
  super.init()
22
28
  downloadManager.setTPStreamsDownloadDelegate(tpStreamsDownloadDelegate: self)
29
+ TPStreamsDownloadModule.shared = self
30
+ }
31
+
32
+ func setAccessTokenDelegate(_ delegate: TokenRequestDelegate) {
33
+ self.tokenDelegate = delegate
23
34
  }
24
35
 
25
36
  @objc
@@ -86,6 +97,14 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
86
97
  notifyDownloadsChange()
87
98
  }
88
99
  }
100
+
101
+ func onRequestNewAccessToken(assetId: String, completion: @escaping (String?) -> Void) {
102
+ if let delegate = tokenDelegate {
103
+ delegate.requestToken(for: assetId, completion: completion)
104
+ } else {
105
+ completion(nil)
106
+ }
107
+ }
89
108
 
90
109
  private func notifyDownloadsChange() {
91
110
  DispatchQueue.main.async { [weak self] in
@@ -104,11 +123,12 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
104
123
  var item: [String: Any] = [:]
105
124
  item["videoId"] = asset.assetId
106
125
  item["title"] = asset.title
126
+ item["thumbnailUrl"] = asset.thumbnailURL
107
127
  item["totalBytes"] = asset.size
108
128
  item["downloadedBytes"] = calculateDownloadedBytes(size: asset.size, progress: asset.percentageCompleted)
109
129
  item["progressPercentage"] = asset.percentageCompleted
110
130
  item["state"] = mapDownloadStatus(Status(rawValue: asset.status))
111
- item["metadata"] = "{}"
131
+ item["metadata"] = asset.metadata ?? "{}"
112
132
 
113
133
  return item
114
134
  }
@@ -13,10 +13,15 @@ class TPStreamsModule: NSObject {
13
13
  DispatchQueue.main.async {
14
14
  TPStreamsSDK.initialize(withOrgCode: organizationId as String)
15
15
  self.isInitialized = true
16
+ self.initializeDownloadModule()
16
17
  }
17
18
  }
18
19
  }
19
20
 
21
+ private func initializeDownloadModule() {
22
+ let _ = TPStreamsDownloadModule()
23
+ }
24
+
20
25
  @objc
21
26
  static func requiresMainQueueSetup() -> Bool {
22
27
  return true
@@ -31,6 +31,8 @@ class TPStreamsRNPlayerView: UIView {
31
31
  @objc var onIsLoadingChanged: RCTDirectEventBlock?
32
32
  @objc var onError: RCTDirectEventBlock?
33
33
  @objc var onAccessTokenExpired: RCTDirectEventBlock?
34
+
35
+ private var pendingTokenCompletion: ((String?) -> Void)?
34
36
 
35
37
  override init(frame: CGRect) {
36
38
  super.init(frame: frame)
@@ -73,7 +75,7 @@ class TPStreamsRNPlayerView: UIView {
73
75
  setupScheduled = false
74
76
  return
75
77
  }
76
-
78
+ setupTokenDelegate()
77
79
  configurePlayerView()
78
80
  observePlayerChanges()
79
81
  setupScheduled = false
@@ -81,14 +83,19 @@ class TPStreamsRNPlayerView: UIView {
81
83
 
82
84
  private func cleanupPlayer() {
83
85
  removeObservers()
86
+ player?.pause()
87
+
84
88
  playerViewController?.view.removeFromSuperview()
85
89
  playerViewController?.removeFromParent()
86
90
  playerViewController = nil
91
+
92
+ player?.replaceCurrentItem(with: nil)
87
93
  player = nil
88
94
  }
89
95
 
90
96
  private func removeObservers() {
91
97
  playerStatusObserver?.invalidate()
98
+ playerStatusObserver = nil
92
99
  }
93
100
 
94
101
  private func createOfflinePlayer() -> TPAVPlayer? {
@@ -131,11 +138,13 @@ class TPStreamsRNPlayerView: UIView {
131
138
  }
132
139
 
133
140
  private func createPlayerConfigBuilder() -> TPStreamPlayerConfigurationBuilder {
141
+ let metadataDict = parseMetadataJSON(from: downloadMetadata)
134
142
  let configBuilder = TPStreamPlayerConfigurationBuilder()
135
143
  .setPreferredForwardDuration(15)
136
144
  .setPreferredRewindDuration(5)
137
145
  .setprogressBarThumbColor(.systemBlue)
138
146
  .setwatchedProgressTrackColor(.systemBlue)
147
+ .setDownloadMetadata(metadataDict)
139
148
 
140
149
  if enableDownload {
141
150
  configBuilder.showDownloadOption()
@@ -170,6 +179,24 @@ class TPStreamsRNPlayerView: UIView {
170
179
  self.playerStatusObserver = nil
171
180
  }
172
181
  }
182
+
183
+ private func setupTokenDelegate() {
184
+ TPStreamsDownloadModule.shared?.setAccessTokenDelegate(self)
185
+ }
186
+
187
+ private func parseMetadataJSON(from jsonString: NSString?) -> [String: String]? {
188
+ guard let metadataString = jsonString as String? else { return nil }
189
+
190
+ guard let data = metadataString.data(using: .utf8) else { return nil }
191
+ do {
192
+ if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String] {
193
+ return json
194
+ }
195
+ } catch {
196
+ print("Error parsing metadata JSON: \(error)")
197
+ }
198
+ return nil
199
+ }
173
200
 
174
201
  @objc func seekTo(position: Double) {
175
202
  guard position >= 0, let player = player else { return }
@@ -214,11 +241,29 @@ class TPStreamsRNPlayerView: UIView {
214
241
  }
215
242
 
216
243
  @objc func setNewAccessToken(_ newToken: String) {
217
- print("New access token set: \(newToken)")
218
- // TODO: Reinitialize player with new token if needed
244
+ pendingTokenCompletion?(newToken)
245
+ pendingTokenCompletion = nil
246
+ }
247
+
248
+ override func willMove(toSuperview newSuperview: UIView?) {
249
+ if newSuperview == nil {
250
+ cleanupPlayer()
251
+ }
252
+ super.willMove(toSuperview: newSuperview)
219
253
  }
220
254
 
221
255
  deinit {
222
- removeObservers()
256
+ cleanupPlayer()
257
+ }
258
+ }
259
+
260
+ extension TPStreamsRNPlayerView: TokenRequestDelegate {
261
+ func requestToken(for assetId: String, completion: @escaping (String?) -> Void) {
262
+ guard let onAccessTokenExpired = onAccessTokenExpired else {
263
+ completion(nil)
264
+ return
265
+ }
266
+ pendingTokenCompletion = completion
267
+ onAccessTokenExpired(["videoId": assetId])
223
268
  }
224
269
  }
@@ -34,5 +34,6 @@ RCT_EXTERN_METHOD(getCurrentPosition:(nonnull NSNumber *)node)
34
34
  RCT_EXTERN_METHOD(getDuration:(nonnull NSNumber *)node)
35
35
  RCT_EXTERN_METHOD(isPlaying:(nonnull NSNumber *)node)
36
36
  RCT_EXTERN_METHOD(getPlaybackSpeed:(nonnull NSNumber *)node)
37
+ RCT_EXTERN_METHOD(setNewAccessToken:(nonnull NSNumber *)node newToken:(nonnull NSString *)newToken)
37
38
 
38
39
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-tpstreams",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Video component for TPStreams",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",