react-native-nitro-player 0.5.5 → 0.5.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.
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/NitroPlayerLogger.kt +8 -2
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +5 -4
- package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadDatabase.kt +43 -10
- package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +16 -7
- package/android/src/main/java/com/margelo/nitro/nitroplayer/storage/NitroPlayerStorage.kt +9 -2
- package/ios/download/DownloadDatabase.swift +79 -2
- package/ios/download/DownloadManagerCore.swift +81 -2
- package/package.json +1 -1
|
@@ -12,7 +12,10 @@ object NitroPlayerLogger {
|
|
|
12
12
|
* Use trailing lambda syntax: NitroPlayerLogger.log("Tag") { "msg $value" }
|
|
13
13
|
* The lambda is inlined (no heap allocation) and skipped entirely when disabled.
|
|
14
14
|
*/
|
|
15
|
-
inline fun log(
|
|
15
|
+
inline fun log(
|
|
16
|
+
header: String = "NitroPlayer",
|
|
17
|
+
message: () -> String,
|
|
18
|
+
) {
|
|
16
19
|
if (isEnabled) {
|
|
17
20
|
Log.d(header, message())
|
|
18
21
|
}
|
|
@@ -23,7 +26,10 @@ object NitroPlayerLogger {
|
|
|
23
26
|
* Note: the String is evaluated at the call site before this function runs.
|
|
24
27
|
* Migrate to the lambda overload for hot paths.
|
|
25
28
|
*/
|
|
26
|
-
fun log(
|
|
29
|
+
fun log(
|
|
30
|
+
header: String = "NitroPlayer",
|
|
31
|
+
message: String,
|
|
32
|
+
) {
|
|
27
33
|
if (isEnabled) {
|
|
28
34
|
Log.d(header, message)
|
|
29
35
|
}
|
|
@@ -698,10 +698,11 @@ class TrackPlayerCore private constructor(
|
|
|
698
698
|
currentRepeatMode = mode
|
|
699
699
|
if (::player.isInitialized) {
|
|
700
700
|
handler.post {
|
|
701
|
-
player.repeatMode =
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
701
|
+
player.repeatMode =
|
|
702
|
+
when (mode) {
|
|
703
|
+
RepeatMode.TRACK -> Player.REPEAT_MODE_ONE
|
|
704
|
+
else -> Player.REPEAT_MODE_OFF
|
|
705
|
+
}
|
|
705
706
|
}
|
|
706
707
|
}
|
|
707
708
|
NitroPlayerLogger.log("TrackPlayerCore", "🔁 setRepeatMode: $mode")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.margelo.nitro.nitroplayer.download
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import com.margelo.nitro.core.AnyMap
|
|
4
5
|
import com.margelo.nitro.core.NullType
|
|
5
6
|
import com.margelo.nitro.nitroplayer.*
|
|
6
7
|
import com.margelo.nitro.nitroplayer.core.NitroPlayerLogger
|
|
@@ -18,6 +19,7 @@ class DownloadDatabase private constructor(
|
|
|
18
19
|
) {
|
|
19
20
|
companion object {
|
|
20
21
|
private const val TAG = "DownloadDatabase"
|
|
22
|
+
|
|
21
23
|
// Legacy SharedPreferences keys (migration only)
|
|
22
24
|
private const val LEGACY_PREFS_NAME = "NitroPlayerDownloads"
|
|
23
25
|
private const val LEGACY_KEY_DOWNLOADED_TRACKS = "downloaded_tracks"
|
|
@@ -304,10 +306,11 @@ class DownloadDatabase private constructor(
|
|
|
304
306
|
playlistJson.put(playlistId, JSONArray(trackIds.toList()))
|
|
305
307
|
}
|
|
306
308
|
|
|
307
|
-
val wrapper =
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
val wrapper =
|
|
310
|
+
JSONObject().apply {
|
|
311
|
+
put("downloadedTracks", tracksJson)
|
|
312
|
+
put("playlistTracks", playlistJson)
|
|
313
|
+
}
|
|
311
314
|
NitroPlayerStorage.write(context, "downloads.json", wrapper.toString())
|
|
312
315
|
} catch (e: Exception) {
|
|
313
316
|
e.printStackTrace()
|
|
@@ -390,8 +393,14 @@ class DownloadDatabase private constructor(
|
|
|
390
393
|
}
|
|
391
394
|
|
|
392
395
|
// Conversion Helpers
|
|
393
|
-
private fun trackItemToRecord(track: TrackItem): TrackItemRecord
|
|
394
|
-
|
|
396
|
+
private fun trackItemToRecord(track: TrackItem): TrackItemRecord {
|
|
397
|
+
val extraPayloadJson =
|
|
398
|
+
track.extraPayload?.let { payload ->
|
|
399
|
+
val extraPayloadMap = payload.toHashMap()
|
|
400
|
+
JSONObject(extraPayloadMap)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return TrackItemRecord(
|
|
395
404
|
id = track.id,
|
|
396
405
|
title = track.title,
|
|
397
406
|
artist = track.artist,
|
|
@@ -399,7 +408,9 @@ class DownloadDatabase private constructor(
|
|
|
399
408
|
duration = track.duration,
|
|
400
409
|
url = track.url,
|
|
401
410
|
artwork = track.artwork?.asSecondOrNull(),
|
|
411
|
+
extraPayload = extraPayloadJson,
|
|
402
412
|
)
|
|
413
|
+
}
|
|
403
414
|
|
|
404
415
|
private fun recordToTrackItem(record: TrackItemRecord): TrackItem {
|
|
405
416
|
val artworkVariant =
|
|
@@ -409,6 +420,21 @@ class DownloadDatabase private constructor(
|
|
|
409
420
|
null
|
|
410
421
|
}
|
|
411
422
|
|
|
423
|
+
val extraPayload: AnyMap? =
|
|
424
|
+
record.extraPayload?.let { extraPayloadJson ->
|
|
425
|
+
val map = AnyMap()
|
|
426
|
+
val keyIterator = extraPayloadJson.keys()
|
|
427
|
+
while (keyIterator.hasNext()) {
|
|
428
|
+
val key = keyIterator.next()
|
|
429
|
+
when (val value = extraPayloadJson.get(key)) {
|
|
430
|
+
is String -> map.setString(key, value)
|
|
431
|
+
is Number -> map.setDouble(key, value.toDouble())
|
|
432
|
+
is Boolean -> map.setBoolean(key, value)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
map
|
|
436
|
+
}
|
|
437
|
+
|
|
412
438
|
return TrackItem(
|
|
413
439
|
id = record.id,
|
|
414
440
|
title = record.title,
|
|
@@ -417,7 +443,7 @@ class DownloadDatabase private constructor(
|
|
|
417
443
|
duration = record.duration,
|
|
418
444
|
url = record.url,
|
|
419
445
|
artwork = artworkVariant,
|
|
420
|
-
extraPayload =
|
|
446
|
+
extraPayload = extraPayload,
|
|
421
447
|
)
|
|
422
448
|
}
|
|
423
449
|
|
|
@@ -440,15 +466,14 @@ class DownloadDatabase private constructor(
|
|
|
440
466
|
)
|
|
441
467
|
}
|
|
442
468
|
|
|
443
|
-
private fun convertPlaylistManagerToNitro(playlist: com.margelo.nitro.nitroplayer.playlist.Playlist): Playlist
|
|
444
|
-
|
|
469
|
+
private fun convertPlaylistManagerToNitro(playlist: com.margelo.nitro.nitroplayer.playlist.Playlist): Playlist =
|
|
470
|
+
Playlist(
|
|
445
471
|
id = playlist.id,
|
|
446
472
|
name = playlist.name,
|
|
447
473
|
description = null,
|
|
448
474
|
artwork = null,
|
|
449
475
|
tracks = playlist.tracks.toTypedArray(),
|
|
450
476
|
)
|
|
451
|
-
}
|
|
452
477
|
}
|
|
453
478
|
|
|
454
479
|
// Internal record classes
|
|
@@ -494,6 +519,7 @@ internal data class TrackItemRecord(
|
|
|
494
519
|
val duration: Double,
|
|
495
520
|
val url: String,
|
|
496
521
|
val artwork: String?,
|
|
522
|
+
val extraPayload: JSONObject?,
|
|
497
523
|
) {
|
|
498
524
|
fun toJson(): JSONObject =
|
|
499
525
|
JSONObject().apply {
|
|
@@ -504,6 +530,7 @@ internal data class TrackItemRecord(
|
|
|
504
530
|
put("duration", duration)
|
|
505
531
|
put("url", url)
|
|
506
532
|
put("artwork", artwork)
|
|
533
|
+
put("extraPayload", extraPayload)
|
|
507
534
|
}
|
|
508
535
|
|
|
509
536
|
companion object {
|
|
@@ -516,6 +543,12 @@ internal data class TrackItemRecord(
|
|
|
516
543
|
duration = json.getDouble("duration"),
|
|
517
544
|
url = json.getString("url"),
|
|
518
545
|
artwork = if (json.isNull("artwork")) null else json.getString("artwork"),
|
|
546
|
+
extraPayload =
|
|
547
|
+
if (json.has("extraPayload") && !json.isNull("extraPayload")) {
|
|
548
|
+
json.getJSONObject("extraPayload")
|
|
549
|
+
} else {
|
|
550
|
+
null
|
|
551
|
+
},
|
|
519
552
|
)
|
|
520
553
|
}
|
|
521
554
|
}
|
|
@@ -405,10 +405,11 @@ class PlaylistManager private constructor(
|
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
val wrapper =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
408
|
+
val wrapper =
|
|
409
|
+
JSONObject().apply {
|
|
410
|
+
put("playlists", jsonArray)
|
|
411
|
+
put("currentPlaylistId", currentPlaylistId)
|
|
412
|
+
}
|
|
412
413
|
NitroPlayerStorage.write(context, "playlists.json", wrapper.toString())
|
|
413
414
|
} catch (e: Exception) {
|
|
414
415
|
e.printStackTrace()
|
|
@@ -423,8 +424,12 @@ class PlaylistManager private constructor(
|
|
|
423
424
|
val wrapper = JSONObject(json)
|
|
424
425
|
val jsonArray = wrapper.optJSONArray("playlists") ?: JSONArray()
|
|
425
426
|
parseAndLoadPlaylists(jsonArray)
|
|
426
|
-
currentPlaylistId =
|
|
427
|
-
|
|
427
|
+
currentPlaylistId =
|
|
428
|
+
if (wrapper.isNull("currentPlaylistId")) {
|
|
429
|
+
null
|
|
430
|
+
} else {
|
|
431
|
+
wrapper.optString("currentPlaylistId", null.toString()).takeIf { it != "null" }
|
|
432
|
+
}
|
|
428
433
|
} catch (e: Exception) {
|
|
429
434
|
e.printStackTrace()
|
|
430
435
|
}
|
|
@@ -440,7 +445,11 @@ class PlaylistManager private constructor(
|
|
|
440
445
|
parseAndLoadPlaylists(jsonArray)
|
|
441
446
|
currentPlaylistId = prefs.getString("currentPlaylistId", null)
|
|
442
447
|
// Remove old SharedPreferences data to free space
|
|
443
|
-
prefs
|
|
448
|
+
prefs
|
|
449
|
+
.edit()
|
|
450
|
+
.remove("playlists")
|
|
451
|
+
.remove("currentPlaylistId")
|
|
452
|
+
.apply()
|
|
444
453
|
// Persist in new format
|
|
445
454
|
saveToFile()
|
|
446
455
|
} catch (e: Exception) {
|
|
@@ -9,7 +9,10 @@ object NitroPlayerStorage {
|
|
|
9
9
|
private const val DIR_NAME = "nitroplayer"
|
|
10
10
|
|
|
11
11
|
/** Reads the contents of [filename] from the NitroPlayer storage directory, or null if absent. */
|
|
12
|
-
fun read(
|
|
12
|
+
fun read(
|
|
13
|
+
context: Context,
|
|
14
|
+
filename: String,
|
|
15
|
+
): String? {
|
|
13
16
|
val file = File(storageDirectory(context), filename)
|
|
14
17
|
return if (file.exists()) {
|
|
15
18
|
try {
|
|
@@ -28,7 +31,11 @@ object NitroPlayerStorage {
|
|
|
28
31
|
* Writes to `<filename>.tmp` first, then renames — leaving the prior file
|
|
29
32
|
* untouched on failure (crash-safe).
|
|
30
33
|
*/
|
|
31
|
-
fun write(
|
|
34
|
+
fun write(
|
|
35
|
+
context: Context,
|
|
36
|
+
filename: String,
|
|
37
|
+
json: String,
|
|
38
|
+
) {
|
|
32
39
|
try {
|
|
33
40
|
val dir = storageDirectory(context)
|
|
34
41
|
dir.mkdirs()
|
|
@@ -490,6 +490,11 @@ final class DownloadDatabase {
|
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
private func trackItemToRecord(_ track: TrackItem) -> TrackItemRecord {
|
|
493
|
+
var extraPayloadDict: [String: Any]? = nil
|
|
494
|
+
if let extraPayload = track.extraPayload {
|
|
495
|
+
extraPayloadDict = extraPayload.toDictionary()
|
|
496
|
+
}
|
|
497
|
+
|
|
493
498
|
return TrackItemRecord(
|
|
494
499
|
id: track.id,
|
|
495
500
|
title: track.title,
|
|
@@ -497,11 +502,28 @@ final class DownloadDatabase {
|
|
|
497
502
|
album: track.album,
|
|
498
503
|
duration: track.duration,
|
|
499
504
|
url: track.url,
|
|
500
|
-
artwork: variantToString(track.artwork)
|
|
505
|
+
artwork: variantToString(track.artwork),
|
|
506
|
+
extraPayload: extraPayloadDict
|
|
501
507
|
)
|
|
502
508
|
}
|
|
503
509
|
|
|
504
510
|
private func recordToTrackItem(_ record: TrackItemRecord) -> TrackItem {
|
|
511
|
+
var extraPayload: AnyMap? = nil
|
|
512
|
+
if let extraPayloadDict = record.extraPayload {
|
|
513
|
+
extraPayload = AnyMap()
|
|
514
|
+
for (key, value) in extraPayloadDict {
|
|
515
|
+
if let stringValue = value as? String {
|
|
516
|
+
extraPayload?.setString(key: key, value: stringValue)
|
|
517
|
+
} else if let doubleValue = value as? Double {
|
|
518
|
+
extraPayload?.setDouble(key: key, value: doubleValue)
|
|
519
|
+
} else if let intValue = value as? Int {
|
|
520
|
+
extraPayload?.setDouble(key: key, value: Double(intValue))
|
|
521
|
+
} else if let boolValue = value as? Bool {
|
|
522
|
+
extraPayload?.setBoolean(key: key, value: boolValue)
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
505
527
|
return TrackItem(
|
|
506
528
|
id: record.id,
|
|
507
529
|
title: record.title,
|
|
@@ -510,7 +532,7 @@ final class DownloadDatabase {
|
|
|
510
532
|
duration: record.duration,
|
|
511
533
|
url: record.url,
|
|
512
534
|
artwork: stringToVariant(record.artwork),
|
|
513
|
-
extraPayload:
|
|
535
|
+
extraPayload: extraPayload
|
|
514
536
|
)
|
|
515
537
|
}
|
|
516
538
|
|
|
@@ -547,4 +569,59 @@ private struct TrackItemRecord: Codable {
|
|
|
547
569
|
let duration: Double
|
|
548
570
|
let url: String
|
|
549
571
|
let artwork: String?
|
|
572
|
+
let extraPayload: [String: Any]?
|
|
573
|
+
|
|
574
|
+
enum CodingKeys: String, CodingKey {
|
|
575
|
+
case id, title, artist, album, duration, url, artwork, extraPayload
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Manual encoding to handle [String: Any]
|
|
579
|
+
func encode(to encoder: Encoder) throws {
|
|
580
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
581
|
+
try container.encode(id, forKey: .id)
|
|
582
|
+
try container.encode(title, forKey: .title)
|
|
583
|
+
try container.encode(artist, forKey: .artist)
|
|
584
|
+
try container.encode(album, forKey: .album)
|
|
585
|
+
try container.encode(duration, forKey: .duration)
|
|
586
|
+
try container.encode(url, forKey: .url)
|
|
587
|
+
try container.encodeIfPresent(artwork, forKey: .artwork)
|
|
588
|
+
|
|
589
|
+
if let extraPayload = extraPayload {
|
|
590
|
+
let jsonData = try JSONSerialization.data(withJSONObject: extraPayload)
|
|
591
|
+
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
|
592
|
+
try container.encode(jsonString, forKey: .extraPayload)
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Manual decoding to handle [String: Any]
|
|
598
|
+
init(from decoder: Decoder) throws {
|
|
599
|
+
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
600
|
+
id = try container.decode(String.self, forKey: .id)
|
|
601
|
+
title = try container.decode(String.self, forKey: .title)
|
|
602
|
+
artist = try container.decode(String.self, forKey: .artist)
|
|
603
|
+
album = try container.decode(String.self, forKey: .album)
|
|
604
|
+
duration = try container.decode(Double.self, forKey: .duration)
|
|
605
|
+
url = try container.decode(String.self, forKey: .url)
|
|
606
|
+
artwork = try container.decodeIfPresent(String.self, forKey: .artwork)
|
|
607
|
+
|
|
608
|
+
if let jsonString = try? container.decodeIfPresent(String.self, forKey: .extraPayload),
|
|
609
|
+
let jsonData = jsonString.data(using: .utf8) {
|
|
610
|
+
extraPayload = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
|
|
611
|
+
} else {
|
|
612
|
+
extraPayload = nil
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// Initializer for code creation
|
|
617
|
+
init(id: String, title: String, artist: String, album: String, duration: Double, url: String, artwork: String?, extraPayload: [String: Any]?) {
|
|
618
|
+
self.id = id
|
|
619
|
+
self.title = title
|
|
620
|
+
self.artist = artist
|
|
621
|
+
self.album = album
|
|
622
|
+
self.duration = duration
|
|
623
|
+
self.url = url
|
|
624
|
+
self.artwork = artwork
|
|
625
|
+
self.extraPayload = extraPayload
|
|
626
|
+
}
|
|
550
627
|
}
|
|
@@ -613,6 +613,12 @@ final class DownloadManagerCore: NSObject {
|
|
|
613
613
|
artworkString = value
|
|
614
614
|
}
|
|
615
615
|
}
|
|
616
|
+
|
|
617
|
+
var extraPayloadDict: [String: Any]? = nil
|
|
618
|
+
if let extraPayload = track.extraPayload {
|
|
619
|
+
extraPayloadDict = extraPayload.toDictionary()
|
|
620
|
+
}
|
|
621
|
+
|
|
616
622
|
return TrackItemRecord(
|
|
617
623
|
id: track.id,
|
|
618
624
|
title: track.title,
|
|
@@ -620,12 +626,30 @@ final class DownloadManagerCore: NSObject {
|
|
|
620
626
|
album: track.album,
|
|
621
627
|
duration: track.duration,
|
|
622
628
|
url: track.url,
|
|
623
|
-
artwork: artworkString
|
|
629
|
+
artwork: artworkString,
|
|
630
|
+
extraPayload: extraPayloadDict
|
|
624
631
|
)
|
|
625
632
|
}
|
|
626
633
|
|
|
627
634
|
private func recordToTrackItem(_ record: TrackItemRecord) -> TrackItem {
|
|
628
635
|
let artwork: Variant_NullType_String? = record.artwork.map { .second($0) }
|
|
636
|
+
|
|
637
|
+
var extraPayload: AnyMap? = nil
|
|
638
|
+
if let extraPayloadDict = record.extraPayload {
|
|
639
|
+
extraPayload = AnyMap()
|
|
640
|
+
for (key, value) in extraPayloadDict {
|
|
641
|
+
if let stringValue = value as? String {
|
|
642
|
+
extraPayload?.setString(key: key, value: stringValue)
|
|
643
|
+
} else if let doubleValue = value as? Double {
|
|
644
|
+
extraPayload?.setDouble(key: key, value: doubleValue)
|
|
645
|
+
} else if let intValue = value as? Int {
|
|
646
|
+
extraPayload?.setDouble(key: key, value: Double(intValue))
|
|
647
|
+
} else if let boolValue = value as? Bool {
|
|
648
|
+
extraPayload?.setBoolean(key: key, value: boolValue)
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
629
653
|
return TrackItem(
|
|
630
654
|
id: record.id,
|
|
631
655
|
title: record.title,
|
|
@@ -634,7 +658,7 @@ final class DownloadManagerCore: NSObject {
|
|
|
634
658
|
duration: record.duration,
|
|
635
659
|
url: record.url,
|
|
636
660
|
artwork: artwork,
|
|
637
|
-
extraPayload:
|
|
661
|
+
extraPayload: extraPayload
|
|
638
662
|
)
|
|
639
663
|
}
|
|
640
664
|
|
|
@@ -963,4 +987,59 @@ private struct TrackItemRecord: Codable {
|
|
|
963
987
|
let duration: Double
|
|
964
988
|
let url: String
|
|
965
989
|
let artwork: String?
|
|
990
|
+
let extraPayload: [String: Any]?
|
|
991
|
+
|
|
992
|
+
enum CodingKeys: String, CodingKey {
|
|
993
|
+
case id, title, artist, album, duration, url, artwork, extraPayload
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Manual encoding to handle [String: Any]
|
|
997
|
+
func encode(to encoder: Encoder) throws {
|
|
998
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
999
|
+
try container.encode(id, forKey: .id)
|
|
1000
|
+
try container.encode(title, forKey: .title)
|
|
1001
|
+
try container.encode(artist, forKey: .artist)
|
|
1002
|
+
try container.encode(album, forKey: .album)
|
|
1003
|
+
try container.encode(duration, forKey: .duration)
|
|
1004
|
+
try container.encode(url, forKey: .url)
|
|
1005
|
+
try container.encodeIfPresent(artwork, forKey: .artwork)
|
|
1006
|
+
|
|
1007
|
+
if let extraPayload = extraPayload {
|
|
1008
|
+
let jsonData = try JSONSerialization.data(withJSONObject: extraPayload)
|
|
1009
|
+
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
|
1010
|
+
try container.encode(jsonString, forKey: .extraPayload)
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Manual decoding to handle [String: Any]
|
|
1016
|
+
init(from decoder: Decoder) throws {
|
|
1017
|
+
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
1018
|
+
id = try container.decode(String.self, forKey: .id)
|
|
1019
|
+
title = try container.decode(String.self, forKey: .title)
|
|
1020
|
+
artist = try container.decode(String.self, forKey: .artist)
|
|
1021
|
+
album = try container.decode(String.self, forKey: .album)
|
|
1022
|
+
duration = try container.decode(Double.self, forKey: .duration)
|
|
1023
|
+
url = try container.decode(String.self, forKey: .url)
|
|
1024
|
+
artwork = try container.decodeIfPresent(String.self, forKey: .artwork)
|
|
1025
|
+
|
|
1026
|
+
if let jsonString = try? container.decodeIfPresent(String.self, forKey: .extraPayload),
|
|
1027
|
+
let jsonData = jsonString.data(using: .utf8) {
|
|
1028
|
+
extraPayload = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
|
|
1029
|
+
} else {
|
|
1030
|
+
extraPayload = nil
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// Initializer for code creation
|
|
1035
|
+
init(id: String, title: String, artist: String, album: String, duration: Double, url: String, artwork: String?, extraPayload: [String: Any]?) {
|
|
1036
|
+
self.id = id
|
|
1037
|
+
self.title = title
|
|
1038
|
+
self.artist = artist
|
|
1039
|
+
self.album = album
|
|
1040
|
+
self.duration = duration
|
|
1041
|
+
self.url = url
|
|
1042
|
+
self.artwork = artwork
|
|
1043
|
+
self.extraPayload = extraPayload
|
|
1044
|
+
}
|
|
966
1045
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-player",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "A powerful audio player library for React Native with playlist management, playback controls, and support for Android Auto and CarPlay",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"module": "lib/index",
|