react-native-nitro-player 0.3.0-alpha.9 → 0.4.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.
Files changed (257) hide show
  1. package/README.md +444 -4
  2. package/android/build.gradle +4 -1
  3. package/android/src/main/AndroidManifest.xml +16 -1
  4. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrary.kt +2 -0
  5. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAudioDevices.kt +8 -0
  6. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridDownloadManager.kt +225 -0
  7. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridEqualizer.kt +105 -0
  8. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridPlayerQueue.kt +6 -6
  9. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +37 -12
  10. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +970 -213
  11. package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadDatabase.kt +475 -0
  12. package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadFileManager.kt +159 -0
  13. package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadManagerCore.kt +489 -0
  14. package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadWorker.kt +209 -0
  15. package/android/src/main/java/com/margelo/nitro/nitroplayer/equalizer/EqualizerCore.kt +486 -0
  16. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaBrowserService.kt +3 -1
  17. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaSessionManager.kt +14 -6
  18. package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +27 -0
  19. package/ios/HybridDownloadManager.swift +226 -0
  20. package/ios/HybridEqualizer.swift +111 -0
  21. package/ios/HybridTrackPlayer.swift +36 -8
  22. package/ios/core/TrackPlayerCore.swift +998 -276
  23. package/ios/download/DownloadDatabase.swift +493 -0
  24. package/ios/download/DownloadFileManager.swift +241 -0
  25. package/ios/download/DownloadManagerCore.swift +923 -0
  26. package/ios/equalizer/EqualizerCore.swift +685 -0
  27. package/ios/media/MediaSessionManager.swift +40 -28
  28. package/ios/playlist/PlaylistManager.swift +40 -9
  29. package/ios/queue/HybridPlayerQueue.swift +33 -13
  30. package/lib/hooks/downloadCallbackManager.d.ts +36 -0
  31. package/lib/hooks/downloadCallbackManager.js +108 -0
  32. package/lib/hooks/equalizerCallbackManager.d.ts +37 -0
  33. package/lib/hooks/equalizerCallbackManager.js +109 -0
  34. package/lib/hooks/index.d.ts +16 -0
  35. package/lib/hooks/index.js +10 -0
  36. package/lib/hooks/useActualQueue.d.ts +48 -0
  37. package/lib/hooks/useActualQueue.js +98 -0
  38. package/lib/hooks/useDownloadActions.d.ts +26 -0
  39. package/lib/hooks/useDownloadActions.js +117 -0
  40. package/lib/hooks/useDownloadProgress.d.ts +25 -0
  41. package/lib/hooks/useDownloadProgress.js +79 -0
  42. package/lib/hooks/useDownloadStorage.d.ts +19 -0
  43. package/lib/hooks/useDownloadStorage.js +60 -0
  44. package/lib/hooks/useDownloadedTracks.d.ts +25 -0
  45. package/lib/hooks/useDownloadedTracks.js +69 -0
  46. package/lib/hooks/useEqualizer.d.ts +25 -0
  47. package/lib/hooks/useEqualizer.js +124 -0
  48. package/lib/hooks/useEqualizerPresets.d.ts +22 -0
  49. package/lib/hooks/useEqualizerPresets.js +96 -0
  50. package/lib/hooks/useNowPlaying.js +3 -2
  51. package/lib/hooks/useOnChangeTrack.js +15 -12
  52. package/lib/hooks/useOnPlaybackStateChange.js +16 -13
  53. package/lib/hooks/usePlaylist.d.ts +48 -0
  54. package/lib/hooks/usePlaylist.js +136 -0
  55. package/lib/index.d.ts +6 -0
  56. package/lib/index.js +6 -0
  57. package/lib/specs/DownloadManager.nitro.d.ts +152 -0
  58. package/lib/specs/DownloadManager.nitro.js +1 -0
  59. package/lib/specs/Equalizer.nitro.d.ts +43 -0
  60. package/lib/specs/Equalizer.nitro.js +1 -0
  61. package/lib/specs/TrackPlayer.nitro.d.ts +6 -2
  62. package/lib/types/DownloadTypes.d.ts +110 -0
  63. package/lib/types/DownloadTypes.js +1 -0
  64. package/lib/types/EqualizerTypes.d.ts +52 -0
  65. package/lib/types/EqualizerTypes.js +1 -0
  66. package/lib/types/PlayerQueue.d.ts +4 -0
  67. package/nitro.json +8 -0
  68. package/nitrogen/generated/android/NitroPlayer+autolinking.cmake +10 -1
  69. package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +32 -2
  70. package/nitrogen/generated/android/c++/JCurrentPlayingType.hpp +65 -0
  71. package/nitrogen/generated/android/c++/JDownloadConfig.hpp +92 -0
  72. package/nitrogen/generated/android/c++/JDownloadError.hpp +71 -0
  73. package/nitrogen/generated/android/c++/JDownloadErrorReason.hpp +74 -0
  74. package/nitrogen/generated/android/c++/JDownloadProgress.hpp +79 -0
  75. package/nitrogen/generated/android/c++/JDownloadQueueStatus.hpp +81 -0
  76. package/nitrogen/generated/android/c++/JDownloadState.hpp +71 -0
  77. package/nitrogen/generated/android/c++/JDownloadStorageInfo.hpp +73 -0
  78. package/nitrogen/generated/android/c++/JDownloadTask.hpp +108 -0
  79. package/nitrogen/generated/android/c++/JDownloadedPlaylist.hpp +111 -0
  80. package/nitrogen/generated/android/c++/JDownloadedTrack.hpp +92 -0
  81. package/nitrogen/generated/android/c++/JEqualizerBand.hpp +69 -0
  82. package/nitrogen/generated/android/c++/JEqualizerPreset.hpp +78 -0
  83. package/nitrogen/generated/android/c++/JEqualizerState.hpp +91 -0
  84. package/nitrogen/generated/android/c++/JFunc_void_DownloadProgress.hpp +80 -0
  85. package/nitrogen/generated/android/c++/JFunc_void_DownloadedTrack.hpp +89 -0
  86. package/nitrogen/generated/android/c++/JFunc_void_TrackItem_std__optional_Reason_.hpp +2 -0
  87. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__std__string__.hpp +81 -0
  88. package/nitrogen/generated/android/c++/JFunc_void_std__string_Playlist_std__optional_QueueOperation_.hpp +2 -0
  89. package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string_DownloadState_std__optional_DownloadError_.hpp +83 -0
  90. package/nitrogen/generated/android/c++/JFunc_void_std__vector_EqualizerBand_.hpp +97 -0
  91. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Playlist__std__optional_QueueOperation_.hpp +2 -0
  92. package/nitrogen/generated/android/c++/JGainRange.hpp +61 -0
  93. package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.cpp +470 -0
  94. package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.hpp +99 -0
  95. package/nitrogen/generated/android/c++/JHybridEqualizerSpec.cpp +204 -0
  96. package/nitrogen/generated/android/c++/JHybridEqualizerSpec.hpp +82 -0
  97. package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +2 -0
  98. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +117 -15
  99. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +6 -2
  100. package/nitrogen/generated/android/c++/JPlaybackSource.hpp +62 -0
  101. package/nitrogen/generated/android/c++/JPlayerState.hpp +11 -3
  102. package/nitrogen/generated/android/c++/JPlaylist.hpp +2 -0
  103. package/nitrogen/generated/android/c++/JPresetType.hpp +59 -0
  104. package/nitrogen/generated/android/c++/JStorageLocation.hpp +59 -0
  105. package/nitrogen/generated/android/c++/JTrackItem.hpp +9 -3
  106. package/nitrogen/generated/android/c++/JTrackPlayerState.hpp +3 -3
  107. package/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp +26 -0
  108. package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +69 -0
  109. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadError.cpp +26 -0
  110. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadError.hpp +74 -0
  111. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadTask.cpp +26 -0
  112. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadTask.hpp +84 -0
  113. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedPlaylist.cpp +26 -0
  114. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedPlaylist.hpp +85 -0
  115. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedTrack.cpp +26 -0
  116. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedTrack.hpp +80 -0
  117. package/nitrogen/generated/android/c++/JVariant_NullType_Playlist.hpp +2 -0
  118. package/nitrogen/generated/android/c++/JVariant_NullType_TrackItem.hpp +2 -0
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/CurrentPlayingType.kt +23 -0
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadConfig.kt +59 -0
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadError.kt +47 -0
  122. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadErrorReason.kt +26 -0
  123. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadProgress.kt +53 -0
  124. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadQueueStatus.kt +56 -0
  125. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadState.kt +25 -0
  126. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadStorageInfo.kt +50 -0
  127. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadTask.kt +65 -0
  128. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadedPlaylist.kt +53 -0
  129. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/DownloadedTrack.kt +56 -0
  130. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/EqualizerBand.kt +47 -0
  131. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/EqualizerPreset.kt +44 -0
  132. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/EqualizerState.kt +44 -0
  133. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_DownloadProgress.kt +80 -0
  134. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_DownloadedTrack.kt +80 -0
  135. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__optional_std__variant_nitro__NullType__std__string__.kt +80 -0
  136. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__string_std__string_DownloadState_std__optional_DownloadError_.kt +80 -0
  137. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__vector_EqualizerBand_.kt +80 -0
  138. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/GainRange.kt +41 -0
  139. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridDownloadManagerSpec.kt +210 -0
  140. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridEqualizerSpec.kt +141 -0
  141. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +19 -2
  142. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlaybackSource.kt +22 -0
  143. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlayerState.kt +6 -3
  144. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PresetType.kt +21 -0
  145. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/StorageLocation.kt +21 -0
  146. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TrackItem.kt +7 -3
  147. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TrackPlayerState.kt +2 -2
  148. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Double.kt +59 -0
  149. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadError.kt +59 -0
  150. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadTask.kt +59 -0
  151. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedPlaylist.kt +59 -0
  152. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedTrack.kt +59 -0
  153. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +138 -8
  154. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +1046 -121
  155. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Umbrella.hpp +66 -0
  156. package/nitrogen/generated/ios/NitroPlayerAutolinking.mm +16 -0
  157. package/nitrogen/generated/ios/NitroPlayerAutolinking.swift +30 -0
  158. package/nitrogen/generated/ios/c++/HybridDownloadManagerSpecSwift.cpp +11 -0
  159. package/nitrogen/generated/ios/c++/HybridDownloadManagerSpecSwift.hpp +386 -0
  160. package/nitrogen/generated/ios/c++/HybridEqualizerSpecSwift.cpp +11 -0
  161. package/nitrogen/generated/ios/c++/HybridEqualizerSpecSwift.hpp +223 -0
  162. package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.hpp +1 -0
  163. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +46 -6
  164. package/nitrogen/generated/ios/swift/CurrentPlayingType.swift +48 -0
  165. package/nitrogen/generated/ios/swift/DownloadConfig.swift +270 -0
  166. package/nitrogen/generated/ios/swift/DownloadError.swift +69 -0
  167. package/nitrogen/generated/ios/swift/DownloadErrorReason.swift +60 -0
  168. package/nitrogen/generated/ios/swift/DownloadProgress.swift +91 -0
  169. package/nitrogen/generated/ios/swift/DownloadQueueStatus.swift +102 -0
  170. package/nitrogen/generated/ios/swift/DownloadState.swift +56 -0
  171. package/nitrogen/generated/ios/swift/DownloadStorageInfo.swift +80 -0
  172. package/nitrogen/generated/ios/swift/DownloadTask.swift +315 -0
  173. package/nitrogen/generated/ios/swift/DownloadedPlaylist.swift +103 -0
  174. package/nitrogen/generated/ios/swift/DownloadedTrack.swift +147 -0
  175. package/nitrogen/generated/ios/swift/EqualizerBand.swift +69 -0
  176. package/nitrogen/generated/ios/swift/EqualizerPreset.swift +70 -0
  177. package/nitrogen/generated/ios/swift/EqualizerState.swift +115 -0
  178. package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  179. package/nitrogen/generated/ios/swift/Func_void_DownloadProgress.swift +47 -0
  180. package/nitrogen/generated/ios/swift/Func_void_DownloadStorageInfo.swift +47 -0
  181. package/nitrogen/generated/ios/swift/Func_void_DownloadedTrack.swift +47 -0
  182. package/nitrogen/generated/ios/swift/Func_void_PlayerState.swift +47 -0
  183. package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
  184. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  185. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__variant_nitro__NullType__std__string__.swift +66 -0
  186. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  187. package/nitrogen/generated/ios/swift/Func_void_std__string_std__string_DownloadState_std__optional_DownloadError_.swift +47 -0
  188. package/nitrogen/generated/ios/swift/Func_void_std__vector_EqualizerBand_.swift +47 -0
  189. package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem_.swift +47 -0
  190. package/nitrogen/generated/ios/swift/Func_void_std__vector_std__string_.swift +47 -0
  191. package/nitrogen/generated/ios/swift/GainRange.swift +47 -0
  192. package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec.swift +90 -0
  193. package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec_cxx.swift +705 -0
  194. package/nitrogen/generated/ios/swift/HybridEqualizerSpec.swift +73 -0
  195. package/nitrogen/generated/ios/swift/HybridEqualizerSpec_cxx.swift +396 -0
  196. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +6 -2
  197. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +105 -8
  198. package/nitrogen/generated/ios/swift/PlaybackSource.swift +44 -0
  199. package/nitrogen/generated/ios/swift/PlayerState.swift +13 -2
  200. package/nitrogen/generated/ios/swift/PresetType.swift +40 -0
  201. package/nitrogen/generated/ios/swift/StorageLocation.swift +40 -0
  202. package/nitrogen/generated/ios/swift/TrackItem.swift +31 -1
  203. package/nitrogen/generated/ios/swift/TrackPlayerState.swift +4 -4
  204. package/nitrogen/generated/ios/swift/Variant_NullType_Double.swift +18 -0
  205. package/nitrogen/generated/ios/swift/Variant_NullType_DownloadError.swift +18 -0
  206. package/nitrogen/generated/ios/swift/Variant_NullType_DownloadTask.swift +18 -0
  207. package/nitrogen/generated/ios/swift/Variant_NullType_DownloadedPlaylist.swift +18 -0
  208. package/nitrogen/generated/ios/swift/Variant_NullType_DownloadedTrack.swift +18 -0
  209. package/nitrogen/generated/shared/c++/CurrentPlayingType.hpp +84 -0
  210. package/nitrogen/generated/shared/c++/DownloadConfig.hpp +108 -0
  211. package/nitrogen/generated/shared/c++/DownloadError.hpp +89 -0
  212. package/nitrogen/generated/shared/c++/DownloadErrorReason.hpp +96 -0
  213. package/nitrogen/generated/shared/c++/DownloadProgress.hpp +97 -0
  214. package/nitrogen/generated/shared/c++/DownloadQueueStatus.hpp +99 -0
  215. package/nitrogen/generated/shared/c++/DownloadState.hpp +92 -0
  216. package/nitrogen/generated/shared/c++/DownloadStorageInfo.hpp +91 -0
  217. package/nitrogen/generated/shared/c++/DownloadTask.hpp +122 -0
  218. package/nitrogen/generated/shared/c++/DownloadedPlaylist.hpp +101 -0
  219. package/nitrogen/generated/shared/c++/DownloadedTrack.hpp +107 -0
  220. package/nitrogen/generated/shared/c++/EqualizerBand.hpp +87 -0
  221. package/nitrogen/generated/shared/c++/EqualizerPreset.hpp +86 -0
  222. package/nitrogen/generated/shared/c++/EqualizerState.hpp +89 -0
  223. package/nitrogen/generated/shared/c++/GainRange.hpp +79 -0
  224. package/nitrogen/generated/shared/c++/HybridDownloadManagerSpec.cpp +55 -0
  225. package/nitrogen/generated/shared/c++/HybridDownloadManagerSpec.hpp +134 -0
  226. package/nitrogen/generated/shared/c++/HybridEqualizerSpec.cpp +38 -0
  227. package/nitrogen/generated/shared/c++/HybridEqualizerSpec.hpp +95 -0
  228. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +4 -0
  229. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +11 -5
  230. package/nitrogen/generated/shared/c++/PlaybackSource.hpp +80 -0
  231. package/nitrogen/generated/shared/c++/PlayerState.hpp +9 -2
  232. package/nitrogen/generated/shared/c++/PresetType.hpp +76 -0
  233. package/nitrogen/generated/shared/c++/StorageLocation.hpp +76 -0
  234. package/nitrogen/generated/shared/c++/TrackItem.hpp +7 -2
  235. package/nitrogen/generated/shared/c++/TrackPlayerState.hpp +5 -5
  236. package/package.json +1 -1
  237. package/src/hooks/downloadCallbackManager.ts +149 -0
  238. package/src/hooks/equalizerCallbackManager.ts +138 -0
  239. package/src/hooks/index.ts +23 -0
  240. package/src/hooks/useActualQueue.ts +116 -0
  241. package/src/hooks/useDownloadActions.ts +179 -0
  242. package/src/hooks/useDownloadProgress.ts +126 -0
  243. package/src/hooks/useDownloadStorage.ts +84 -0
  244. package/src/hooks/useDownloadedTracks.ts +138 -0
  245. package/src/hooks/useEqualizer.ts +173 -0
  246. package/src/hooks/useEqualizerPresets.ts +140 -0
  247. package/src/hooks/useNowPlaying.ts +3 -2
  248. package/src/hooks/useOnChangeTrack.ts +15 -11
  249. package/src/hooks/useOnPlaybackStateChange.ts +19 -15
  250. package/src/hooks/usePlaylist.ts +161 -0
  251. package/src/index.ts +12 -0
  252. package/src/specs/DownloadManager.nitro.ts +203 -0
  253. package/src/specs/Equalizer.nitro.ts +69 -0
  254. package/src/specs/TrackPlayer.nitro.ts +6 -2
  255. package/src/types/DownloadTypes.ts +135 -0
  256. package/src/types/EqualizerTypes.ts +72 -0
  257. package/src/types/PlayerQueue.ts +9 -0
@@ -106,36 +106,29 @@ class MediaSessionManager {
106
106
  return .success
107
107
  }
108
108
 
109
- // Seek forward
110
- commandCenter.seekForwardCommand.isEnabled = true
111
- commandCenter.seekForwardCommand.addTarget { [weak self] event in
112
- guard let self = self, let core = self.trackPlayerCore else { return .commandFailed }
113
- let state = core.getState()
114
- let newPosition = min(state.currentPosition + Constants.seekInterval, state.totalDuration)
115
- core.seek(position: newPosition)
116
- return .success
117
- }
109
+ // Disable continuous seek commands - they replace the interactive scrubber
110
+ // with non-interactive forward/backward buttons on the lock screen
111
+ commandCenter.seekForwardCommand.isEnabled = false
112
+ commandCenter.seekBackwardCommand.isEnabled = false
118
113
 
119
- // Seek backward
120
- commandCenter.seekBackwardCommand.isEnabled = true
121
- commandCenter.seekBackwardCommand.addTarget { [weak self] event in
122
- guard let self = self, let core = self.trackPlayerCore else { return .commandFailed }
123
- let state = core.getState()
124
- let newPosition = max(state.currentPosition - Constants.seekInterval, 0.0)
125
- core.seek(position: newPosition)
126
- return .success
127
- }
128
-
129
- // Change playback position
114
+ // Change playback position (interactive scrubber)
130
115
  commandCenter.changePlaybackPositionCommand.isEnabled = true
131
116
  commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in
132
117
  guard let self = self,
133
118
  let core = self.trackPlayerCore,
134
- let event = event as? MPChangePlaybackPositionCommandEvent
119
+ let positionEvent = event as? MPChangePlaybackPositionCommandEvent
135
120
  else {
136
121
  return .commandFailed
137
122
  }
138
- core.seek(position: event.positionTime)
123
+ // Immediately update elapsed time AND set playback rate to 0 during seek
124
+ // This prevents the scrubber from freezing/desyncing during the async seek operation
125
+ if var info = MPNowPlayingInfoCenter.default().nowPlayingInfo {
126
+ info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = positionEvent.positionTime
127
+ // Set rate to 0 to pause scrubber animation during seek
128
+ info[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
129
+ MPNowPlayingInfoCenter.default().nowPlayingInfo = info
130
+ }
131
+ core.seek(position: positionEvent.positionTime)
139
132
  return .success
140
133
  }
141
134
  }
@@ -156,20 +149,39 @@ class MediaSessionManager {
156
149
 
157
150
  let state = core.getState()
158
151
 
159
- let nowPlayingInfo: [String: Any] = [
152
+ // Use player duration if valid, otherwise fall back to track metadata duration.
153
+ // Duration must always be present for the lock screen scrubber to be interactive.
154
+ let playerDuration = state.totalDuration
155
+ let effectiveDuration: Double
156
+ if playerDuration > 0 && !playerDuration.isNaN && !playerDuration.isInfinite {
157
+ effectiveDuration = playerDuration
158
+ } else {
159
+ effectiveDuration = track.duration
160
+ }
161
+
162
+ var nowPlayingInfo: [String: Any] = [
160
163
  MPMediaItemPropertyTitle: track.title,
161
164
  MPMediaItemPropertyArtist: track.artist,
162
165
  MPMediaItemPropertyAlbumTitle: track.album,
163
166
  MPNowPlayingInfoPropertyElapsedPlaybackTime: state.currentPosition,
164
- MPMediaItemPropertyPlaybackDuration: state.totalDuration,
167
+ MPMediaItemPropertyPlaybackDuration: effectiveDuration,
165
168
  MPNowPlayingInfoPropertyPlaybackRate: state.currentState == .playing ? 1.0 : 0.0,
166
169
  ]
167
170
 
168
- // Load artwork asynchronously
171
+ // Add artwork synchronously if cached, otherwise load async
169
172
  if let artwork = track.artwork, case .second(let artworkUrl) = artwork {
170
- loadArtwork(url: artworkUrl) { [weak self] image in
171
- if let image = image {
172
- var updatedInfo = nowPlayingInfo
173
+ if let cachedImage = artworkCache[artworkUrl] {
174
+ // Artwork is cached - include it directly to avoid overwrite race condition
175
+ nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(
176
+ boundsSize: CGSize(width: Constants.artworkSize, height: Constants.artworkSize),
177
+ requestHandler: { _ in cachedImage }
178
+ )
179
+ } else {
180
+ // Artwork not cached - load asynchronously and update later
181
+ loadArtwork(url: artworkUrl) { [weak self] image in
182
+ guard let self = self, let image = image else { return }
183
+ // Re-read current nowPlayingInfo to avoid overwriting other updates
184
+ var updatedInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
173
185
  updatedInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(
174
186
  boundsSize: CGSize(width: Constants.artworkSize, height: Constants.artworkSize),
175
187
  requestHandler: { _ in image }
@@ -260,7 +260,8 @@ class PlaylistManager {
260
260
  * Load a playlist for playback (sets it as current)
261
261
  */
262
262
  func loadPlaylist(playlistId: String) -> Bool {
263
- guard let playlist = queue.sync(execute: { playlists[playlistId] }) else {
263
+ let exists = queue.sync { playlists[playlistId] != nil }
264
+ guard exists else {
264
265
  return false
265
266
  }
266
267
 
@@ -326,18 +327,26 @@ class PlaylistManager {
326
327
  }
327
328
 
328
329
  private func notifyPlaylistsChanged(_ operation: QueueOperation?) {
329
- let allPlaylists = queue.sync {
330
- return Array(playlists.values)
330
+ let (allPlaylists, currentListeners) = queue.sync {
331
+ (Array(playlists.values), listeners)
332
+ }
333
+ DispatchQueue.main.async {
334
+ currentListeners.forEach { $0.1(allPlaylists, operation) }
331
335
  }
332
- listeners.forEach { $0.1(allPlaylists, operation) }
333
336
  }
334
337
 
335
338
  private func notifyPlaylistChanged(_ playlistId: String, _ operation: QueueOperation?) {
336
- guard let playlist = queue.sync(execute: { playlists[playlistId] }) else {
337
- return
339
+ let result: (PlaylistModel, [(String, (PlaylistModel, QueueOperation?) -> Void)])? = queue.sync
340
+ {
341
+ guard let p = playlists[playlistId] else { return nil }
342
+ return (p, playlistListeners[playlistId] ?? [])
338
343
  }
339
344
 
340
- playlistListeners[playlistId]?.forEach { $0.1(playlist, operation) }
345
+ guard let (playlist, currentListeners) = result else { return }
346
+
347
+ DispatchQueue.main.async {
348
+ currentListeners.forEach { $0.1(playlist, operation) }
349
+ }
341
350
  }
342
351
 
343
352
  private func savePlaylistsToUserDefaults() {
@@ -368,6 +377,10 @@ class PlaylistManager {
368
377
  } else {
369
378
  trackDict["artwork"] = ""
370
379
  }
380
+ // Serialize extraPayload to dictionary for persistence
381
+ if let extraPayload = track.extraPayload {
382
+ trackDict["extraPayload"] = extraPayload.toDictionary()
383
+ }
371
384
  return trackDict
372
385
  },
373
386
  ]
@@ -386,7 +399,6 @@ class PlaylistManager {
386
399
  }
387
400
 
388
401
  do {
389
- let decoder = JSONDecoder()
390
402
  let playlistsDict = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] ?? []
391
403
 
392
404
  queue.sync {
@@ -417,6 +429,24 @@ class PlaylistManager {
417
429
  let artwork = artworkString.flatMap {
418
430
  !$0.isEmpty ? Variant_NullType_String.second($0) : nil
419
431
  }
432
+
433
+ // Deserialize extraPayload from dictionary
434
+ var extraPayload: AnyMap? = nil
435
+ if let extraPayloadDict = trackDict["extraPayload"] as? [String: Any] {
436
+ extraPayload = AnyMap()
437
+ for (key, value) in extraPayloadDict {
438
+ if let stringValue = value as? String {
439
+ extraPayload?.setString(key: key, value: stringValue)
440
+ } else if let doubleValue = value as? Double {
441
+ extraPayload?.setDouble(key: key, value: doubleValue)
442
+ } else if let intValue = value as? Int {
443
+ extraPayload?.setDouble(key: key, value: Double(intValue))
444
+ } else if let boolValue = value as? Bool {
445
+ extraPayload?.setBoolean(key: key, value: boolValue)
446
+ }
447
+ }
448
+ }
449
+
420
450
  return TrackItem(
421
451
  id: id,
422
452
  title: title,
@@ -424,7 +454,8 @@ class PlaylistManager {
424
454
  album: album,
425
455
  duration: duration,
426
456
  url: url,
427
- artwork: artwork
457
+ artwork: artwork,
458
+ extraPayload: extraPayload
428
459
  )
429
460
  }
430
461
 
@@ -9,8 +9,12 @@ import NitroModules
9
9
 
10
10
  final class HybridPlayerQueue: HybridPlayerQueueSpec {
11
11
  private let playlistManager = PlaylistManager.shared
12
- private var playlistsChangeListener: (() -> Void)?
13
- private var playlistChangeListeners: [String: () -> Void] = [:]
12
+
13
+ // Static storage for callbacks to ensure they persist across HybridPlayerQueue instances
14
+ private static var playlistsChangeCallbacks: [([Playlist], QueueOperation?) -> Void] = []
15
+ private static var playlistChangeCallbacks: [(String, Playlist, QueueOperation?) -> Void] = []
16
+ private static var isPlaylistsListenerRegistered = false
17
+ private static var playlistListenerIds: Set<String> = []
14
18
 
15
19
  func createPlaylist(name: String, description: String?, artwork: String?) throws -> String {
16
20
  return playlistManager.createPlaylist(name: name, description: description, artwork: artwork)
@@ -72,24 +76,40 @@ final class HybridPlayerQueue: HybridPlayerQueueSpec {
72
76
  }
73
77
 
74
78
  func onPlaylistsChanged(callback: @escaping ([Playlist], QueueOperation?) -> Void) throws {
75
- // Remove previous listener if exists
76
- playlistsChangeListener?()
77
-
78
- // Add new listener
79
- playlistsChangeListener = playlistManager.addPlaylistsChangeListener { playlists, operation in
80
- callback(playlists.map { $0.toGeneratedPlaylist() }, operation)
79
+ // Store callback in static storage so it persists across HybridPlayerQueue instances
80
+ HybridPlayerQueue.playlistsChangeCallbacks.append(callback)
81
+
82
+ // Register a single listener with PlaylistManager that dispatches to all callbacks
83
+ if !HybridPlayerQueue.isPlaylistsListenerRegistered {
84
+ HybridPlayerQueue.isPlaylistsListenerRegistered = true
85
+ _ = playlistManager.addPlaylistsChangeListener { playlists, operation in
86
+ let generatedPlaylists = playlists.map { $0.toGeneratedPlaylist() }
87
+ // Call all registered callbacks
88
+ for cb in HybridPlayerQueue.playlistsChangeCallbacks {
89
+ cb(generatedPlaylists, operation)
90
+ }
91
+ }
81
92
  }
82
93
  }
83
94
 
84
95
  func onPlaylistChanged(callback: @escaping (String, Playlist, QueueOperation?) -> Void) throws {
85
- // Listen to all playlists
96
+ // Store callback in static storage so it persists across HybridPlayerQueue instances
97
+ HybridPlayerQueue.playlistChangeCallbacks.append(callback)
98
+
99
+ // Register listeners for all existing playlists (only once per playlist)
86
100
  let allPlaylists = playlistManager.getAllPlaylists()
87
101
  for playlist in allPlaylists {
88
- let removeListener = playlistManager.addPlaylistChangeListener(playlistId: playlist.id) {
89
- updatedPlaylist, operation in
90
- callback(updatedPlaylist.id, updatedPlaylist.toGeneratedPlaylist(), operation)
102
+ if !HybridPlayerQueue.playlistListenerIds.contains(playlist.id) {
103
+ HybridPlayerQueue.playlistListenerIds.insert(playlist.id)
104
+ _ = playlistManager.addPlaylistChangeListener(playlistId: playlist.id) {
105
+ updatedPlaylist, operation in
106
+ let generatedPlaylist = updatedPlaylist.toGeneratedPlaylist()
107
+ // Call all registered callbacks
108
+ for cb in HybridPlayerQueue.playlistChangeCallbacks {
109
+ cb(updatedPlaylist.id, generatedPlaylist, operation)
110
+ }
111
+ }
91
112
  }
92
- playlistChangeListeners[playlist.id] = removeListener
93
113
  }
94
114
  }
95
115
  }
@@ -0,0 +1,36 @@
1
+ import type { DownloadProgress, DownloadState, DownloadedTrack, DownloadError } from '../types/DownloadTypes';
2
+ type ProgressCallback = (progress: DownloadProgress) => void;
3
+ type StateChangeCallback = (downloadId: string, trackId: string, state: DownloadState, error?: DownloadError) => void;
4
+ type CompleteCallback = (downloadedTrack: DownloadedTrack) => void;
5
+ /**
6
+ * Internal subscription manager for download callbacks.
7
+ * Allows multiple hooks to subscribe to a single native callback.
8
+ */
9
+ declare class DownloadCallbackSubscriptionManager {
10
+ private progressSubscribers;
11
+ private stateChangeSubscribers;
12
+ private completeSubscribers;
13
+ private isProgressRegistered;
14
+ private isStateChangeRegistered;
15
+ private isCompleteRegistered;
16
+ /**
17
+ * Subscribe to download progress updates
18
+ * @returns Unsubscribe function
19
+ */
20
+ subscribeToProgress(callback: ProgressCallback): () => void;
21
+ /**
22
+ * Subscribe to download state changes
23
+ * @returns Unsubscribe function
24
+ */
25
+ subscribeToStateChange(callback: StateChangeCallback): () => void;
26
+ /**
27
+ * Subscribe to download completions
28
+ * @returns Unsubscribe function
29
+ */
30
+ subscribeToComplete(callback: CompleteCallback): () => void;
31
+ private ensureProgressRegistered;
32
+ private ensureStateChangeRegistered;
33
+ private ensureCompleteRegistered;
34
+ }
35
+ export declare const downloadCallbackManager: DownloadCallbackSubscriptionManager;
36
+ export {};
@@ -0,0 +1,108 @@
1
+ import { DownloadManager } from '../index';
2
+ /**
3
+ * Internal subscription manager for download callbacks.
4
+ * Allows multiple hooks to subscribe to a single native callback.
5
+ */
6
+ class DownloadCallbackSubscriptionManager {
7
+ progressSubscribers = new Set();
8
+ stateChangeSubscribers = new Set();
9
+ completeSubscribers = new Set();
10
+ isProgressRegistered = false;
11
+ isStateChangeRegistered = false;
12
+ isCompleteRegistered = false;
13
+ /**
14
+ * Subscribe to download progress updates
15
+ * @returns Unsubscribe function
16
+ */
17
+ subscribeToProgress(callback) {
18
+ this.progressSubscribers.add(callback);
19
+ this.ensureProgressRegistered();
20
+ return () => {
21
+ this.progressSubscribers.delete(callback);
22
+ };
23
+ }
24
+ /**
25
+ * Subscribe to download state changes
26
+ * @returns Unsubscribe function
27
+ */
28
+ subscribeToStateChange(callback) {
29
+ this.stateChangeSubscribers.add(callback);
30
+ this.ensureStateChangeRegistered();
31
+ return () => {
32
+ this.stateChangeSubscribers.delete(callback);
33
+ };
34
+ }
35
+ /**
36
+ * Subscribe to download completions
37
+ * @returns Unsubscribe function
38
+ */
39
+ subscribeToComplete(callback) {
40
+ this.completeSubscribers.add(callback);
41
+ this.ensureCompleteRegistered();
42
+ return () => {
43
+ this.completeSubscribers.delete(callback);
44
+ };
45
+ }
46
+ ensureProgressRegistered() {
47
+ if (this.isProgressRegistered)
48
+ return;
49
+ try {
50
+ DownloadManager.onDownloadProgress((progress) => {
51
+ this.progressSubscribers.forEach((subscriber) => {
52
+ try {
53
+ subscriber(progress);
54
+ }
55
+ catch (error) {
56
+ console.error('[DownloadCallbackManager] Error in progress subscriber:', error);
57
+ }
58
+ });
59
+ });
60
+ this.isProgressRegistered = true;
61
+ }
62
+ catch (error) {
63
+ console.error('[DownloadCallbackManager] Failed to register progress callback:', error);
64
+ }
65
+ }
66
+ ensureStateChangeRegistered() {
67
+ if (this.isStateChangeRegistered)
68
+ return;
69
+ try {
70
+ DownloadManager.onDownloadStateChange((downloadId, trackId, state, error) => {
71
+ this.stateChangeSubscribers.forEach((subscriber) => {
72
+ try {
73
+ subscriber(downloadId, trackId, state, error);
74
+ }
75
+ catch (err) {
76
+ console.error('[DownloadCallbackManager] Error in state change subscriber:', err);
77
+ }
78
+ });
79
+ });
80
+ this.isStateChangeRegistered = true;
81
+ }
82
+ catch (error) {
83
+ console.error('[DownloadCallbackManager] Failed to register state change callback:', error);
84
+ }
85
+ }
86
+ ensureCompleteRegistered() {
87
+ if (this.isCompleteRegistered)
88
+ return;
89
+ try {
90
+ DownloadManager.onDownloadComplete((downloadedTrack) => {
91
+ this.completeSubscribers.forEach((subscriber) => {
92
+ try {
93
+ subscriber(downloadedTrack);
94
+ }
95
+ catch (error) {
96
+ console.error('[DownloadCallbackManager] Error in complete subscriber:', error);
97
+ }
98
+ });
99
+ });
100
+ this.isCompleteRegistered = true;
101
+ }
102
+ catch (error) {
103
+ console.error('[DownloadCallbackManager] Failed to register complete callback:', error);
104
+ }
105
+ }
106
+ }
107
+ // Export singleton instance
108
+ export const downloadCallbackManager = new DownloadCallbackSubscriptionManager();
@@ -0,0 +1,37 @@
1
+ import type { EqualizerBand } from '../types/EqualizerTypes';
2
+ type EnabledChangeCallback = (enabled: boolean) => void;
3
+ type BandChangeCallback = (bands: EqualizerBand[]) => void;
4
+ type PresetChangeCallback = (presetName: string | null) => void;
5
+ /**
6
+ * Internal subscription manager that allows multiple hooks to subscribe
7
+ * to equalizer callbacks. This solves the problem where registering
8
+ * a new callback overwrites the previous one.
9
+ */
10
+ declare class EqualizerCallbackSubscriptionManager {
11
+ private enabledChangeSubscribers;
12
+ private bandChangeSubscribers;
13
+ private presetChangeSubscribers;
14
+ private isEnabledChangeRegistered;
15
+ private isBandChangeRegistered;
16
+ private isPresetChangeRegistered;
17
+ /**
18
+ * Subscribe to enabled state changes
19
+ * @returns Unsubscribe function
20
+ */
21
+ subscribeToEnabledChange(callback: EnabledChangeCallback): () => void;
22
+ /**
23
+ * Subscribe to band changes
24
+ * @returns Unsubscribe function
25
+ */
26
+ subscribeToBandChange(callback: BandChangeCallback): () => void;
27
+ /**
28
+ * Subscribe to preset changes
29
+ * @returns Unsubscribe function
30
+ */
31
+ subscribeToPresetChange(callback: PresetChangeCallback): () => void;
32
+ private ensureEnabledChangeRegistered;
33
+ private ensureBandChangeRegistered;
34
+ private ensurePresetChangeRegistered;
35
+ }
36
+ export declare const equalizerCallbackManager: EqualizerCallbackSubscriptionManager;
37
+ export {};
@@ -0,0 +1,109 @@
1
+ import { Equalizer } from '../index';
2
+ /**
3
+ * Internal subscription manager that allows multiple hooks to subscribe
4
+ * to equalizer callbacks. This solves the problem where registering
5
+ * a new callback overwrites the previous one.
6
+ */
7
+ class EqualizerCallbackSubscriptionManager {
8
+ enabledChangeSubscribers = new Set();
9
+ bandChangeSubscribers = new Set();
10
+ presetChangeSubscribers = new Set();
11
+ isEnabledChangeRegistered = false;
12
+ isBandChangeRegistered = false;
13
+ isPresetChangeRegistered = false;
14
+ /**
15
+ * Subscribe to enabled state changes
16
+ * @returns Unsubscribe function
17
+ */
18
+ subscribeToEnabledChange(callback) {
19
+ this.enabledChangeSubscribers.add(callback);
20
+ this.ensureEnabledChangeRegistered();
21
+ return () => {
22
+ this.enabledChangeSubscribers.delete(callback);
23
+ };
24
+ }
25
+ /**
26
+ * Subscribe to band changes
27
+ * @returns Unsubscribe function
28
+ */
29
+ subscribeToBandChange(callback) {
30
+ this.bandChangeSubscribers.add(callback);
31
+ this.ensureBandChangeRegistered();
32
+ return () => {
33
+ this.bandChangeSubscribers.delete(callback);
34
+ };
35
+ }
36
+ /**
37
+ * Subscribe to preset changes
38
+ * @returns Unsubscribe function
39
+ */
40
+ subscribeToPresetChange(callback) {
41
+ this.presetChangeSubscribers.add(callback);
42
+ this.ensurePresetChangeRegistered();
43
+ return () => {
44
+ this.presetChangeSubscribers.delete(callback);
45
+ };
46
+ }
47
+ ensureEnabledChangeRegistered() {
48
+ if (this.isEnabledChangeRegistered)
49
+ return;
50
+ try {
51
+ Equalizer.onEnabledChange((enabled) => {
52
+ this.enabledChangeSubscribers.forEach((subscriber) => {
53
+ try {
54
+ subscriber(enabled);
55
+ }
56
+ catch (error) {
57
+ console.error('[EqualizerCallbackManager] Error in enabled change subscriber:', error);
58
+ }
59
+ });
60
+ });
61
+ this.isEnabledChangeRegistered = true;
62
+ }
63
+ catch (error) {
64
+ console.error('[EqualizerCallbackManager] Failed to register enabled change callback:', error);
65
+ }
66
+ }
67
+ ensureBandChangeRegistered() {
68
+ if (this.isBandChangeRegistered)
69
+ return;
70
+ try {
71
+ Equalizer.onBandChange((bands) => {
72
+ this.bandChangeSubscribers.forEach((subscriber) => {
73
+ try {
74
+ subscriber(bands);
75
+ }
76
+ catch (error) {
77
+ console.error('[EqualizerCallbackManager] Error in band change subscriber:', error);
78
+ }
79
+ });
80
+ });
81
+ this.isBandChangeRegistered = true;
82
+ }
83
+ catch (error) {
84
+ console.error('[EqualizerCallbackManager] Failed to register band change callback:', error);
85
+ }
86
+ }
87
+ ensurePresetChangeRegistered() {
88
+ if (this.isPresetChangeRegistered)
89
+ return;
90
+ try {
91
+ Equalizer.onPresetChange((presetName) => {
92
+ this.presetChangeSubscribers.forEach((subscriber) => {
93
+ try {
94
+ subscriber(presetName);
95
+ }
96
+ catch (error) {
97
+ console.error('[EqualizerCallbackManager] Error in preset change subscriber:', error);
98
+ }
99
+ });
100
+ });
101
+ this.isPresetChangeRegistered = true;
102
+ }
103
+ catch (error) {
104
+ console.error('[EqualizerCallbackManager] Failed to register preset change callback:', error);
105
+ }
106
+ }
107
+ }
108
+ // Export singleton instance
109
+ export const equalizerCallbackManager = new EqualizerCallbackSubscriptionManager();
@@ -7,3 +7,19 @@ export { useOnPlaybackProgressChange } from './useOnPlaybackProgressChange';
7
7
  export { useAndroidAutoConnection } from './useAndroidAutoConnection';
8
8
  export { useAudioDevices } from './useAudioDevices';
9
9
  export { useNowPlaying } from './useNowPlaying';
10
+ export { usePlaylist } from './usePlaylist';
11
+ export type { UsePlaylistResult } from './usePlaylist';
12
+ export { useActualQueue } from './useActualQueue';
13
+ export type { UseActualQueueResult } from './useActualQueue';
14
+ export { useDownloadProgress } from './useDownloadProgress';
15
+ export type { UseDownloadProgressOptions, UseDownloadProgressResult, } from './useDownloadProgress';
16
+ export { useDownloadedTracks } from './useDownloadedTracks';
17
+ export type { UseDownloadedTracksResult } from './useDownloadedTracks';
18
+ export { useDownloadActions } from './useDownloadActions';
19
+ export type { UseDownloadActionsResult } from './useDownloadActions';
20
+ export { useDownloadStorage } from './useDownloadStorage';
21
+ export type { UseDownloadStorageResult } from './useDownloadStorage';
22
+ export { useEqualizer } from './useEqualizer';
23
+ export type { UseEqualizerResult } from './useEqualizer';
24
+ export { useEqualizerPresets } from './useEqualizerPresets';
25
+ export type { UseEqualizerPresetsResult } from './useEqualizerPresets';
@@ -5,3 +5,13 @@ export { useOnPlaybackProgressChange } from './useOnPlaybackProgressChange';
5
5
  export { useAndroidAutoConnection } from './useAndroidAutoConnection';
6
6
  export { useAudioDevices } from './useAudioDevices';
7
7
  export { useNowPlaying } from './useNowPlaying';
8
+ export { usePlaylist } from './usePlaylist';
9
+ export { useActualQueue } from './useActualQueue';
10
+ // Download hooks
11
+ export { useDownloadProgress } from './useDownloadProgress';
12
+ export { useDownloadedTracks } from './useDownloadedTracks';
13
+ export { useDownloadActions } from './useDownloadActions';
14
+ export { useDownloadStorage } from './useDownloadStorage';
15
+ // Equalizer hooks
16
+ export { useEqualizer } from './useEqualizer';
17
+ export { useEqualizerPresets } from './useEqualizerPresets';
@@ -0,0 +1,48 @@
1
+ import type { TrackItem } from '../types/PlayerQueue';
2
+ export interface UseActualQueueResult {
3
+ /** The current queue in playback order */
4
+ queue: TrackItem[];
5
+ /** Manually refresh the queue */
6
+ refreshQueue: () => void;
7
+ /** Whether the queue is currently loading */
8
+ isLoading: boolean;
9
+ }
10
+ /**
11
+ * Hook to get the actual playback queue including temporary tracks
12
+ *
13
+ * Returns the complete queue in playback order:
14
+ * [tracks_before_current] + [current] + [playNext_stack] + [upNext_queue] + [remaining_tracks]
15
+ *
16
+ * Auto-updates when:
17
+ * - Track changes
18
+ * - Playback state changes
19
+ *
20
+ * Call `refreshQueue()` after adding tracks via `playNext()` or `addToUpNext()`
21
+ * to immediately see the updated queue.
22
+ *
23
+ * @returns Object containing queue array, refresh function, and loading state
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function QueueView() {
28
+ * const { queue, refreshQueue, isLoading } = useActualQueue();
29
+ *
30
+ * const handleAddToUpNext = (trackId: string) => {
31
+ * TrackPlayer.addToUpNext(trackId);
32
+ * // Refresh queue after adding track
33
+ * setTimeout(refreshQueue, 100);
34
+ * };
35
+ *
36
+ * return (
37
+ * <ScrollView>
38
+ * {queue.map((track, index) => (
39
+ * <Text key={track.id}>
40
+ * {index + 1}. {track.title}
41
+ * </Text>
42
+ * ))}
43
+ * </ScrollView>
44
+ * );
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function useActualQueue(): UseActualQueueResult;