react-native-tpstreams 0.1.9 → 0.1.11
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/LICENSE +20 -20
- package/README.md +433 -426
- package/Tpstreams.podspec +42 -42
- package/android/build.gradle +122 -122
- package/android/gradle.properties +5 -5
- package/android/libs/extracted-aar/META-INF/com/android/build/gradle/aar-metadata.properties +4 -0
- package/android/src/main/AndroidManifest.xml +4 -4
- package/android/src/main/AndroidManifestNew.xml +2 -2
- package/android/src/main/java/com/tpstreams/FragmentModule.kt +192 -190
- package/android/src/main/java/com/tpstreams/PlayerFragment.kt +226 -210
- package/android/src/main/java/com/tpstreams/TpStreamsPlayerView.kt +93 -79
- package/android/src/main/java/com/tpstreams/TpStreamsPlayerViewManager.kt +49 -40
- package/android/src/main/java/com/tpstreams/TpstreamsModule.kt +168 -161
- package/android/src/main/java/com/tpstreams/TpstreamsPackage.kt +16 -16
- package/android/src/main/res/layout/fragment_player.xml +28 -28
- package/android/src/main/res/xml/network_security_config.xml +7 -7
- package/ios/Tpstreams.h +6 -6
- package/ios/Tpstreams.mm +18 -18
- package/lib/commonjs/NativeTpstreams.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/NativeTpstreams.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/commonjs/src/types.d.ts +2 -0
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
- package/lib/typescript/module/src/types.d.ts +2 -0
- package/lib/typescript/module/src/types.d.ts.map +1 -1
- package/package.json +203 -203
- package/src/types.ts +2 -0
|
@@ -1,190 +1,192 @@
|
|
|
1
|
-
package com.tpstreams
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.os.Bundle
|
|
5
|
-
import androidx.fragment.app.FragmentActivity
|
|
6
|
-
import com.facebook.react.bridge.ReactMethod
|
|
7
|
-
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
8
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
|
-
import android.util.Log
|
|
10
|
-
import androidx.lifecycle.LiveData
|
|
11
|
-
import androidx.lifecycle.ViewModel
|
|
12
|
-
import androidx.lifecycle.ViewModelProvider
|
|
13
|
-
import com.facebook.react.bridge.Arguments
|
|
14
|
-
import com.facebook.react.bridge.WritableMap
|
|
15
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
16
|
-
import com.tpstream.player.data.Asset
|
|
17
|
-
import com.tpstream.player.offline.TpStreamDownloadManager
|
|
18
|
-
import com.tpstream.player.TPStreamsSDK
|
|
19
|
-
|
|
20
|
-
class FragmentModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
21
|
-
|
|
22
|
-
lateinit var viewModel: DownloadListViewModel
|
|
23
|
-
private var assets = listOf<Asset>()
|
|
24
|
-
|
|
25
|
-
override fun initialize() {
|
|
26
|
-
super.initialize()
|
|
27
|
-
(currentActivity as? FragmentActivity)?.let {
|
|
28
|
-
viewModel = DownloadListViewModel.init(it)
|
|
29
|
-
}
|
|
30
|
-
Log.d("FragmentModule", "initialize: ")
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
override fun getName(): String {
|
|
34
|
-
return "FragmentModule"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@ReactMethod
|
|
38
|
-
fun showCustomFragment(videoId: String, accessToken: String, enableDownload: Boolean, autoPlay: Boolean) {
|
|
39
|
-
Log.e("FragmentModule", "showCustomFragment() called")
|
|
40
|
-
// Ensure the currentActivity is a FragmentActivity
|
|
41
|
-
val activity = currentActivity as? FragmentActivity
|
|
42
|
-
activity?.let {
|
|
43
|
-
// Begin the fragment transaction
|
|
44
|
-
val fragmentTransaction = it.supportFragmentManager.beginTransaction()
|
|
45
|
-
|
|
46
|
-
// Create a new fragment instance
|
|
47
|
-
val bundle = Bundle()
|
|
48
|
-
bundle.putString("VIDEO_ID", videoId)
|
|
49
|
-
bundle.putString("ACCESS_TOKEN", accessToken)
|
|
50
|
-
bundle.putBoolean("ENABLE_DOWNLOAD_SUPPORT", enableDownload)
|
|
51
|
-
bundle.putBoolean("AUTO_PLAY", autoPlay)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
fragmentTransaction.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
assetMap.
|
|
112
|
-
assetMap.putString("
|
|
113
|
-
assetMap.putString("
|
|
114
|
-
assetMap.putString("
|
|
115
|
-
assetMap.putString("
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
1
|
+
package com.tpstreams
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import androidx.fragment.app.FragmentActivity
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod
|
|
7
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
|
+
import android.util.Log
|
|
10
|
+
import androidx.lifecycle.LiveData
|
|
11
|
+
import androidx.lifecycle.ViewModel
|
|
12
|
+
import androidx.lifecycle.ViewModelProvider
|
|
13
|
+
import com.facebook.react.bridge.Arguments
|
|
14
|
+
import com.facebook.react.bridge.WritableMap
|
|
15
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
16
|
+
import com.tpstream.player.data.Asset
|
|
17
|
+
import com.tpstream.player.offline.TpStreamDownloadManager
|
|
18
|
+
import com.tpstream.player.TPStreamsSDK
|
|
19
|
+
|
|
20
|
+
class FragmentModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
21
|
+
|
|
22
|
+
lateinit var viewModel: DownloadListViewModel
|
|
23
|
+
private var assets = listOf<Asset>()
|
|
24
|
+
|
|
25
|
+
override fun initialize() {
|
|
26
|
+
super.initialize()
|
|
27
|
+
(currentActivity as? FragmentActivity)?.let {
|
|
28
|
+
viewModel = DownloadListViewModel.init(it)
|
|
29
|
+
}
|
|
30
|
+
Log.d("FragmentModule", "initialize: ")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun getName(): String {
|
|
34
|
+
return "FragmentModule"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@ReactMethod
|
|
38
|
+
fun showCustomFragment(videoId: String, accessToken: String, enableDownload: Boolean, autoPlay: Boolean, startAt: Int, offlineLicenseExpireTime: Int) {
|
|
39
|
+
Log.e("FragmentModule", "showCustomFragment() called")
|
|
40
|
+
// Ensure the currentActivity is a FragmentActivity
|
|
41
|
+
val activity = currentActivity as? FragmentActivity
|
|
42
|
+
activity?.let {
|
|
43
|
+
// Begin the fragment transaction
|
|
44
|
+
val fragmentTransaction = it.supportFragmentManager.beginTransaction()
|
|
45
|
+
|
|
46
|
+
// Create a new fragment instance
|
|
47
|
+
val bundle = Bundle()
|
|
48
|
+
bundle.putString("VIDEO_ID", videoId)
|
|
49
|
+
bundle.putString("ACCESS_TOKEN", accessToken)
|
|
50
|
+
bundle.putBoolean("ENABLE_DOWNLOAD_SUPPORT", enableDownload)
|
|
51
|
+
bundle.putBoolean("AUTO_PLAY", autoPlay)
|
|
52
|
+
bundle.putInt("START_AT", startAt)
|
|
53
|
+
bundle.putInt("OFFLINE_LICENSE_EXPIRE_TIME", offlineLicenseExpireTime)
|
|
54
|
+
val fragment = PlayerFragment()
|
|
55
|
+
fragment.setArguments(bundle)
|
|
56
|
+
|
|
57
|
+
// Find a container to add the fragment
|
|
58
|
+
val fragmentContainerId = android.R.id.content // or you could specify your own container ID
|
|
59
|
+
|
|
60
|
+
// Add the fragment
|
|
61
|
+
fragmentTransaction.replace(fragmentContainerId, fragment)
|
|
62
|
+
fragmentTransaction.addToBackStack(null) // Optional: Add fragment to back stack
|
|
63
|
+
fragmentTransaction.commit()
|
|
64
|
+
} ?: run {
|
|
65
|
+
// Handle the error if the activity is not a FragmentActivity
|
|
66
|
+
Log.e("ReactNativeJS", "Current activity is not a FragmentActivity")
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@ReactMethod
|
|
71
|
+
fun closeCustomFragment() {
|
|
72
|
+
Log.e("FragmentModule", "closeCustomFragment() called")
|
|
73
|
+
|
|
74
|
+
// Ensure currentActivity is a FragmentActivity
|
|
75
|
+
val activity = currentActivity as? FragmentActivity
|
|
76
|
+
if (activity == null || activity.isFinishing || activity.isDestroyed) {
|
|
77
|
+
Log.e("FragmentModule", "Activity is null, finishing, or destroyed")
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
val fragmentManager = activity.supportFragmentManager
|
|
82
|
+
val playerFragment = fragmentManager.findFragmentByTag("PLAYER_FRAGMENT") as? PlayerFragment
|
|
83
|
+
|
|
84
|
+
if (playerFragment != null) {
|
|
85
|
+
Log.d("FragmentModule", "Removing PlayerFragment")
|
|
86
|
+
fragmentManager.beginTransaction()
|
|
87
|
+
.remove(playerFragment)
|
|
88
|
+
.commitAllowingStateLoss() // Avoid IllegalStateException
|
|
89
|
+
} else if (fragmentManager.backStackEntryCount > 0) {
|
|
90
|
+
Log.d("FragmentModule", "Popping back stack")
|
|
91
|
+
fragmentManager.popBackStack()
|
|
92
|
+
} else {
|
|
93
|
+
Log.e("FragmentModule", "No fragments to remove")
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@ReactMethod
|
|
98
|
+
fun observeDownloadData() {
|
|
99
|
+
// Ensure this code runs on the main thread
|
|
100
|
+
currentActivity?.runOnUiThread {
|
|
101
|
+
val activity = currentActivity as? FragmentActivity
|
|
102
|
+
activity?.let {
|
|
103
|
+
// Observe LiveData only on the main thread
|
|
104
|
+
viewModel.getDownloadData().observe(it) { assets ->
|
|
105
|
+
this.assets = assets ?: emptyList()
|
|
106
|
+
// Emit event to React Native
|
|
107
|
+
val eventMap = Arguments.createMap()
|
|
108
|
+
val assetsList = Arguments.createArray()
|
|
109
|
+
|
|
110
|
+
assets?.forEachIndexed { index , asset ->
|
|
111
|
+
val assetMap = Arguments.createMap()
|
|
112
|
+
assetMap.putString("id", index.toString())
|
|
113
|
+
assetMap.putString("videoId", asset.id)
|
|
114
|
+
assetMap.putString("title", asset.title)
|
|
115
|
+
assetMap.putString("percentage", asset.video.percentageDownloaded.toString())
|
|
116
|
+
assetMap.putString("status", asset.video.downloadState?.name ?: "Unknown")
|
|
117
|
+
assetMap.putString("duration", asset.video.duration.toString())
|
|
118
|
+
|
|
119
|
+
assetsList.pushMap(assetMap)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
eventMap.putArray("assets", assetsList)
|
|
123
|
+
reactApplicationContext
|
|
124
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
125
|
+
.emit("onDownloadDataChanged", eventMap)
|
|
126
|
+
}
|
|
127
|
+
} ?: run {
|
|
128
|
+
Log.e("FragmentModule", "Current activity is not a FragmentActivity")
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@ReactMethod
|
|
134
|
+
fun pauseDownload(videoId: String) {
|
|
135
|
+
val asset = assets.first { it.id == videoId }
|
|
136
|
+
viewModel.pauseDownload(asset)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@ReactMethod
|
|
140
|
+
fun resumeDownload(videoId: String) {
|
|
141
|
+
val asset = assets.first { it.id == videoId }
|
|
142
|
+
viewModel.resumeDownload(asset)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@ReactMethod
|
|
146
|
+
fun cancelDownload(videoId: String) {
|
|
147
|
+
val asset = assets.first { it.id == videoId }
|
|
148
|
+
viewModel.cancelDownload(asset)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@ReactMethod
|
|
152
|
+
fun deleteDownload(videoId: String) {
|
|
153
|
+
val asset = assets.first { it.id == videoId }
|
|
154
|
+
viewModel.deleteDownload(asset)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
class DownloadListViewModel(context: Context): ViewModel() {
|
|
160
|
+
|
|
161
|
+
private var tpStreamDownloadManager: TpStreamDownloadManager = TpStreamDownloadManager(context)
|
|
162
|
+
|
|
163
|
+
fun getDownloadData(): LiveData<List<Asset>?> {
|
|
164
|
+
return tpStreamDownloadManager.getAllDownloads()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
fun pauseDownload(offlineAssetInfo: Asset) {
|
|
168
|
+
tpStreamDownloadManager.pauseDownload(offlineAssetInfo)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
fun resumeDownload(offlineAssetInfo: Asset) {
|
|
172
|
+
tpStreamDownloadManager.resumeDownload(offlineAssetInfo)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
fun cancelDownload(offlineAssetInfo: Asset) {
|
|
176
|
+
tpStreamDownloadManager.cancelDownload(offlineAssetInfo)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fun deleteDownload(offlineAssetInfo: Asset) {
|
|
180
|
+
tpStreamDownloadManager.deleteDownload(offlineAssetInfo)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
companion object {
|
|
184
|
+
fun init(fragmentActivity: FragmentActivity) : DownloadListViewModel {
|
|
185
|
+
return ViewModelProvider(fragmentActivity, object : ViewModelProvider.Factory {
|
|
186
|
+
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
|
187
|
+
return DownloadListViewModel(fragmentActivity) as T
|
|
188
|
+
}
|
|
189
|
+
})[DownloadListViewModel::class.java]
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|