react-native-nitro-player 1.0.1 → 1.0.3

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.
@@ -153,6 +153,12 @@ class HybridTrackPlayer : HybridTrackPlayerSpec() {
153
153
  }
154
154
 
155
155
  override fun onAndroidAutoConnectionChange(callback: (connected: Boolean) -> Unit) {
156
+ // Replace any prior listener registered through this HybridObject so JS
157
+ // reloads (Fast Refresh, hot reload) don't accumulate handlers.
158
+ val existing = listenerIds.filter { it.first == "onAndroidAutoConnectionChange" }
159
+ existing.forEach { (_, oldId) -> core.removeOnAndroidAutoConnectionListener(oldId) }
160
+ listenerIds.removeAll { it.first == "onAndroidAutoConnectionChange" }
161
+
156
162
  val id = core.addOnAndroidAutoConnectionListener(callback)
157
163
  listenerIds += "onAndroidAutoConnectionChange" to id
158
164
  }
@@ -120,6 +120,7 @@ class TrackPlayerCore private constructor(
120
120
  } else {
121
121
  updatePlayerQueue(playlist.tracks)
122
122
  }
123
+ checkUpcomingTracksForUrls(lookaheadCount)
123
124
  }
124
125
 
125
126
  // ── Service binding ────────────────────────────────────────────────────
@@ -32,7 +32,6 @@ internal fun TrackPlayerCore.rebuildQueueAndPlayFromIndex(index: Int) {
32
32
  exo.clearMediaItems()
33
33
  exo.setMediaItems(mediaItems)
34
34
  exo.seekToDefaultPosition(0)
35
- exo.playWhenReady = true
36
35
  exo.prepare()
37
36
  }
38
37
 
@@ -319,7 +319,29 @@ class NitroPlayerMediaBrowserService : MediaBrowserServiceCompat() {
319
319
  * Fallback: Load playlists when no media library is set
320
320
  */
321
321
  private suspend fun loadFallbackPlaylists(): MutableList<MediaBrowserCompat.MediaItem> {
322
- val playlists = trackPlayerCore?.getAllPlaylists() ?: emptyList()
322
+ // Apps frequently create internal queue playlists named with raw UUIDs
323
+ // (e.g. `PlayerQueue.createPlaylist(uuid.v4())`). Showing those in
324
+ // Android Auto surfaces ugly UUID strings as titles. Filter:
325
+ // - empty playlists (no tracks)
326
+ // - playlists whose name is a bare UUID
327
+ // - duplicate names (keep latest)
328
+ // and prefer surfacing the currently-loaded playlist first so the user
329
+ // always has access to "what's playing now" while the JS side hasn't
330
+ // published a media library yet.
331
+ val rawPlaylists = trackPlayerCore?.getAllPlaylists() ?: emptyList()
332
+ val currentId = trackPlayerCore?.getCurrentPlaylistId()
333
+ val uuidRegex = Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
334
+
335
+ val dedupedByName = linkedMapOf<String, com.margelo.nitro.nitroplayer.playlist.Playlist>()
336
+ rawPlaylists.forEach { p ->
337
+ if (p.tracks.isEmpty()) return@forEach
338
+ // Always keep the currently-playing playlist regardless of name shape.
339
+ val isCurrent = p.id == currentId
340
+ if (!isCurrent && uuidRegex.matches(p.name)) return@forEach
341
+ dedupedByName[p.name] = p
342
+ }
343
+ val playlists =
344
+ dedupedByName.values.sortedByDescending { it.id == currentId }
323
345
  val mediaItems = mutableListOf<MediaBrowserCompat.MediaItem>()
324
346
 
325
347
  playlists.forEach { playlist ->
@@ -331,11 +353,13 @@ class NitroPlayerMediaBrowserService : MediaBrowserServiceCompat() {
331
353
  )
332
354
  }
333
355
 
356
+ val displayTitle =
357
+ if (uuidRegex.matches(playlist.name)) "Now Playing" else playlist.name
334
358
  val description =
335
359
  MediaDescriptionCompat
336
360
  .Builder()
337
361
  .setMediaId("$PLAYLIST_PREFIX${playlist.id}")
338
- .setTitle(playlist.name)
362
+ .setTitle(displayTitle)
339
363
  .setSubtitle(playlist.description ?: "${playlist.tracks.size} tracks")
340
364
  .setIconUri(playlist.artwork?.let { Uri.parse(it) })
341
365
  .setExtras(extras)
@@ -53,12 +53,14 @@ extension TrackPlayerCore {
53
53
  // If nothing is playing yet, do a full load
54
54
  guard self.player?.currentItem != nil else {
55
55
  self.updatePlayerQueue(tracks: playlist.tracks)
56
+ self.checkUpcomingTracksForUrls(lookahead: self.lookaheadCount)
56
57
  return
57
58
  }
58
59
 
59
60
  // Update tracks list without interrupting playback
60
61
  self.currentTracks = playlist.tracks
61
62
  self.rebuildAVQueueFromCurrentPosition()
63
+ self.checkUpcomingTracksForUrls(lookahead: self.lookaheadCount)
62
64
  }
63
65
 
64
66
  pendingPlaylistUpdateWorkItem = workItem
@@ -172,6 +172,7 @@ class PlaylistManager {
172
172
  // Update TrackPlayerCore if this is the current playlist
173
173
  if currentPlaylistId == playlistId {
174
174
  TrackPlayerCore.shared.updatePlaylist(playlistId: playlistId)
175
+ TrackPlayerCore.shared.checkUpcomingTracksForUrls(lookahead: TrackPlayerCore.shared.lookaheadCount)
175
176
  }
176
177
 
177
178
  return true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
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",