@takeoffmedia/react-native-penthera 0.2.67 → 0.3.1

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 (28) hide show
  1. package/android/src/main/java/com/takeoffmediareactnativepenthera/AssetQueueObserver.kt +117 -94
  2. package/android/src/main/java/com/takeoffmediareactnativepenthera/EventEmitter.kt +23 -12
  3. package/android/src/main/java/com/takeoffmediareactnativepenthera/PentheraModule.kt +55 -39
  4. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/DemoLicenseManager.kt +0 -14
  5. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/OfflineVideoEngine.kt +235 -177
  6. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/data/Item.kt +0 -18
  7. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/NotificationFactory.kt +11 -8
  8. package/android/src/main/res/values/colors.xml +1 -0
  9. package/lib/commonjs/hooks/usePenthera/usePentheraInit.js +69 -0
  10. package/lib/commonjs/hooks/usePenthera/usePentheraInit.js.map +1 -1
  11. package/lib/commonjs/nativeModules/index.js +8 -0
  12. package/lib/commonjs/nativeModules/index.js.map +1 -1
  13. package/lib/module/hooks/usePenthera/usePentheraInit.js +68 -0
  14. package/lib/module/hooks/usePenthera/usePentheraInit.js.map +1 -1
  15. package/lib/module/nativeModules/index.js +6 -0
  16. package/lib/module/nativeModules/index.js.map +1 -1
  17. package/lib/typescript/hooks/usePenthera/usePentheraInit.d.ts +5 -0
  18. package/lib/typescript/hooks/usePenthera/usePentheraInit.d.ts.map +1 -1
  19. package/lib/typescript/nativeModules/index.d.ts +2 -0
  20. package/lib/typescript/nativeModules/index.d.ts.map +1 -1
  21. package/package.json +1 -1
  22. package/src/hooks/usePenthera/usePentheraInit.tsx +70 -0
  23. package/src/nativeModules/index.ts +8 -0
  24. package/ios/Penthera.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  25. package/ios/Penthera.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  26. package/ios/Penthera.xcodeproj/project.xcworkspace/xcuserdata/joseguerreroot.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  27. package/ios/Penthera.xcodeproj/xcuserdata/joseguerreroot.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -104
  28. package/ios/Penthera.xcodeproj/xcuserdata/joseguerreroot.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
@@ -1,118 +1,110 @@
1
1
  package com.takeoffmediareactnativepenthera.virtuoso
2
2
 
3
3
  import android.annotation.SuppressLint
4
- import android.app.Activity
5
4
  import android.content.Context
6
5
  import android.util.Log
7
- import com.bitmovin.player.api.media.subtitle.SubtitleTrack
8
6
  import com.bitmovin.player.reactnative.PlayerModule
9
7
  import com.bitmovin.player.reactnative.converter.JsonConverter
10
-
8
+ import com.facebook.react.bridge.Arguments
9
+ import com.facebook.react.bridge.Promise
11
10
  import com.facebook.react.bridge.ReactApplicationContext
11
+ import com.facebook.react.bridge.ReadableArray
12
+ import com.facebook.react.bridge.UiThreadUtil
12
13
  import com.google.gson.Gson
13
- import com.penthera.common.Common.AuthenticationStatus
14
+ import com.penthera.virtuososdk.client.AncillaryFile
14
15
  import com.penthera.virtuososdk.client.EngineObserver
15
16
  import com.penthera.virtuososdk.client.IAsset
16
17
  import com.penthera.virtuososdk.client.IIdentifier
17
18
  import com.penthera.virtuososdk.client.IPushRegistrationObserver
18
19
  import com.penthera.virtuososdk.client.ISegmentedAsset
19
20
  import com.penthera.virtuososdk.client.ISegmentedAssetFromParserObserver
20
- import com.penthera.virtuososdk.client.Observers
21
21
  import com.penthera.virtuososdk.client.Virtuoso
22
22
  import com.penthera.virtuososdk.client.bitmovin.BitmovinSourceManager
23
23
  import com.penthera.virtuososdk.client.builders.MPDAssetBuilder
24
24
  import com.penthera.virtuososdk.interfaces.toolkit.VirtuosoSegmentedFile
25
25
  import com.takeoffmediareactnativepenthera.AssetQueueObserver
26
- import java.net.URL
27
- import com.facebook.react.bridge.Arguments
28
- import com.facebook.react.uimanager.UIManagerModule
29
- import com.facebook.react.bridge.Promise
30
- import com.facebook.react.bridge.ReadableArray
31
- import com.penthera.virtuososdk.client.AncillaryFile
32
26
  import okhttp3.OkHttpClient
33
27
  import okhttp3.Request
34
28
  import org.json.JSONArray
35
29
  import org.json.JSONObject
36
30
  import java.io.IOException
37
- import java.net.HttpURLConnection
31
+ import java.net.MalformedURLException
32
+ import java.net.URL
38
33
  import java.text.SimpleDateFormat
39
34
  import java.util.Calendar
35
+ import com.penthera.common.Common
36
+ import com.penthera.virtuososdk.client.IService
37
+ import com.takeoffmediareactnativepenthera.EventEmitter
38
+ import com.takeoffmediareactnativepenthera.PentheraEvent
39
+ import com.takeoffmediareactnativepenthera.virtuoso.errors.PentheraErrors
40
40
 
41
41
  class OfflineVideoEngine(private val context: ReactApplicationContext) {
42
- lateinit var virtuoso : Virtuoso
43
- private lateinit var queueObserver: AssetQueueObserver
42
+ private val virtuoso = Virtuoso(context)
43
+ private var queueObserver = AssetQueueObserver(this, virtuoso)
44
44
  var asset: IAsset? = null
45
- var assetId: MutableList<String> = mutableListOf()
45
+ val assetId: MutableList<String> = mutableListOf()
46
46
  private val gson = Gson()
47
- var minimumLowBandWidth: Double = 0.00010
48
- var valueUserId: String = ""
49
- var valueBackPlaneUrl: String = ""
50
- var valuePublicKey: String = ""
51
- var valuePrivateKey: String = ""
52
47
  private val client = OkHttpClient()
53
-
54
- private val enginePauseObserver: Observers.IEngineObserver = object : EngineObserver() {
48
+ var minimumLowBandWidth: Double = 0.5 // 500kbps
49
+ val mService: IService = virtuoso.service
50
+ private val enginePauseObserver = object: EngineObserver() {
55
51
  override fun engineStatusChanged(status: Int) {
56
52
  Log.e("MiModulo", "<<<<<<<<<<status $status>>>>>>>>>>>>")
57
53
  }
58
54
  }
59
55
 
60
- private fun getInstanceVirtuoso(): Virtuoso {
61
- virtuoso = Virtuoso(context)
62
- queueObserver = AssetQueueObserver(this, virtuoso)
63
- onResume()
64
- return virtuoso
65
- }
66
-
67
56
  fun onResume() {
68
- virtuoso.onResume()
69
- virtuoso.addObserver(queueObserver)
70
- virtuoso.addObserver(enginePauseObserver)
57
+ virtuoso.let {
58
+ it.onResume()
59
+ it.addObserver(queueObserver)
60
+ it.addObserver(enginePauseObserver)
61
+ mService.bind()
62
+ }
71
63
  }
72
64
 
73
65
  fun onPause() {
74
- virtuoso.onPause()
75
- virtuoso.removeObserver(queueObserver)
76
- virtuoso.removeObserver(enginePauseObserver)
66
+ virtuoso.let {
67
+ it.onPause()
68
+ it.removeObserver(queueObserver)
69
+ it.removeObserver(enginePauseObserver)
70
+ mService.unbind()
71
+ }
77
72
  }
78
73
 
79
74
  fun setup(
80
- userId: String = valueUserId,
81
- backplaneUrl: String = valueBackPlaneUrl,
82
- publicKey: String = valuePublicKey,
83
- privateKey: String = valuePrivateKey,
84
- promise: Promise? = null
85
- ) {
86
- val vir = getInstanceVirtuoso()
87
- valueUserId = userId
88
- valueBackPlaneUrl = backplaneUrl
89
- valuePrivateKey = privateKey
90
- valuePublicKey = publicKey
91
-
92
- val nameDevice = android.os.Build.MODEL
93
-
94
- vir.startup(
95
- URL(valueBackPlaneUrl),
96
- valueUserId,
97
- nameDevice,
98
- valuePublicKey,
99
- valuePrivateKey,
100
- object : IPushRegistrationObserver {
101
- override fun onServiceAvailabilityResponse(
102
- pushService: Int,
103
- errorCode: Int
104
- ) {
105
- //callback for push registration. this will be detailed in subsequent tutorials
106
- }
75
+ userId: String,
76
+ backplaneUrl: String,
77
+ publicKey: String,
78
+ privateKey: String,
79
+ promise: Promise
80
+ ) {
81
+ try {
82
+ onResume()
83
+ virtuoso.settings.batteryThreshold = 0f
84
+ virtuoso.startup(
85
+ URL(backplaneUrl),
86
+ userId,
87
+ android.os.Build.MODEL,
88
+ publicKey,
89
+ privateKey,
90
+ object : IPushRegistrationObserver {
91
+ override fun onServiceAvailabilityResponse(
92
+ pushService: Int,
93
+ errorCode: Int
94
+ ) {
95
+ //callback for push registration. this will be detailed in subsequent tutorials
107
96
  }
108
- ).let {
109
- promise?.resolve("Penthera initialization successfully")
110
97
  }
111
-
98
+ ).let {
99
+ promise.resolve("Penthera initialization successfully")
100
+ }
101
+ } catch (e: MalformedURLException) {
102
+ // Handle the exception here, for example, reject the promise
103
+ promise.reject(e)
104
+ }
112
105
  }
113
106
 
114
107
  fun downloadAsset(newItem: String) {
115
- setup()
116
108
  val data = JSONObject(newItem)
117
109
  val item = data["item"] as JSONObject
118
110
  assetId.add(item["id"].toString())
@@ -169,80 +161,100 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
169
161
  virtuoso.assetManager.createMPDSegmentedAssetAsync(params)
170
162
  }
171
163
 
172
- fun getDownloads(): String? {
164
+ fun getDownloads(promise: Promise) {
173
165
  val completedList = mutableListOf<MutableMap<String, Any>>()
174
- val cursor = virtuoso.assetManager?.cursor
175
- val count = cursor?.count
176
- if( count == 0){
166
+ val cursor = virtuoso.assetManager.cursor
167
+ val count = cursor.count
168
+ if (count == 0) {
177
169
  cursor.close()
178
- return gson.toJson(completedList)
170
+ return promise.resolve(gson.toJson(completedList))
179
171
  }
180
- val columnNames = cursor?.columnNames
181
- while (cursor?.moveToNext() == true && columnNames != null) {
182
- val dataMap = mutableMapOf<String, Any>()
183
- var eap = ""
184
- var ead = ""
185
- for (columnName in columnNames) {
186
- val columnIndex = cursor.getColumnIndex(columnName)
187
- if (columnIndex >= 0) {
188
- val value = cursor.getString(columnIndex)
189
- if (columnName == "description") {
190
- val jsonObject = Gson().fromJson(value, Map::class.java)
191
- dataMap["data"] = jsonObject["data"] as Any
192
- dataMap["title"] = jsonObject["title"] as Any
193
- dataMap["thumbnails"] = jsonObject["thumbnails"] as Any
194
- }
195
- else if (value != null) {
196
- dataMap[columnName] = value
197
- }
198
- if (columnName == "assetId") {
199
- dataMap["id"] = value
200
- }
201
- if (columnName == "durationSeconds") {
202
- dataMap["data"] = (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
203
- put("duration", value)
204
- }
205
- }
206
- if (columnName == "expectedSize") {
207
- dataMap["data"] = (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
208
- put("estimatedSize", value)
209
- }
210
- }
211
- if (columnName == "ead") {
212
- ead = value
213
- }
214
- if (columnName == "eap") {
215
- eap = value
216
- }
217
- if(columnName == "activePercentOfDownloads"){
218
- val percentage = value.toDouble() * 100
219
- val isComplete = percentage == 100.0
220
- dataMap["isCompleted"] = isComplete
221
- }
222
- if (columnName == "firstPlayTime") {
223
- var eadFormated = dateToString(ead)
224
- var eapFormated = dateToString(eap)
225
- dataMap["data"] = (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
226
- put("effectiveExpiryDate", if (value == "0") eadFormated else eapFormated)
172
+ val columnNames = cursor.columnNames
173
+ while (cursor.moveToNext() && columnNames != null) {
174
+ val dataMap = mutableMapOf<String, Any>()
175
+ var eap = ""
176
+ var ead = ""
177
+ for (columnName in columnNames) {
178
+ val columnIndex = cursor.getColumnIndex(columnName)
179
+ if (columnIndex >= 0) {
180
+ val value = cursor.getString(columnIndex)
181
+ if (columnName == "description") {
182
+ val jsonObject = Gson().fromJson(value, Map::class.java)
183
+ dataMap["data"] = jsonObject["data"] as Any
184
+ dataMap["title"] = jsonObject["title"] as Any
185
+ dataMap["thumbnails"] = jsonObject["thumbnails"] as Any
186
+ } else if (value != null) {
187
+ dataMap[columnName] = value
188
+ }
189
+ if (columnName == "assetId") {
190
+ dataMap["id"] = value
191
+ UiThreadUtil.runOnUiThread {
192
+ val list = virtuoso.assetManager.getByAssetId(value)
193
+ list.let {
194
+ if (it.isNotEmpty()) {
195
+ asset = list[0] as VirtuosoSegmentedFile
196
+ if (asset?.downloadStatus == Common.AssetStatus.DOWNLOAD_DENIED_COPIES) {
197
+ EventEmitter.sharedInstance.dispatch(
198
+ "penthera",
199
+ PentheraEvent.ERROR_DOWNLOAD,
200
+ value,
201
+ PentheraErrors.DOWNLOAD_DENIED_COPIES
202
+ )
203
+ }
204
+ }
227
205
  }
228
206
  }
229
207
  }
208
+ if (columnName == "durationSeconds") {
209
+ (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
210
+ put("duration", value)
211
+ }.also { dataMap["data"] = it }
212
+ }
213
+ if (columnName == "expectedSize") {
214
+ (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
215
+ put("estimatedSize", value)
216
+ }.also { dataMap["data"] = it }
217
+ }
218
+ if (columnName == "ead") {
219
+ ead = value
220
+ }
221
+ if (columnName == "eap") {
222
+ eap = value
223
+ }
224
+ if (columnName == "activePercentOfDownloads") {
225
+ val percentage = value.toDouble() * 100
226
+ val isComplete = percentage == 100.0
227
+ dataMap["isCompleted"] = isComplete
228
+ }
229
+ if (columnName == "firstPlayTime") {
230
+ val eadFormated = dateToString(ead)
231
+ val eapFormated = dateToString(eap)
232
+ (dataMap["data"] as? MutableMap<String, Any> ?: mutableMapOf()).apply {
233
+ put("effectiveExpiryDate", if (value == "0") eadFormated else eapFormated)
234
+ }.also { dataMap["data"] = it }
235
+ }
230
236
  }
231
- dataMap["isPaused"] = false
232
- completedList.add(dataMap)
233
237
  }
234
- cursor?.close()
238
+ dataMap["isPaused"] = false
239
+ completedList.add(dataMap)
240
+ }
241
+ cursor.close()
235
242
 
236
- return gson.toJson(completedList)
243
+ promise.resolve(gson.toJson(completedList))
237
244
  }
238
245
 
239
246
  private fun dateToString(seconds: String): String {
240
- val secondsLong = seconds.toLong()
241
- val calendar = Calendar.getInstance()
242
- calendar.add(Calendar.SECOND, secondsLong.toInt())
243
-
244
247
  val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
245
- return dateFormat.format(calendar.time)
248
+ return try {
249
+ val secondsLong = seconds.toLong()
250
+ Calendar.getInstance().let {
251
+ it.add(Calendar.SECOND, secondsLong.toInt())
252
+ dateFormat.format(it.time)
253
+ }
254
+ } catch (e: NumberFormatException) {
255
+ // Handle the exception here, for example, return an empty string or throw the exception
256
+ ""
257
+ }
246
258
  }
247
259
 
248
260
  class AssetParseObserver(activity: Context) : ISegmentedAssetFromParserObserver {
@@ -250,24 +262,12 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
250
262
 
251
263
  @SuppressLint("ShowToast")
252
264
  override fun complete(asset: ISegmentedAsset?, error: Int, addedToQueue: Boolean) {
253
- // Show a process when the asset to parsed and added to queue
254
- // if (asset != null) {
255
- // Toast.makeText(
256
- // mActivity,
257
- // "Asset parsed and " + if (addedToQueue) "added" else "not added" + "to download queue",
258
- // Toast.LENGTH_LONG
259
- // ).show()
260
- // } else {
261
- // Toast.makeText(mActivity, "Error $error while parsing asset", Toast.LENGTH_LONG).show()
262
- // }
263
265
  }
264
266
  }
265
267
 
266
-
267
268
  fun deleteMany(assetIds: ReadableArray, promise: Promise) {
268
269
  val assetManager = virtuoso.assetManager
269
270
  val result = Arguments.createMap()
270
-
271
271
  for (i in 0 until assetIds.size()) {
272
272
  val idValue = assetIds.getString(i)
273
273
  val asset = assetManager.getByAssetId(idValue)
@@ -281,20 +281,19 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
281
281
  assetId.remove(idValue)
282
282
  }
283
283
  }
284
-
285
- promise.resolve(result);
284
+ promise.resolve(result)
286
285
  }
287
286
 
288
287
 
289
- fun getByAssetId(assetId: String): String? {
290
- //load asset if it has already been downloaded
291
- val list: MutableList<IIdentifier>? = getInstanceVirtuoso().assetManager.getByAssetId(assetId)
288
+ fun getByAssetId(assetId: String): String? {
289
+ // load asset if it has already been downloaded
290
+ val list: MutableList<IIdentifier> = virtuoso.assetManager.getByAssetId(assetId)
292
291
 
293
- list?.let {
292
+ list.let {
294
293
  if (it.isNotEmpty()) {
295
294
  asset = list[0] as VirtuosoSegmentedFile
296
295
 
297
- // This a workaound to works ancillary files
296
+ // This a workaround to works ancillary files
298
297
  val offlineUrl = asset?.playbackURL
299
298
  val request = Request.Builder()
300
299
  .url(offlineUrl.toString())
@@ -307,62 +306,121 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
307
306
  keyValueMap["offlineUrl"] = offlineUrl.toString()
308
307
  keyValueMap["metadata"] = asset?.metadata.toString()
309
308
 
310
- val ancillaryFiles = (asset as ISegmentedAsset).getAncillaryFiles(context)
309
+ val ancillaryFiles = (asset as ISegmentedAsset).getAncillaryFiles(context)
311
310
 
312
- //HERE THE ASSET MANIFEST IS REQUESTED
311
+ // HERE THE ASSET MANIFEST IS REQUESTED
313
312
  keyValueMap["ancillary"] = ancillaryFiles
314
313
  return gson.toJson(keyValueMap)
315
314
  }
316
315
  }
317
316
  return null
318
317
  }
319
- fun updateUI() {}
320
318
 
321
- fun loadBitmovinSourceManager(assetId: String, nativeId: String, startOffset: Double?, ancillaries: String , promise: Promise) {
322
- getInstanceVirtuoso().assetManager?.getByAssetId(assetId)?.firstOrNull()?.let { asset ->
319
+ fun loadBitmovinSourceManager(
320
+ assetId: String,
321
+ nativeId: String,
322
+ startOffset: Double?,
323
+ ancillaries: String,
324
+ promise: Promise
325
+ ) {
326
+ virtuoso.assetManager.getByAssetId(assetId)?.firstOrNull()?.let { asset ->
323
327
  val sourceManager = BitmovinSourceManager(context, asset as ISegmentedAsset)
324
328
  val sourceItem = sourceManager.bitmovinSourceItem
325
329
  val playerModule = context.getNativeModule(PlayerModule::class.java)
326
330
  if (playerModule != null && sourceItem != null) {
327
331
  var player = playerModule.getPlayer(nativeId)
328
- while(player == null) {
332
+ while (player == null) {
329
333
  Thread.sleep(100)
330
334
  player = playerModule.getPlayer(nativeId) as Nothing?
331
335
  }
332
- if (player != null) {
333
- val metadata = JSONObject(asset.metadata)
334
- val subtitles = JSONArray(metadata["subtitles"] as String)
335
- val ancillaryFiles = JSONArray(ancillaries)
336
- for (i in 0 until subtitles.length()) {
337
- val subtitleMap = Arguments.createMap()
338
- val subtitle = subtitles.getJSONObject(i)
339
-
340
- for (j in 0 until ancillaryFiles.length()) {
341
- val ancillary = ancillaryFiles.getJSONObject(j)
342
- if(ancillary.getString("description") == subtitle.getString("language")) {
343
- subtitleMap.putString("url", ancillary.getString("playbackUrl").toString())
344
- }
336
+ val metadata = JSONObject(asset.metadata)
337
+ val subtitles = JSONArray(metadata["subtitles"] as String)
338
+ val ancillaryFiles = JSONArray(ancillaries)
339
+ for (i in 0 until subtitles.length()) {
340
+ val subtitleMap = Arguments.createMap()
341
+ val subtitle = subtitles.getJSONObject(i)
342
+
343
+ for (j in 0 until ancillaryFiles.length()) {
344
+ val ancillary = ancillaryFiles.getJSONObject(j)
345
+ if (ancillary.getString("description") == subtitle.getString("language")) {
346
+ subtitleMap.putString("url", ancillary.getString("playbackUrl").toString())
345
347
  }
346
- subtitleMap.putString("language",subtitle.getString("language"))
347
- subtitleMap.putString("label",subtitle.getString("label"))
348
- subtitleMap.putString("format","vtt")
348
+ }
349
+ subtitleMap.putString("language", subtitle.getString("language"))
350
+ subtitleMap.putString("label", subtitle.getString("label"))
351
+ subtitleMap.putString("format", "vtt")
349
352
 
350
- JsonConverter.toSubtitleTrack(subtitleMap)?.let {
351
- sourceItem.addSubtitleTrack(it)
352
- }
353
+ JsonConverter.toSubtitleTrack(subtitleMap)?.let {
354
+ sourceItem.addSubtitleTrack(it)
355
+ }
356
+ }
357
+ if (startOffset != null) {
358
+ sourceItem.options.startOffset = startOffset
359
+ }
360
+ val metaDataMap = mutableMapOf<String, String>()
361
+
362
+ val data = metadata.getJSONObject("data")
363
+ val infoVideoPlayer = data.getJSONObject("infoVideoPlayer")
364
+
365
+ infoVideoPlayer.optString("title").let { title ->
366
+ if (title.isNotBlank()) {
367
+ sourceItem.title = title
368
+ }
369
+ }
370
+
371
+ infoVideoPlayer.optString("description").let { description ->
372
+ if (description.isNotBlank()) {
373
+ metaDataMap["description"] = description
353
374
  }
354
- if(startOffset != null) {
355
- sourceItem.options.startOffset = startOffset
375
+ }
376
+
377
+ infoVideoPlayer.optString("advisoryClassification").let { advisoryClassification ->
378
+ if (advisoryClassification.isNotBlank()) {
379
+ metaDataMap["advisoryClassification"] = advisoryClassification
356
380
  }
357
- player.load(sourceItem)
358
- promise.resolve(true)
359
381
  }
382
+
383
+ infoVideoPlayer.optString("advisoryDescription").let { advisoryDescription ->
384
+ if (advisoryDescription.isNotBlank()) {
385
+ metaDataMap["advisoryDescription"] = advisoryDescription
386
+ }
387
+ }
388
+
389
+ sourceItem.metadata = metaDataMap
390
+ player.load(sourceItem)
391
+ promise.resolve(true)
360
392
  }
361
393
  }
362
394
  promise.reject("Error", "Error loading asset")
363
395
  }
364
396
 
365
- private fun uiManager(): UIManagerModule? =
366
- context.getNativeModule(UIManagerModule::class.java)
397
+ fun getAuthenticationStatus(promise: Promise) {
398
+ promise.resolve(virtuoso.backplane.authenticationStatus)
399
+ }
400
+
401
+ fun configParameters(params: String, promise: Promise){
402
+ try {
403
+ val data = JSONObject(params)
367
404
 
405
+ if (data.has("minimumLowBandWidth"))
406
+ data.getDouble("minimumLowBandWidth").let {
407
+ minimumLowBandWidth = it / 1000
408
+ }
409
+
410
+
411
+ if (data.has("maxStorageAllowed"))
412
+ data.getLong("maxStorageAllowed").let {
413
+ virtuoso.settings.maxStorageAllowed = it
414
+ }
415
+
416
+ if (data.has("headroom"))
417
+ data.getLong("headroom").let {
418
+ virtuoso.settings.headroom = it
419
+ }
420
+
421
+ promise.resolve("Penthera configuration successfully")
422
+ } catch (e: Exception) {
423
+ promise.reject(e)
424
+ }
425
+ }
368
426
  }
@@ -6,27 +6,9 @@ data class Item(
6
6
 
7
7
  var id: String,
8
8
 
9
- @SerializedName("asset_id")
10
- val assetId: String = "",
11
-
12
9
  @SerializedName("title")
13
10
  val title: String = "",
14
11
 
15
- @SerializedName("content_url")
16
- val contentUrl: String = "",
17
-
18
- @SerializedName("poster")
19
- val poster: String = "",
20
-
21
- @SerializedName("thumbnail")
22
- val thumbnail: String = "",
23
-
24
- @SerializedName("en_subtitle")
25
- val subtitle: String? = "",
26
-
27
- @SerializedName("drm")
28
- var drm: String? = null,
29
-
30
12
  )
31
13
 
32
14
 
@@ -11,10 +11,12 @@ import android.content.pm.PackageManager
11
11
  import android.os.Build
12
12
  import android.util.Log
13
13
  import androidx.core.app.NotificationCompat
14
+ import androidx.core.content.ContextCompat
14
15
  import com.google.gson.Gson
15
16
  import com.penthera.virtuososdk.Common
16
17
  import com.penthera.virtuososdk.client.IAsset
17
18
  import com.penthera.virtuososdk.client.IEvent
19
+ import com.penthera.virtuososdk.utility.CommonUtil.getApplicationContext
18
20
  import com.takeoffmediareactnativepenthera.PentheraModule
19
21
  import com.takeoffmediareactnativepenthera.R
20
22
  import com.takeoffmediareactnativepenthera.virtuoso.data.Item
@@ -22,9 +24,9 @@ import com.takeoffmediareactnativepenthera.virtuoso.data.Item
22
24
  class NotificationFactory(private val applicationName: String) {
23
25
 
24
26
  companion object {
25
- fun channelId() = "Penthera example"
26
- fun channelName() = "Penthera example channel"
27
- fun channelDescription() = "Penthera example description"
27
+ fun channelId() = "Britbox"
28
+ fun channelName() = "Britbox"
29
+ fun channelDescription() = "Downloads"
28
30
 
29
31
  private val TAG = NotificationFactory::class.java.simpleName
30
32
  private var notificationChannel : NotificationChannel? = null
@@ -108,7 +110,7 @@ class NotificationFactory(private val applicationName: String) {
108
110
 
109
111
  Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_COMPLETE -> {
110
112
  if (file != null) {
111
- Log.d(TAG, "DOWNLOAD COMPLETE NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
113
+ Log.d(TAG, "DOWNLOAD COMPLETE NOTIFICATION FOR " + file.uuid + " stat: " + if (hasInfo) info else "unknown")
112
114
  } else {
113
115
  Log.d(TAG, "DOWNLOAD COMPLETE NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
114
116
  }
@@ -116,7 +118,7 @@ class NotificationFactory(private val applicationName: String) {
116
118
  }
117
119
  Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_START ->{
118
120
  if(file != null) {
119
- Log.d(TAG, "DOWNLOAD START NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
121
+ Log.d(TAG, "DOWNLOAD START NOTIFICATION FOR " + file.uuid + " stat: " + if (hasInfo) info else "unknown")
120
122
  } else {
121
123
  Log.d(TAG, "DOWNLOAD START NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
122
124
  }
@@ -143,7 +145,7 @@ class NotificationFactory(private val applicationName: String) {
143
145
 
144
146
  Common.Notifications.INTENT_NOTIFICATION_DOWNLOAD_UPDATE -> {
145
147
  if (file != null) {
146
- Log.d(TAG, "DOWNLOAD UPDATE NOTIFICATION FOR " + file?.uuid + " stat: " + if (hasInfo) info else "unknown")
148
+ Log.d(TAG, "DOWNLOAD UPDATE NOTIFICATION FOR " + file.uuid + " stat: " + if (hasInfo) info else "unknown")
147
149
  } else {
148
150
  Log.d(TAG, "DOWNLOAD UPDATE NOTIFICATION FOR UNKNOWN" + " stat: " + if (hasInfo) info else "unknown")
149
151
  }
@@ -178,7 +180,7 @@ class NotificationFactory(private val applicationName: String) {
178
180
  * @param asset the asset (may be null)
179
181
  * @return the notification.
180
182
  */
181
- private fun createNotification(type: Int, context: Context, asset: IAsset?): Notification? {
183
+ private fun createNotification(type: Int, context: Context, asset: IAsset?): Notification {
182
184
  var title = "$applicationName: "
183
185
  var contentText = ""
184
186
  var progress = -1
@@ -236,7 +238,8 @@ class NotificationFactory(private val applicationName: String) {
236
238
  setSmallIcon(R.drawable.small_logo)
237
239
  setContentTitle(title)
238
240
  setContentIntent(pendingIntent)
239
- color = context.resources.getColor(android.R.color.holo_blue_bright)
241
+ // The color of notification. This requires Android 21 or higher.
242
+ color = ContextCompat.getColor(getApplicationContext(), R.color.primary)
240
243
  setContentText(contentText)
241
244
  if(progress >= 0)setProgress(100, progress, false)
242
245
  setWhen(System.currentTimeMillis())
@@ -1,5 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <resources>
3
+ <color name="primary">#00202B</color>
3
4
  <color name="colorPrimary">#6200EE</color>
4
5
  <color name="colorPrimaryDark">#3700B3</color>
5
6
  <color name="colorAccent">#03DAC5</color>