react-native-tpstreams 1.0.1 → 1.0.3-debug.0
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.
- package/README.md +76 -552
- package/TPStreamsRNPlayerView.podspec +1 -1
- package/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/TPStreamsRNPlayerViewManagerDelegate.java +87 -0
- package/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/TPStreamsRNPlayerViewManagerInterface.java +34 -0
- package/android/app/build/generated/source/codegen/jni/CMakeLists.txt +36 -0
- package/android/app/build/generated/source/codegen/jni/TPStreamsPlayerViewSpec-generated.cpp +22 -0
- package/android/app/build/generated/source/codegen/jni/TPStreamsPlayerViewSpec.h +24 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/ComponentDescriptors.cpp +22 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/ComponentDescriptors.h +24 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/EventEmitters.cpp +107 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/EventEmitters.h +81 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/Props.cpp +32 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/Props.h +34 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/ShadowNodes.cpp +17 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/ShadowNodes.h +32 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/States.cpp +16 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/States.h +29 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/TPStreamsPlayerViewSpecJSI-generated.cpp +17 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/TPStreamsPlayerViewSpec/TPStreamsPlayerViewSpecJSI.h +19 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/tpstreams/TPStreamsDownloadModule.kt +44 -34
- package/ios/TPStreamsDownloadModule.swift +77 -4
- package/ios/TPStreamsModule.swift +5 -0
- package/ios/TPStreamsRNPlayerView.swift +33 -4
- package/ios/TPStreamsRNPlayerViewManager.m +1 -0
- package/lib/module/TPStreamsDownload.js +8 -0
- package/lib/module/TPStreamsDownload.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/TPStreamsDownload.d.ts +6 -0
- package/lib/typescript/src/TPStreamsDownload.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/TPStreamsDownload.tsx +21 -0
- package/src/index.tsx +2 -0
|
@@ -6,6 +6,7 @@ import com.facebook.react.bridge.Arguments
|
|
|
6
6
|
import com.facebook.react.bridge.ReactMethod
|
|
7
7
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
8
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
9
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
10
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
10
11
|
import com.tpstreams.player.download.DownloadClient
|
|
11
12
|
import com.tpstreams.player.download.DownloadItem
|
|
@@ -68,31 +69,56 @@ class TPStreamsDownloadModule(private val reactContext: ReactApplicationContext)
|
|
|
68
69
|
|
|
69
70
|
val result = Arguments.createArray()
|
|
70
71
|
for (item in currentDownloads) {
|
|
71
|
-
val map =
|
|
72
|
-
map.putString("videoId", item.assetId)
|
|
73
|
-
map.putString("title", item.title)
|
|
74
|
-
item.thumbnailUrl?.let { map.putString("thumbnailUrl", it) }
|
|
75
|
-
map.putDouble("totalBytes", item.totalBytes.toDouble())
|
|
76
|
-
map.putDouble("downloadedBytes", item.downloadedBytes.toDouble())
|
|
77
|
-
map.putDouble("progressPercentage", item.progressPercentage.toDouble())
|
|
78
|
-
map.putString("state", downloadClient.getDownloadStatus(item.assetId))
|
|
79
|
-
|
|
80
|
-
val metadataJson = org.json.JSONObject()
|
|
81
|
-
item.metadata.forEach { (key, value) ->
|
|
82
|
-
metadataJson.put(key, value)
|
|
83
|
-
}
|
|
84
|
-
map.putString("metadata", metadataJson.toString())
|
|
85
|
-
|
|
72
|
+
val map = createDownloadItemMap(item)
|
|
86
73
|
result.pushMap(map)
|
|
87
74
|
}
|
|
88
|
-
|
|
89
75
|
emitEvent("onDownloadProgressChanged", result)
|
|
90
|
-
|
|
91
76
|
} catch (e: Exception) {
|
|
92
77
|
Log.e(TAG, "Error in onDownloadsChanged: ${e.message}", e)
|
|
93
78
|
}
|
|
94
79
|
}
|
|
95
80
|
|
|
81
|
+
override fun onDownloadStateChanged(downloadItem: DownloadItem, error: Exception?) {
|
|
82
|
+
try {
|
|
83
|
+
val map = Arguments.createMap()
|
|
84
|
+
val downloadItemMap = createDownloadItemMap(downloadItem)
|
|
85
|
+
map.putMap("downloadItem", downloadItemMap)
|
|
86
|
+
|
|
87
|
+
if (error != null) {
|
|
88
|
+
val errorMap = Arguments.createMap()
|
|
89
|
+
errorMap.putString("message", error.message ?: "Unknown error")
|
|
90
|
+
errorMap.putString("type", error.javaClass.simpleName)
|
|
91
|
+
map.putMap("error", errorMap)
|
|
92
|
+
} else {
|
|
93
|
+
map.putNull("error")
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
emitEvent("onDownloadStateChanged", map)
|
|
97
|
+
|
|
98
|
+
} catch (e: Exception) {
|
|
99
|
+
Log.e(TAG, "Error in onDownloadStateChanged: ${e.message}", e)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private fun createDownloadItemMap(item: DownloadItem): WritableMap {
|
|
104
|
+
val map = Arguments.createMap()
|
|
105
|
+
map.putString("videoId", item.assetId)
|
|
106
|
+
map.putString("title", item.title)
|
|
107
|
+
item.thumbnailUrl?.let { map.putString("thumbnailUrl", it) }
|
|
108
|
+
map.putDouble("totalBytes", item.totalBytes.toDouble())
|
|
109
|
+
map.putDouble("downloadedBytes", item.downloadedBytes.toDouble())
|
|
110
|
+
map.putDouble("progressPercentage", item.progressPercentage.toDouble())
|
|
111
|
+
map.putString("state", downloadClient.getDownloadStatus(item.assetId))
|
|
112
|
+
|
|
113
|
+
val metadataJson = org.json.JSONObject()
|
|
114
|
+
item.metadata.forEach { (key, value) ->
|
|
115
|
+
metadataJson.put(key, value)
|
|
116
|
+
}
|
|
117
|
+
map.putString("metadata", metadataJson.toString())
|
|
118
|
+
|
|
119
|
+
return map
|
|
120
|
+
}
|
|
121
|
+
|
|
96
122
|
private fun emitEvent(eventName: String, data: Any) {
|
|
97
123
|
reactContext
|
|
98
124
|
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
@@ -183,23 +209,7 @@ class TPStreamsDownloadModule(private val reactContext: ReactApplicationContext)
|
|
|
183
209
|
val result = Arguments.createArray()
|
|
184
210
|
|
|
185
211
|
for (item in downloadItems) {
|
|
186
|
-
val map =
|
|
187
|
-
map.putString("videoId", item.assetId)
|
|
188
|
-
map.putString("title", item.title)
|
|
189
|
-
item.thumbnailUrl?.let { map.putString("thumbnailUrl", it) }
|
|
190
|
-
map.putDouble("totalBytes", item.totalBytes.toDouble())
|
|
191
|
-
map.putDouble("downloadedBytes", item.downloadedBytes.toDouble())
|
|
192
|
-
map.putDouble("progressPercentage", item.progressPercentage.toDouble())
|
|
193
|
-
map.putString("state", downloadClient.getDownloadStatus(item.assetId))
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
val metadataJson = org.json.JSONObject(item.metadata as Map<*, *>)
|
|
197
|
-
map.putString("metadata", metadataJson.toString())
|
|
198
|
-
} catch (e: Exception) {
|
|
199
|
-
Log.w(TAG, "Error serializing metadata for item ${item.assetId}: ${e.message}")
|
|
200
|
-
map.putString("metadata", "{}")
|
|
201
|
-
}
|
|
202
|
-
|
|
212
|
+
val map = createDownloadItemMap(item)
|
|
203
213
|
result.pushMap(map)
|
|
204
214
|
}
|
|
205
215
|
|
|
@@ -3,23 +3,38 @@ import React
|
|
|
3
3
|
import TPStreamsSDK
|
|
4
4
|
|
|
5
5
|
private enum PlayerConstants {
|
|
6
|
-
static let
|
|
6
|
+
static let statusQueued = "Queued"
|
|
7
7
|
static let statusDownloading = "Downloading"
|
|
8
8
|
static let statusPaused = "Paused"
|
|
9
9
|
static let statusCompleted = "Completed"
|
|
10
10
|
static let statusFailed = "Failed"
|
|
11
|
+
static let statusRemoving = "Removing"
|
|
12
|
+
static let statusRestarting = "Restarting"
|
|
11
13
|
static let statusUnknown = "Unknown"
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
protocol TokenRequestDelegate: AnyObject {
|
|
17
|
+
func requestToken(for assetId: String, completion: @escaping (String?) -> Void)
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
@objc(TPStreamsDownload)
|
|
15
21
|
class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
|
|
16
22
|
|
|
17
23
|
private let downloadManager = TPStreamsDownloadManager.shared
|
|
18
24
|
private var isListening = false
|
|
25
|
+
private var tokenDelegate: TokenRequestDelegate?
|
|
26
|
+
static var shared: TPStreamsDownloadModule?
|
|
19
27
|
|
|
20
28
|
override init() {
|
|
21
29
|
super.init()
|
|
22
30
|
downloadManager.setTPStreamsDownloadDelegate(tpStreamsDownloadDelegate: self)
|
|
31
|
+
TPStreamsDownloadModule.shared = self
|
|
32
|
+
print("TPStreamsDownloadModule initialized")
|
|
33
|
+
print("Downloadmanager delegates are set")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
func setAccessTokenDelegate(_ delegate: TokenRequestDelegate) {
|
|
37
|
+
self.tokenDelegate = delegate
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
@objc
|
|
@@ -29,69 +44,121 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
|
|
|
29
44
|
|
|
30
45
|
@objc
|
|
31
46
|
func addDownloadProgressListener(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
47
|
+
print("adding download progress listener")
|
|
32
48
|
isListening = true
|
|
33
49
|
resolve(nil)
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
@objc
|
|
37
53
|
func removeDownloadProgressListener(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
54
|
+
print("removing download progress listener")
|
|
38
55
|
isListening = false
|
|
39
56
|
resolve(nil)
|
|
40
57
|
}
|
|
41
58
|
|
|
42
59
|
func onProgressChange(assetId: String, percentage: Double) {
|
|
60
|
+
print("Download Progress Changed)")
|
|
43
61
|
if isListening {
|
|
44
62
|
notifyDownloadsChange()
|
|
45
63
|
}
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
func onStateChange(status: Status, offlineAsset: OfflineAsset) {
|
|
67
|
+
print("Download State Changed")
|
|
49
68
|
if isListening {
|
|
50
69
|
notifyDownloadsChange()
|
|
51
70
|
}
|
|
52
71
|
}
|
|
53
72
|
|
|
54
73
|
func onDelete(assetId: String) {
|
|
74
|
+
print("Download Deleted")
|
|
55
75
|
if isListening {
|
|
76
|
+
if let offlineAsset = getOfflineAsset(assetId: assetId) {
|
|
77
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
78
|
+
}
|
|
56
79
|
notifyDownloadsChange()
|
|
57
80
|
}
|
|
58
81
|
}
|
|
59
82
|
|
|
60
83
|
func onStart(offlineAsset: OfflineAsset) {
|
|
84
|
+
print("Download Started")
|
|
61
85
|
if isListening {
|
|
86
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
62
87
|
notifyDownloadsChange()
|
|
63
88
|
}
|
|
64
89
|
}
|
|
65
90
|
|
|
66
91
|
func onComplete(offlineAsset: OfflineAsset) {
|
|
92
|
+
print("Download Completed")
|
|
67
93
|
if isListening {
|
|
94
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
68
95
|
notifyDownloadsChange()
|
|
69
96
|
}
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
func onPause(offlineAsset: OfflineAsset) {
|
|
100
|
+
print("Download Paused")
|
|
73
101
|
if isListening {
|
|
102
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
74
103
|
notifyDownloadsChange()
|
|
75
104
|
}
|
|
76
105
|
}
|
|
77
106
|
|
|
78
107
|
func onResume(offlineAsset: OfflineAsset) {
|
|
108
|
+
print("Download Resumed")
|
|
79
109
|
if isListening {
|
|
110
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
80
111
|
notifyDownloadsChange()
|
|
81
112
|
}
|
|
82
113
|
}
|
|
83
114
|
|
|
84
115
|
func onCanceled(assetId: String) {
|
|
116
|
+
print("Download Canceled")
|
|
85
117
|
if isListening {
|
|
118
|
+
if let offlineAsset = getOfflineAsset(assetId: assetId) {
|
|
119
|
+
notifyDownloadStateChanged(offlineAsset: offlineAsset)
|
|
120
|
+
}
|
|
86
121
|
notifyDownloadsChange()
|
|
87
122
|
}
|
|
88
123
|
}
|
|
124
|
+
|
|
125
|
+
func onRequestNewAccessToken(assetId: String, completion: @escaping (String?) -> Void) {
|
|
126
|
+
if let delegate = tokenDelegate {
|
|
127
|
+
delegate.requestToken(for: assetId, completion: completion)
|
|
128
|
+
} else {
|
|
129
|
+
completion(nil)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
89
132
|
|
|
90
133
|
private func notifyDownloadsChange() {
|
|
134
|
+
print("notifying downloads change to js")
|
|
91
135
|
DispatchQueue.main.async { [weak self] in
|
|
92
136
|
guard let self = self else { return }
|
|
93
137
|
let downloadAssets = self.getAllDownloadItems()
|
|
94
138
|
self.sendEvent(withName: "onDownloadProgressChanged", body: downloadAssets)
|
|
139
|
+
print("notified downloads change event to js")
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private func notifyDownloadStateChanged(offlineAsset: OfflineAsset, error: Error? = nil) {
|
|
144
|
+
DispatchQueue.main.async { [weak self] in
|
|
145
|
+
guard let self = self else { return }
|
|
146
|
+
|
|
147
|
+
let downloadItem = self.mapOfflineAssetToDict(offlineAsset)
|
|
148
|
+
|
|
149
|
+
var eventData: [String: Any] = [:]
|
|
150
|
+
eventData["downloadItem"] = downloadItem
|
|
151
|
+
|
|
152
|
+
if let error = error {
|
|
153
|
+
eventData["error"] = [
|
|
154
|
+
"message": error.localizedDescription,
|
|
155
|
+
"type": String(describing: type(of: error))
|
|
156
|
+
]
|
|
157
|
+
} else {
|
|
158
|
+
eventData["error"] = NSNull()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
self.sendEvent(withName: "onDownloadStateChanged", body: eventData)
|
|
95
162
|
}
|
|
96
163
|
}
|
|
97
164
|
|
|
@@ -211,7 +278,7 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
|
|
|
211
278
|
if let asset = offlineAssets.first(where: { $0.assetId == videoId }) {
|
|
212
279
|
resolve(mapDownloadStatus(Status(rawValue: asset.status)))
|
|
213
280
|
} else {
|
|
214
|
-
resolve(PlayerConstants.
|
|
281
|
+
resolve(PlayerConstants.statusUnknown)
|
|
215
282
|
}
|
|
216
283
|
}
|
|
217
284
|
}
|
|
@@ -241,22 +308,28 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate {
|
|
|
241
308
|
case .failed:
|
|
242
309
|
return PlayerConstants.statusFailed
|
|
243
310
|
default:
|
|
244
|
-
return PlayerConstants.
|
|
311
|
+
return PlayerConstants.statusUnknown
|
|
245
312
|
}
|
|
246
313
|
}
|
|
247
314
|
|
|
315
|
+
private func getOfflineAsset(assetId: String) -> OfflineAsset? {
|
|
316
|
+
return downloadManager.getAllOfflineAssets().first(where: { $0.assetId == assetId })
|
|
317
|
+
}
|
|
318
|
+
|
|
248
319
|
@objc
|
|
249
320
|
override func supportedEvents() -> [String] {
|
|
250
|
-
return ["onDownloadProgressChanged"]
|
|
321
|
+
return ["onDownloadProgressChanged", "onDownloadStateChanged"]
|
|
251
322
|
}
|
|
252
323
|
|
|
253
324
|
@objc
|
|
254
325
|
override func addListener(_ eventName: String) {
|
|
326
|
+
print("adding listener: \(eventName)")
|
|
255
327
|
super.addListener(eventName)
|
|
256
328
|
}
|
|
257
329
|
|
|
258
330
|
@objc
|
|
259
331
|
override func removeListeners(_ count: Double) {
|
|
332
|
+
print("removing listener: \(count)")
|
|
260
333
|
super.removeListeners(count)
|
|
261
334
|
|
|
262
335
|
if count >= 1 && isListening {
|
|
@@ -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? {
|
|
@@ -173,6 +180,10 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
173
180
|
}
|
|
174
181
|
}
|
|
175
182
|
|
|
183
|
+
private func setupTokenDelegate() {
|
|
184
|
+
TPStreamsDownloadModule.shared?.setAccessTokenDelegate(self)
|
|
185
|
+
}
|
|
186
|
+
|
|
176
187
|
private func parseMetadataJSON(from jsonString: NSString?) -> [String: String]? {
|
|
177
188
|
guard let metadataString = jsonString as String? else { return nil }
|
|
178
189
|
|
|
@@ -230,11 +241,29 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
230
241
|
}
|
|
231
242
|
|
|
232
243
|
@objc func setNewAccessToken(_ newToken: String) {
|
|
233
|
-
|
|
234
|
-
|
|
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)
|
|
235
253
|
}
|
|
236
254
|
|
|
237
255
|
deinit {
|
|
238
|
-
|
|
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])
|
|
239
268
|
}
|
|
240
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
|
|
@@ -6,14 +6,22 @@ const {
|
|
|
6
6
|
} = NativeModules;
|
|
7
7
|
const downloadEventEmitter = new NativeEventEmitter(TPStreamsDownload);
|
|
8
8
|
export function addDownloadProgressListener() {
|
|
9
|
+
console.log('JS: addDownloadProgressListener');
|
|
9
10
|
return TPStreamsDownload.addDownloadProgressListener();
|
|
10
11
|
}
|
|
11
12
|
export function removeDownloadProgressListener() {
|
|
13
|
+
console.log('JS: removeDownloadProgressListener');
|
|
12
14
|
return TPStreamsDownload.removeDownloadProgressListener();
|
|
13
15
|
}
|
|
14
16
|
export function onDownloadProgressChanged(listener) {
|
|
17
|
+
console.log('JS: onDownloadProgressChanged');
|
|
15
18
|
return downloadEventEmitter.addListener('onDownloadProgressChanged', listener);
|
|
16
19
|
}
|
|
20
|
+
export function onDownloadStateChanged(listener) {
|
|
21
|
+
return downloadEventEmitter.addListener('onDownloadStateChanged', event => {
|
|
22
|
+
listener(event.downloadItem, event.error);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
17
25
|
export function pauseDownload(videoId) {
|
|
18
26
|
return TPStreamsDownload.pauseDownload(videoId);
|
|
19
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","NativeEventEmitter","TPStreamsDownload","downloadEventEmitter","addDownloadProgressListener","removeDownloadProgressListener","onDownloadProgressChanged","listener","addListener","pauseDownload","videoId","resumeDownload","removeDownload","isDownloaded","isDownloading","isPaused","getDownloadStatus","getAllDownloads"],"sourceRoot":"../../src","sources":["TPStreamsDownload.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,cAAc;AAGhE,MAAM;EAAEC;AAAkB,CAAC,GAAGF,aAAa;
|
|
1
|
+
{"version":3,"names":["NativeModules","NativeEventEmitter","TPStreamsDownload","downloadEventEmitter","addDownloadProgressListener","console","log","removeDownloadProgressListener","onDownloadProgressChanged","listener","addListener","onDownloadStateChanged","event","downloadItem","error","pauseDownload","videoId","resumeDownload","removeDownload","isDownloaded","isDownloading","isPaused","getDownloadStatus","getAllDownloads"],"sourceRoot":"../../src","sources":["TPStreamsDownload.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,cAAc;AAGhE,MAAM;EAAEC;AAAkB,CAAC,GAAGF,aAAa;AA4B3C,MAAMG,oBAAoB,GAAG,IAAIF,kBAAkB,CAACC,iBAAiB,CAAC;AAEtE,OAAO,SAASE,2BAA2BA,CAAA,EAAkB;EAC3DC,OAAO,CAACC,GAAG,CAAC,iCAAiC,CAAC;EAC9C,OAAOJ,iBAAiB,CAACE,2BAA2B,CAAC,CAAC;AACxD;AAEA,OAAO,SAASG,8BAA8BA,CAAA,EAAkB;EAC9DF,OAAO,CAACC,GAAG,CAAC,oCAAoC,CAAC;EACjD,OAAOJ,iBAAiB,CAACK,8BAA8B,CAAC,CAAC;AAC3D;AAEA,OAAO,SAASC,yBAAyBA,CACvCC,QAAkC,EACb;EACrBJ,OAAO,CAACC,GAAG,CAAC,+BAA+B,CAAC;EAC5C,OAAOH,oBAAoB,CAACO,WAAW,CACrC,2BAA2B,EAC3BD,QACF,CAAC;AACH;AAEA,OAAO,SAASE,sBAAsBA,CACpCF,QAAqC,EAChB;EACrB,OAAON,oBAAoB,CAACO,WAAW,CAAC,wBAAwB,EAAGE,KAAK,IAAK;IAC3EH,QAAQ,CAACG,KAAK,CAACC,YAAY,EAAED,KAAK,CAACE,KAAK,CAAC;EAC3C,CAAC,CAAC;AACJ;AAEA,OAAO,SAASC,aAAaA,CAACC,OAAe,EAAiB;EAC5D,OAAOd,iBAAiB,CAACa,aAAa,CAACC,OAAO,CAAC;AACjD;AAEA,OAAO,SAASC,cAAcA,CAACD,OAAe,EAAiB;EAC7D,OAAOd,iBAAiB,CAACe,cAAc,CAACD,OAAO,CAAC;AAClD;AAEA,OAAO,SAASE,cAAcA,CAACF,OAAe,EAAiB;EAC7D,OAAOd,iBAAiB,CAACgB,cAAc,CAACF,OAAO,CAAC;AAClD;AAEA,OAAO,SAASG,YAAYA,CAACH,OAAe,EAAoB;EAC9D,OAAOd,iBAAiB,CAACiB,YAAY,CAACH,OAAO,CAAC;AAChD;AAEA,OAAO,SAASI,aAAaA,CAACJ,OAAe,EAAoB;EAC/D,OAAOd,iBAAiB,CAACkB,aAAa,CAACJ,OAAO,CAAC;AACjD;AAEA,OAAO,SAASK,QAAQA,CAACL,OAAe,EAAoB;EAC1D,OAAOd,iBAAiB,CAACmB,QAAQ,CAACL,OAAO,CAAC;AAC5C;AAEA,OAAO,SAASM,iBAAiBA,CAACN,OAAe,EAAmB;EAClE,OAAOd,iBAAiB,CAACoB,iBAAiB,CAACN,OAAO,CAAC;AACrD;AAEA,OAAO,SAASO,eAAeA,CAAA,EAA4B;EACzD,OAAOrB,iBAAiB,CAACqB,eAAe,CAAC,CAAC;AAC5C","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export * from './TPStreamsPlayerViewNativeComponent';
|
|
|
7
7
|
|
|
8
8
|
// Export the wrapper component as TPStreamsPlayerView
|
|
9
9
|
export { default as TPStreamsPlayerView } from "./TPStreamsPlayer.js";
|
|
10
|
-
export { pauseDownload, resumeDownload, removeDownload, isDownloaded, isDownloading, isPaused, getDownloadStatus, getAllDownloads, addDownloadProgressListener, removeDownloadProgressListener, onDownloadProgressChanged } from "./TPStreamsDownload.js";
|
|
10
|
+
export { pauseDownload, resumeDownload, removeDownload, isDownloaded, isDownloading, isPaused, getDownloadStatus, getAllDownloads, addDownloadProgressListener, removeDownloadProgressListener, onDownloadProgressChanged, onDownloadStateChanged } from "./TPStreamsDownload.js";
|
|
11
11
|
const TPStreamsModule = NativeModules.TPStreams;
|
|
12
12
|
export const TPStreams = {
|
|
13
13
|
initialize: organizationId => {
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","default","TPStreamsPlayerNative","TPStreamsPlayerView","pauseDownload","resumeDownload","removeDownload","isDownloaded","isDownloading","isPaused","getDownloadStatus","getAllDownloads","addDownloadProgressListener","removeDownloadProgressListener","onDownloadProgressChanged","TPStreamsModule","TPStreams","initialize","organizationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C;AACA,SAASC,OAAO,IAAIC,qBAAqB,QAAQ,sCAAsC;AACvF,cAAc,sCAAsC;;AAEpD;AACA,SAASD,OAAO,IAAIE,mBAAmB,QAAQ,sBAAmB;AAGlE,SACEC,aAAa,EACbC,cAAc,EACdC,cAAc,EACdC,YAAY,EACZC,aAAa,EACbC,QAAQ,EACRC,iBAAiB,EACjBC,eAAe,EACfC,2BAA2B,EAC3BC,8BAA8B,EAC9BC,yBAAyB,
|
|
1
|
+
{"version":3,"names":["NativeModules","default","TPStreamsPlayerNative","TPStreamsPlayerView","pauseDownload","resumeDownload","removeDownload","isDownloaded","isDownloading","isPaused","getDownloadStatus","getAllDownloads","addDownloadProgressListener","removeDownloadProgressListener","onDownloadProgressChanged","onDownloadStateChanged","TPStreamsModule","TPStreams","initialize","organizationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C;AACA,SAASC,OAAO,IAAIC,qBAAqB,QAAQ,sCAAsC;AACvF,cAAc,sCAAsC;;AAEpD;AACA,SAASD,OAAO,IAAIE,mBAAmB,QAAQ,sBAAmB;AAGlE,SACEC,aAAa,EACbC,cAAc,EACdC,cAAc,EACdC,YAAY,EACZC,aAAa,EACbC,QAAQ,EACRC,iBAAiB,EACjBC,eAAe,EACfC,2BAA2B,EAC3BC,8BAA8B,EAC9BC,yBAAyB,EACzBC,sBAAsB,QAKjB,wBAAqB;AAE5B,MAAMC,eAAe,GAAGhB,aAAa,CAACiB,SAAS;AAE/C,OAAO,MAAMA,SAAS,GAAG;EACvBC,UAAU,EAAGC,cAAsB,IAAW;IAC5CH,eAAe,CAACE,UAAU,CAACC,cAAc,CAAC;EAC5C;AACF,CAAC","ignoreList":[]}
|
|
@@ -11,9 +11,15 @@ export interface DownloadItem {
|
|
|
11
11
|
}
|
|
12
12
|
export type DownloadProgressChange = DownloadItem;
|
|
13
13
|
export type DownloadProgressListener = (downloads: DownloadProgressChange[]) => void;
|
|
14
|
+
export interface DownloadError {
|
|
15
|
+
message: string;
|
|
16
|
+
type: string;
|
|
17
|
+
}
|
|
18
|
+
export type DownloadStateChangeListener = (downloadItem: DownloadItem, error: DownloadError | null) => void;
|
|
14
19
|
export declare function addDownloadProgressListener(): Promise<void>;
|
|
15
20
|
export declare function removeDownloadProgressListener(): Promise<void>;
|
|
16
21
|
export declare function onDownloadProgressChanged(listener: DownloadProgressListener): EmitterSubscription;
|
|
22
|
+
export declare function onDownloadStateChanged(listener: DownloadStateChangeListener): EmitterSubscription;
|
|
17
23
|
export declare function pauseDownload(videoId: string): Promise<void>;
|
|
18
24
|
export declare function resumeDownload(videoId: string): Promise<void>;
|
|
19
25
|
export declare function removeDownload(videoId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TPStreamsDownload.d.ts","sourceRoot":"","sources":["../../../src/TPStreamsDownload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAIxD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAClD,MAAM,MAAM,wBAAwB,GAAG,CACrC,SAAS,EAAE,sBAAsB,EAAE,KAChC,IAAI,CAAC;AAIV,wBAAgB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"TPStreamsDownload.d.ts","sourceRoot":"","sources":["../../../src/TPStreamsDownload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAIxD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAClD,MAAM,MAAM,wBAAwB,GAAG,CACrC,SAAS,EAAE,sBAAsB,EAAE,KAChC,IAAI,CAAC;AAEV,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,2BAA2B,GAAG,CACxC,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,aAAa,GAAG,IAAI,KACxB,IAAI,CAAC;AAIV,wBAAgB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3D;AAED,wBAAgB,8BAA8B,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9D;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,wBAAwB,GACjC,mBAAmB,CAMrB;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,2BAA2B,GACpC,mBAAmB,CAIrB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/D;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAElE;AAED,wBAAgB,eAAe,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzD"}
|
|
@@ -2,7 +2,7 @@ export { default as TPStreamsPlayerNative } from './TPStreamsPlayerViewNativeCom
|
|
|
2
2
|
export * from './TPStreamsPlayerViewNativeComponent';
|
|
3
3
|
export { default as TPStreamsPlayerView } from './TPStreamsPlayer';
|
|
4
4
|
export type { TPStreamsPlayerRef } from './TPStreamsPlayer';
|
|
5
|
-
export { pauseDownload, resumeDownload, removeDownload, isDownloaded, isDownloading, isPaused, getDownloadStatus, getAllDownloads, addDownloadProgressListener, removeDownloadProgressListener, onDownloadProgressChanged, type DownloadItem, type DownloadProgressChange, type DownloadProgressListener, } from './TPStreamsDownload';
|
|
5
|
+
export { pauseDownload, resumeDownload, removeDownload, isDownloaded, isDownloading, isPaused, getDownloadStatus, getAllDownloads, addDownloadProgressListener, removeDownloadProgressListener, onDownloadProgressChanged, onDownloadStateChanged, type DownloadItem, type DownloadProgressChange, type DownloadProgressListener, type DownloadStateChangeListener, } from './TPStreamsDownload';
|
|
6
6
|
export declare const TPStreams: {
|
|
7
7
|
initialize: (organizationId: string) => void;
|
|
8
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AACxF,cAAc,sCAAsC,CAAC;AAGrD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AACxF,cAAc,sCAAsC,CAAC;AAGrD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,SAAS;iCACS,MAAM,KAAG,IAAI;CAG3C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-tpstreams",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3-debug.0",
|
|
4
4
|
"description": "Video component for TPStreams",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -166,5 +166,8 @@
|
|
|
166
166
|
"languages": "kotlin-objc",
|
|
167
167
|
"type": "fabric-view",
|
|
168
168
|
"version": "0.50.3"
|
|
169
|
+
},
|
|
170
|
+
"dependencies": {
|
|
171
|
+
"react-native-toast-message": "^2.3.3"
|
|
169
172
|
}
|
|
170
173
|
}
|
|
@@ -19,25 +19,46 @@ export type DownloadProgressListener = (
|
|
|
19
19
|
downloads: DownloadProgressChange[]
|
|
20
20
|
) => void;
|
|
21
21
|
|
|
22
|
+
export interface DownloadError {
|
|
23
|
+
message: string;
|
|
24
|
+
type: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type DownloadStateChangeListener = (
|
|
28
|
+
downloadItem: DownloadItem,
|
|
29
|
+
error: DownloadError | null
|
|
30
|
+
) => void;
|
|
31
|
+
|
|
22
32
|
const downloadEventEmitter = new NativeEventEmitter(TPStreamsDownload);
|
|
23
33
|
|
|
24
34
|
export function addDownloadProgressListener(): Promise<void> {
|
|
35
|
+
console.log('JS: addDownloadProgressListener');
|
|
25
36
|
return TPStreamsDownload.addDownloadProgressListener();
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
export function removeDownloadProgressListener(): Promise<void> {
|
|
40
|
+
console.log('JS: removeDownloadProgressListener');
|
|
29
41
|
return TPStreamsDownload.removeDownloadProgressListener();
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
export function onDownloadProgressChanged(
|
|
33
45
|
listener: DownloadProgressListener
|
|
34
46
|
): EmitterSubscription {
|
|
47
|
+
console.log('JS: onDownloadProgressChanged');
|
|
35
48
|
return downloadEventEmitter.addListener(
|
|
36
49
|
'onDownloadProgressChanged',
|
|
37
50
|
listener
|
|
38
51
|
);
|
|
39
52
|
}
|
|
40
53
|
|
|
54
|
+
export function onDownloadStateChanged(
|
|
55
|
+
listener: DownloadStateChangeListener
|
|
56
|
+
): EmitterSubscription {
|
|
57
|
+
return downloadEventEmitter.addListener('onDownloadStateChanged', (event) => {
|
|
58
|
+
listener(event.downloadItem, event.error);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
41
62
|
export function pauseDownload(videoId: string): Promise<void> {
|
|
42
63
|
return TPStreamsDownload.pauseDownload(videoId);
|
|
43
64
|
}
|
package/src/index.tsx
CHANGED
|
@@ -19,9 +19,11 @@ export {
|
|
|
19
19
|
addDownloadProgressListener,
|
|
20
20
|
removeDownloadProgressListener,
|
|
21
21
|
onDownloadProgressChanged,
|
|
22
|
+
onDownloadStateChanged,
|
|
22
23
|
type DownloadItem,
|
|
23
24
|
type DownloadProgressChange,
|
|
24
25
|
type DownloadProgressListener,
|
|
26
|
+
type DownloadStateChangeListener,
|
|
25
27
|
} from './TPStreamsDownload';
|
|
26
28
|
|
|
27
29
|
const TPStreamsModule = NativeModules.TPStreams;
|