react-native-audio-browser 0.2.0-next.3 → 0.2.0-next.31

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 (989) hide show
  1. package/README.md +36 -22
  2. package/android/build.gradle +35 -12
  3. package/android/gradle.properties +2 -2
  4. package/android/src/main/AndroidManifest.xml +3 -1
  5. package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +541 -278
  6. package/android/src/main/java/com/audiobrowser/AudioBrowserLifecycleModule.kt +38 -0
  7. package/android/src/main/java/com/audiobrowser/AudioBrowserPackage.kt +18 -2
  8. package/android/src/main/java/com/audiobrowser/ServiceBinding.kt +52 -0
  9. package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +315 -213
  10. package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +27 -9
  11. package/android/src/main/java/com/audiobrowser/browser/InertStyleDiagnostic.kt +288 -0
  12. package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +97 -58
  13. package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +70 -29
  14. package/android/src/main/java/com/audiobrowser/browser/StyleResolver.kt +60 -0
  15. package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +20 -7
  16. package/android/src/main/java/com/audiobrowser/extension/TappedTrack.kt +20 -0
  17. package/android/src/main/java/com/audiobrowser/extension/TrackIdentity.kt +15 -0
  18. package/android/src/main/java/com/audiobrowser/http/HttpClient.kt +20 -3
  19. package/android/src/main/java/com/audiobrowser/model/IcyTitle.kt +24 -0
  20. package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +10 -6
  21. package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +12 -12
  22. package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +111 -58
  23. package/android/src/main/java/com/audiobrowser/player/CrossOriginHeaderStripper.kt +77 -0
  24. package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +28 -10
  25. package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +509 -230
  26. package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +218 -252
  27. package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +21 -25
  28. package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +113 -78
  29. package/android/src/main/java/com/audiobrowser/player/Player.kt +81 -38
  30. package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +2 -15
  31. package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +1 -1
  32. package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +2 -1
  33. package/android/src/main/java/com/audiobrowser/player/ShuffleOrderLedBy.kt +30 -0
  34. package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +67 -11
  35. package/android/src/main/java/com/audiobrowser/tls/AiaChasingExtendedTrustManager.kt +168 -0
  36. package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +58 -14
  37. package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +35 -7
  38. package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +278 -59
  39. package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +7 -9
  40. package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +62 -40
  41. package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +28 -23
  42. package/android/src/main/java/com/audiobrowser/util/StyleWire.kt +110 -0
  43. package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +56 -52
  44. package/android/src/main/res/values/strings.xml +25 -5
  45. package/android/src/test/java/com/audiobrowser/ServiceBindingTest.kt +100 -0
  46. package/android/src/test/java/com/audiobrowser/TestFixtures.kt +119 -33
  47. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerFavoritesTest.kt +153 -0
  48. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +15 -0
  49. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +346 -8
  50. package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +40 -2
  51. package/android/src/test/java/com/audiobrowser/browser/InertStyleDiagnosticTest.kt +301 -0
  52. package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +3 -2
  53. package/android/src/test/java/com/audiobrowser/browser/JsonStyleTest.kt +168 -0
  54. package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +128 -55
  55. package/android/src/test/java/com/audiobrowser/browser/StyleResolverTest.kt +160 -0
  56. package/android/src/test/java/com/audiobrowser/extension/TappedTrackTest.kt +43 -0
  57. package/android/src/test/java/com/audiobrowser/extension/TrackIdentityTest.kt +41 -0
  58. package/android/src/test/java/com/audiobrowser/model/IcyTitleTest.kt +49 -0
  59. package/android/src/test/java/com/audiobrowser/player/BrowseTilesTest.kt +385 -0
  60. package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +101 -58
  61. package/android/src/test/java/com/audiobrowser/player/CrossOriginHeaderStripperTest.kt +94 -0
  62. package/android/src/test/java/com/audiobrowser/player/MediaSessionSlotMappingTest.kt +45 -0
  63. package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +42 -2
  64. package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +3 -4
  65. package/android/src/test/java/com/audiobrowser/player/PlaybackStateStoreTrackJsonTest.kt +55 -0
  66. package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +3 -3
  67. package/android/src/test/java/com/audiobrowser/player/ShuffleOrderLedByTest.kt +79 -0
  68. package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +197 -7
  69. package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +325 -4
  70. package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherCallSiteTest.kt +322 -0
  71. package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +83 -0
  72. package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +55 -16
  73. package/android/src/test/java/com/audiobrowser/util/MediaExtrasBuilderTest.kt +162 -0
  74. package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +7 -7
  75. package/ios/AVPlayerEngine.swift +330 -0
  76. package/ios/AVPlayerEngineCallbacks.swift +15 -0
  77. package/ios/Browser/BrowseGate.swift +58 -0
  78. package/ios/Browser/BrowserConfig.swift +117 -78
  79. package/ios/Browser/BrowserManager.swift +209 -603
  80. package/ios/Browser/BrowserPathHelper.swift +50 -46
  81. package/ios/Browser/InertStyleDiagnostic.swift +296 -0
  82. package/ios/Browser/JsonModels.swift +264 -106
  83. package/ios/Browser/NavigationErrorState.swift +41 -0
  84. package/ios/Browser/PageResolver.swift +227 -0
  85. package/ios/Browser/RequestLayer.swift +90 -0
  86. package/ios/Browser/{BrowserManager+URLResolution.swift → RequestPipeline.swift} +193 -121
  87. package/ios/Browser/SearchDrillIn.swift +7 -7
  88. package/ios/Browser/SectionScope.swift +58 -24
  89. package/ios/Browser/StyleResolver.swift +58 -0
  90. package/ios/Browser/TabBarEntries.swift +9 -3
  91. package/ios/Browser/TrackIdTemplate.swift +37 -0
  92. package/ios/CarPlay/CPInterfaceController+Safe.swift +100 -43
  93. package/ios/CarPlay/CarPlayArtworkResolver.swift +36 -83
  94. package/ios/CarPlay/CarPlayController.swift +42 -1296
  95. package/ios/CarPlay/CarPlayImageLoader.swift +78 -97
  96. package/ios/CarPlay/CarPlayListItemFactory.swift +303 -92
  97. package/ios/CarPlay/CarPlayNowPlayingManager.swift +129 -136
  98. package/ios/CarPlay/CarPlaySession+Navigator.swift +114 -0
  99. package/ios/CarPlay/CarPlaySession+PageLoader.swift +92 -0
  100. package/ios/CarPlay/CarPlaySession+Refresher.swift +43 -0
  101. package/ios/CarPlay/CarPlaySession+TabBar.swift +193 -0
  102. package/ios/CarPlay/CarPlaySession.swift +209 -0
  103. package/ios/CarPlay/CarPlayTemplates.swift +63 -0
  104. package/ios/CarPlay/HybridAudioBrowser+IntentFavorite.swift +20 -0
  105. package/ios/{Player → CarPlay}/MediaIntentCriteria.swift +17 -9
  106. package/ios/CarPlay/MediaIntentPlayback.swift +74 -0
  107. package/ios/CarPlay/RNABMediaAddHandler.swift +8 -24
  108. package/ios/CarPlay/RNABMediaAffinityHandler.swift +7 -23
  109. package/ios/CarPlay/RNABMediaIntentHandler.swift +18 -19
  110. package/ios/CarPlay/SectionPresentation.swift +77 -0
  111. package/ios/CarPlay/TopTemplateReplacer.swift +96 -0
  112. package/ios/Extension/Capability+RemoteCommand.swift +1 -1
  113. package/ios/Extension/NavigationError+Conversion.swift +14 -4
  114. package/ios/Extension/PlayerCapabilities+Favorite.swift +1 -15
  115. package/ios/Extension/ResolvedTrack+Copying.swift +13 -15
  116. package/ios/Extension/Section+Copying.swift +29 -0
  117. package/ios/Extension/String+IcyCharset.swift +21 -0
  118. package/ios/Extension/TimedMetadata+AVFoundation.swift +6 -4
  119. package/ios/Extension/Track+Copying.swift +8 -12
  120. package/ios/Extension/Track+Identity.swift +18 -0
  121. package/ios/Extension/UIApplication+ActiveScene.swift +27 -0
  122. package/ios/Extension/UIImage+Adaptive.swift +12 -0
  123. package/ios/Extension/URLError+Connectivity.swift +15 -0
  124. package/ios/Http/HttpClient.swift +66 -142
  125. package/ios/HybridAudioBrowser+Browser.swift +153 -0
  126. package/ios/HybridAudioBrowser+Options.swift +144 -0
  127. package/ios/HybridAudioBrowser+Player.swift +397 -0
  128. package/ios/HybridAudioBrowser+PlayerCallbacks.swift +189 -0
  129. package/ios/HybridAudioBrowser+Stubs.swift +46 -0
  130. package/ios/HybridAudioBrowser.swift +153 -1610
  131. package/ios/Model/NitroTypeStubs.swift +146 -24
  132. package/ios/Model/PlayerUpdateOptions.swift +8 -1
  133. package/ios/Model/RemoteCommand.swift +18 -0
  134. package/ios/Model/TrackPlayerError.swift +2 -2
  135. package/ios/NowPlayingInfo/NowPlayingInfoController.swift +18 -53
  136. package/ios/Observer/ItemObserver.swift +90 -0
  137. package/ios/Observer/PlayerObserver.swift +59 -0
  138. package/ios/Option/SessionCategories.swift +42 -92
  139. package/ios/Player/AudioSessionController.swift +189 -0
  140. package/ios/Player/DeferredSeek.swift +70 -0
  141. package/ios/Player/ErrorStatus.swift +27 -0
  142. package/ios/Player/MediaLoader.swift +62 -35
  143. package/ios/Player/NowPlayingUpdater.swift +197 -50
  144. package/ios/Player/PlaybackFailure.swift +125 -0
  145. package/ios/Player/PlaybackPersistence.swift +73 -0
  146. package/ios/Player/PlaybackTimer.swift +8 -2
  147. package/ios/Player/Player.swift +1078 -0
  148. package/ios/Player/{PlaybackCoordinatorCallbacks.swift → PlayerCallbacks.swift} +3 -4
  149. package/ios/Player/PlayerEngine.swift +87 -0
  150. package/ios/Player/PlayerStatusTypes.swift +2 -6
  151. package/ios/Player/QueueManager.swift +93 -67
  152. package/ios/Player/RetryLoop.swift +261 -0
  153. package/ios/Player/ShuffleOrder.swift +33 -0
  154. package/ios/Player/SleepTimerManager.swift +1 -1
  155. package/ios/RemoteCommand/RemoteCommandCallbacks.swift +46 -0
  156. package/ios/RemoteCommand/RemoteCommandController.swift +87 -331
  157. package/ios/Tests/BrowserPathHelperTests.swift +56 -15
  158. package/ios/Tests/CarPlayArtworkResolverTests.swift +60 -373
  159. package/ios/Tests/DeferredSeekTests.swift +70 -0
  160. package/ios/Tests/EmitterTests.swift +29 -0
  161. package/ios/Tests/GenerationMemoTests.swift +121 -0
  162. package/ios/Tests/InertStyleDiagnosticTests.swift +209 -0
  163. package/ios/Tests/JsonModelsTests.swift +164 -1
  164. package/ios/Tests/LRUCacheTests.swift +110 -0
  165. package/ios/Tests/MediaIntentCriteriaTests.swift +2 -2
  166. package/ios/Tests/MediaLoaderTests.swift +12 -48
  167. package/ios/Tests/ObserverTests.swift +88 -0
  168. package/ios/Tests/PlaybackErrorTests.swift +76 -0
  169. package/ios/Tests/PlaybackFailureTests.swift +189 -0
  170. package/ios/Tests/PlaybackPersistenceTests.swift +93 -0
  171. package/ios/Tests/PlayerPolicyTests.swift +420 -0
  172. package/ios/Tests/{PlaybackCoordinatorTests.swift → PlayerTests.swift} +300 -248
  173. package/ios/Tests/PlayingStateTests.swift +42 -0
  174. package/ios/Tests/QueueManagerTests.swift +196 -115
  175. package/ios/Tests/ReadyValueTests.swift +73 -0
  176. package/ios/Tests/RemoteCommandControllerTests.swift +152 -0
  177. package/ios/Tests/RemoteCommandTests.swift +65 -0
  178. package/ios/Tests/RequestLayerTests.swift +112 -0
  179. package/ios/Tests/ResolvedTrackCopyingTests.swift +39 -35
  180. package/ios/Tests/RetryLoopTests.swift +270 -0
  181. package/ios/Tests/SearchDrillInTests.swift +16 -16
  182. package/ios/Tests/SectionPresentationTests.swift +98 -0
  183. package/ios/Tests/SectionScopeTests.swift +87 -55
  184. package/ios/Tests/StyleResolverTests.swift +132 -0
  185. package/ios/Tests/Support/TestTypes.swift +108 -104
  186. package/ios/Tests/TabBarEntriesTests.swift +19 -19
  187. package/ios/Tests/TimedMetadataAVFoundationTests.swift +42 -0
  188. package/ios/Tests/TopTemplateReplacerTests.swift +172 -0
  189. package/ios/Tests/TrackIdTemplateTests.swift +67 -0
  190. package/ios/Tests/TrackIdentityTests.swift +20 -0
  191. package/ios/Tests/TrackSelectorTests.swift +168 -33
  192. package/ios/Tests/URLErrorConnectivityTests.swift +20 -0
  193. package/ios/TrackSelector.swift +46 -31
  194. package/ios/Util/ArtworkImageFetcher.swift +58 -1
  195. package/ios/Util/Emitter.swift +42 -0
  196. package/ios/Util/GenerationMemo.swift +36 -0
  197. package/ios/Util/LRUCache.swift +23 -159
  198. package/ios/Util/NetworkMonitor.swift +43 -26
  199. package/ios/Util/ReadyValue.swift +56 -0
  200. package/ios/Util/SFSymbolRenderer.swift +59 -31
  201. package/ios/Util/SVGProcessor.swift +9 -12
  202. package/lib/commonjs/AudioBrowser.js +8 -8
  203. package/lib/commonjs/AudioBrowser.js.map +1 -1
  204. package/lib/commonjs/CLAUDE.md +52 -0
  205. package/lib/commonjs/features/browser-config.js +12 -8
  206. package/lib/commonjs/features/browser-config.js.map +1 -1
  207. package/lib/commonjs/features/browser.js +11 -3
  208. package/lib/commonjs/features/browser.js.map +1 -1
  209. package/lib/commonjs/features/carConnection.js +1 -1
  210. package/lib/commonjs/features/equalizer.js +1 -1
  211. package/lib/commonjs/features/errors.js +3 -3
  212. package/lib/commonjs/features/favorites.js +14 -11
  213. package/lib/commonjs/features/favorites.js.map +1 -1
  214. package/lib/commonjs/features/gate.js +16 -1
  215. package/lib/commonjs/features/gate.js.map +1 -1
  216. package/lib/commonjs/features/metadata.js +20 -3
  217. package/lib/commonjs/features/metadata.js.map +1 -1
  218. package/lib/commonjs/features/network.js +1 -1
  219. package/lib/commonjs/features/nowPlaying.js +1 -1
  220. package/lib/commonjs/features/output.js +1 -1
  221. package/lib/commonjs/features/playback/controls.js +4 -2
  222. package/lib/commonjs/features/playback/controls.js.map +1 -1
  223. package/lib/commonjs/features/playback/playWhenReady.js +1 -1
  224. package/lib/commonjs/features/playback/playing.js +1 -1
  225. package/lib/commonjs/features/playback/progress.js +3 -2
  226. package/lib/commonjs/features/playback/progress.js.map +1 -1
  227. package/lib/commonjs/features/playback/rate.js +8 -1
  228. package/lib/commonjs/features/playback/rate.js.map +1 -1
  229. package/lib/commonjs/features/playback/state.js +3 -4
  230. package/lib/commonjs/features/playback/state.js.map +1 -1
  231. package/lib/commonjs/features/playback/trackPlaybackTime.js +0 -6
  232. package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -1
  233. package/lib/commonjs/features/playback/volume.js +1 -1
  234. package/lib/commonjs/features/player/options.js +48 -34
  235. package/lib/commonjs/features/player/options.js.map +1 -1
  236. package/lib/commonjs/features/player/setup.js +18 -9
  237. package/lib/commonjs/features/player/setup.js.map +1 -1
  238. package/lib/commonjs/features/player/validateOptions.js +23 -0
  239. package/lib/commonjs/features/player/validateOptions.js.map +1 -0
  240. package/lib/commonjs/features/queue/activeTrack.js +15 -4
  241. package/lib/commonjs/features/queue/activeTrack.js.map +1 -1
  242. package/lib/commonjs/features/queue/queue.js +13 -6
  243. package/lib/commonjs/features/queue/queue.js.map +1 -1
  244. package/lib/commonjs/features/queue/repeatMode.js +1 -1
  245. package/lib/commonjs/features/queue/shuffle.js +1 -1
  246. package/lib/commonjs/features/remoteControls.js +13 -92
  247. package/lib/commonjs/features/remoteControls.js.map +1 -1
  248. package/lib/commonjs/features/sleepTimer.js +13 -1
  249. package/lib/commonjs/features/sleepTimer.js.map +1 -1
  250. package/lib/commonjs/test-utils/reactNativeStub.js +65 -0
  251. package/lib/commonjs/test-utils/reactNativeStub.js.map +1 -0
  252. package/lib/commonjs/utils/LazyNativeEmitter.js +28 -14
  253. package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
  254. package/lib/commonjs/utils/NativeUpdatedValue.js +31 -13
  255. package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
  256. package/lib/commonjs/utils/getTrackIdentity.js +24 -0
  257. package/lib/commonjs/utils/getTrackIdentity.js.map +1 -0
  258. package/lib/commonjs/utils/useNativeValueRefreshedBy.js +33 -0
  259. package/lib/commonjs/utils/useNativeValueRefreshedBy.js.map +1 -0
  260. package/lib/commonjs/web/NativeAudioBrowser.js +201 -76
  261. package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
  262. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js +37 -0
  263. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js.map +1 -0
  264. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  265. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  266. package/lib/commonjs/web/TrackPlayer/Player.js +254 -39
  267. package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
  268. package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +1 -1
  269. package/lib/commonjs/web/TrackPlayer/QueueManager.js +14 -0
  270. package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -1
  271. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +33 -12
  272. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -1
  273. package/lib/commonjs/web/browser/BrowserManager.js +175 -100
  274. package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
  275. package/lib/commonjs/web/browser/FavoriteManager.js +30 -21
  276. package/lib/commonjs/web/browser/FavoriteManager.js.map +1 -1
  277. package/lib/commonjs/web/browser/NavigationErrorManager.js +3 -1
  278. package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
  279. package/lib/commonjs/web/browser/SearchManager.js +18 -23
  280. package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
  281. package/lib/commonjs/web/browser/assertBrowsePageShape.js +2 -2
  282. package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -1
  283. package/lib/commonjs/web/browser/classifyTrackNavigation.js +9 -9
  284. package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -1
  285. package/lib/commonjs/web/browser/sections.js +89 -0
  286. package/lib/commonjs/web/browser/sections.js.map +1 -0
  287. package/lib/commonjs/web/http/RequestConfigBuilder.js +110 -27
  288. package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
  289. package/lib/commonjs/web/http/followMediaRedirect.js +219 -0
  290. package/lib/commonjs/web/http/followMediaRedirect.js.map +1 -0
  291. package/lib/commonjs/web/player/NowPlayingManager.js +4 -3
  292. package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
  293. package/lib/commonjs/web/util/BrowserPathHelper.js +62 -11
  294. package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -1
  295. package/lib/module/AudioBrowser.js +2 -1
  296. package/lib/module/AudioBrowser.js.map +1 -1
  297. package/lib/module/CLAUDE.md +52 -0
  298. package/lib/module/features/browser-config.js +12 -8
  299. package/lib/module/features/browser-config.js.map +1 -1
  300. package/lib/module/features/browser.js +11 -3
  301. package/lib/module/features/browser.js.map +1 -1
  302. package/lib/module/features/carConnection.js +1 -1
  303. package/lib/module/features/equalizer.js +1 -1
  304. package/lib/module/features/errors.js +3 -3
  305. package/lib/module/features/favorites.js +14 -11
  306. package/lib/module/features/favorites.js.map +1 -1
  307. package/lib/module/features/gate.js +16 -1
  308. package/lib/module/features/gate.js.map +1 -1
  309. package/lib/module/features/metadata.js +20 -3
  310. package/lib/module/features/metadata.js.map +1 -1
  311. package/lib/module/features/network.js +1 -1
  312. package/lib/module/features/nowPlaying.js +1 -1
  313. package/lib/module/features/output.js +1 -1
  314. package/lib/module/features/playback/controls.js +4 -2
  315. package/lib/module/features/playback/controls.js.map +1 -1
  316. package/lib/module/features/playback/playWhenReady.js +1 -1
  317. package/lib/module/features/playback/playing.js +1 -1
  318. package/lib/module/features/playback/progress.js +3 -2
  319. package/lib/module/features/playback/progress.js.map +1 -1
  320. package/lib/module/features/playback/rate.js +8 -1
  321. package/lib/module/features/playback/rate.js.map +1 -1
  322. package/lib/module/features/playback/state.js +3 -4
  323. package/lib/module/features/playback/state.js.map +1 -1
  324. package/lib/module/features/playback/trackPlaybackTime.js +0 -5
  325. package/lib/module/features/playback/trackPlaybackTime.js.map +1 -1
  326. package/lib/module/features/playback/volume.js +1 -1
  327. package/lib/module/features/player/options.js +47 -32
  328. package/lib/module/features/player/options.js.map +1 -1
  329. package/lib/module/features/player/setup.js +17 -8
  330. package/lib/module/features/player/setup.js.map +1 -1
  331. package/lib/module/features/player/validateOptions.js +19 -0
  332. package/lib/module/features/player/validateOptions.js.map +1 -0
  333. package/lib/module/features/queue/activeTrack.js +15 -4
  334. package/lib/module/features/queue/activeTrack.js.map +1 -1
  335. package/lib/module/features/queue/queue.js +13 -6
  336. package/lib/module/features/queue/queue.js.map +1 -1
  337. package/lib/module/features/queue/repeatMode.js +1 -1
  338. package/lib/module/features/queue/shuffle.js +1 -1
  339. package/lib/module/features/remoteControls.js +13 -92
  340. package/lib/module/features/remoteControls.js.map +1 -1
  341. package/lib/module/features/sleepTimer.js +13 -1
  342. package/lib/module/features/sleepTimer.js.map +1 -1
  343. package/lib/module/test-utils/reactNativeStub.js +58 -0
  344. package/lib/module/test-utils/reactNativeStub.js.map +1 -0
  345. package/lib/module/utils/LazyNativeEmitter.js +28 -14
  346. package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
  347. package/lib/module/utils/NativeUpdatedValue.js +31 -13
  348. package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
  349. package/lib/module/utils/getTrackIdentity.js +20 -0
  350. package/lib/module/utils/getTrackIdentity.js.map +1 -0
  351. package/lib/module/utils/useNativeValueRefreshedBy.js +29 -0
  352. package/lib/module/utils/useNativeValueRefreshedBy.js.map +1 -0
  353. package/lib/module/web/NativeAudioBrowser.js +201 -76
  354. package/lib/module/web/NativeAudioBrowser.js.map +1 -1
  355. package/lib/module/web/TrackPlayer/LoadAttempt.js +32 -0
  356. package/lib/module/web/TrackPlayer/LoadAttempt.js.map +1 -0
  357. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  358. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  359. package/lib/module/web/TrackPlayer/Player.js +254 -39
  360. package/lib/module/web/TrackPlayer/Player.js.map +1 -1
  361. package/lib/module/web/TrackPlayer/PlayingStateFactory.js +1 -1
  362. package/lib/module/web/TrackPlayer/QueueManager.js +14 -0
  363. package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -1
  364. package/lib/module/web/TrackPlayer/QueuePlayer.js +33 -12
  365. package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -1
  366. package/lib/module/web/browser/BrowserManager.js +175 -100
  367. package/lib/module/web/browser/BrowserManager.js.map +1 -1
  368. package/lib/module/web/browser/FavoriteManager.js +31 -21
  369. package/lib/module/web/browser/FavoriteManager.js.map +1 -1
  370. package/lib/module/web/browser/NavigationErrorManager.js +3 -1
  371. package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
  372. package/lib/module/web/browser/SearchManager.js +18 -23
  373. package/lib/module/web/browser/SearchManager.js.map +1 -1
  374. package/lib/module/web/browser/assertBrowsePageShape.js +2 -2
  375. package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -1
  376. package/lib/module/web/browser/classifyTrackNavigation.js +9 -9
  377. package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -1
  378. package/lib/module/web/browser/sections.js +83 -0
  379. package/lib/module/web/browser/sections.js.map +1 -0
  380. package/lib/module/web/http/RequestConfigBuilder.js +110 -27
  381. package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
  382. package/lib/module/web/http/followMediaRedirect.js +215 -0
  383. package/lib/module/web/http/followMediaRedirect.js.map +1 -0
  384. package/lib/module/web/player/NowPlayingManager.js +4 -3
  385. package/lib/module/web/player/NowPlayingManager.js.map +1 -1
  386. package/lib/module/web/util/BrowserPathHelper.js +62 -11
  387. package/lib/module/web/util/BrowserPathHelper.js.map +1 -1
  388. package/lib/typescript/package.json +1 -0
  389. package/lib/typescript/src/AudioBrowser.d.ts +1 -1
  390. package/lib/typescript/src/AudioBrowser.d.ts.map +1 -1
  391. package/lib/typescript/src/features/browser-config.d.ts.map +1 -1
  392. package/lib/typescript/src/features/browser.d.ts +10 -2
  393. package/lib/typescript/src/features/browser.d.ts.map +1 -1
  394. package/lib/typescript/src/features/carConnection.d.ts +1 -1
  395. package/lib/typescript/src/features/equalizer.d.ts +1 -1
  396. package/lib/typescript/src/features/errors.d.ts +3 -3
  397. package/lib/typescript/src/features/favorites.d.ts +14 -11
  398. package/lib/typescript/src/features/favorites.d.ts.map +1 -1
  399. package/lib/typescript/src/features/gate.d.ts +18 -2
  400. package/lib/typescript/src/features/gate.d.ts.map +1 -1
  401. package/lib/typescript/src/features/metadata.d.ts +20 -3
  402. package/lib/typescript/src/features/metadata.d.ts.map +1 -1
  403. package/lib/typescript/src/features/network.d.ts +1 -1
  404. package/lib/typescript/src/features/nowPlaying.d.ts +1 -1
  405. package/lib/typescript/src/features/output.d.ts +1 -1
  406. package/lib/typescript/src/features/playback/controls.d.ts +4 -2
  407. package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
  408. package/lib/typescript/src/features/playback/playWhenReady.d.ts +1 -1
  409. package/lib/typescript/src/features/playback/playing.d.ts +1 -1
  410. package/lib/typescript/src/features/playback/progress.d.ts +1 -1
  411. package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
  412. package/lib/typescript/src/features/playback/rate.d.ts +8 -1
  413. package/lib/typescript/src/features/playback/rate.d.ts.map +1 -1
  414. package/lib/typescript/src/features/playback/state.d.ts +3 -4
  415. package/lib/typescript/src/features/playback/state.d.ts.map +1 -1
  416. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +1 -1
  417. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -1
  418. package/lib/typescript/src/features/playback/volume.d.ts +1 -1
  419. package/lib/typescript/src/features/player/options.d.ts +108 -56
  420. package/lib/typescript/src/features/player/options.d.ts.map +1 -1
  421. package/lib/typescript/src/features/player/setup.d.ts +14 -4
  422. package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
  423. package/lib/typescript/src/features/player/validateOptions.d.ts +2 -0
  424. package/lib/typescript/src/features/player/validateOptions.d.ts.map +1 -0
  425. package/lib/typescript/src/features/queue/activeTrack.d.ts +9 -2
  426. package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -1
  427. package/lib/typescript/src/features/queue/queue.d.ts +7 -4
  428. package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
  429. package/lib/typescript/src/features/queue/repeatMode.d.ts +1 -1
  430. package/lib/typescript/src/features/queue/shuffle.d.ts +1 -1
  431. package/lib/typescript/src/features/remoteControls.d.ts +23 -22
  432. package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
  433. package/lib/typescript/src/features/sleepTimer.d.ts +1 -1
  434. package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
  435. package/lib/typescript/src/test-utils/reactNativeStub.d.ts +36 -0
  436. package/lib/typescript/src/test-utils/reactNativeStub.d.ts.map +1 -0
  437. package/lib/typescript/src/types/browser-native.d.ts +3 -2
  438. package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
  439. package/lib/typescript/src/types/browser-nodes.d.ts +387 -126
  440. package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
  441. package/lib/typescript/src/types/browser.d.ts +93 -61
  442. package/lib/typescript/src/types/browser.d.ts.map +1 -1
  443. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +19 -16
  444. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
  445. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +24 -19
  446. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
  447. package/lib/typescript/src/utils/getTrackIdentity.d.ts +18 -0
  448. package/lib/typescript/src/utils/getTrackIdentity.d.ts.map +1 -0
  449. package/lib/typescript/src/utils/resolveAssetSource.d.ts +1 -2
  450. package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
  451. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts +21 -0
  452. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts.map +1 -0
  453. package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +1 -2
  454. package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +4 -2
  455. package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +2 -2
  456. package/nitrogen/generated/android/c++/JAndroidAudioOffloadSettings.hpp +2 -2
  457. package/nitrogen/generated/android/c++/JAndroidOptions.hpp +12 -12
  458. package/nitrogen/generated/android/c++/JAndroidPlayerWakeMode.hpp +2 -2
  459. package/nitrogen/generated/android/c++/JAppKilledPlaybackBehavior.hpp +2 -2
  460. package/nitrogen/generated/android/c++/JArtworkRendering.hpp +58 -0
  461. package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +10 -5
  462. package/nitrogen/generated/android/c++/JArtworkVariants.hpp +2 -2
  463. package/nitrogen/generated/android/c++/JBatteryOptimizationStatus.hpp +2 -2
  464. package/nitrogen/generated/android/c++/JBatteryOptimizationStatusChangedEvent.hpp +2 -2
  465. package/nitrogen/generated/android/c++/JBatteryWarningPendingChangedEvent.hpp +2 -2
  466. package/nitrogen/generated/android/c++/JBrowseError.hpp +2 -2
  467. package/nitrogen/generated/android/c++/JBrowseResult.hpp +19 -7
  468. package/nitrogen/generated/android/c++/JBrowserSourceCallbackParam.hpp +2 -2
  469. package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +2 -2
  470. package/nitrogen/generated/android/c++/JCarPlayPlayingIndicatorLocation.hpp +58 -0
  471. package/nitrogen/generated/android/c++/JCarPlaySiriListButtonPosition.hpp +2 -2
  472. package/nitrogen/generated/android/c++/JCardImage.hpp +58 -0
  473. package/nitrogen/generated/android/c++/JChapterMetadata.hpp +2 -2
  474. package/nitrogen/generated/android/c++/JEqualizerSettings.hpp +10 -10
  475. package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +10 -5
  476. package/nitrogen/generated/android/c++/JFormatNavigationErrorParams.hpp +11 -5
  477. package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +10 -5
  478. package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +2 -2
  479. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +2 -2
  480. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +9 -9
  481. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +10 -5
  482. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.hpp +4 -2
  483. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +10 -5
  484. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +10 -5
  485. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +2 -2
  486. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.hpp +2 -2
  487. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +9 -9
  488. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +10 -5
  489. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +2 -2
  490. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +18 -12
  491. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +10 -4
  492. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__string__.hpp +102 -0
  493. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +18 -6
  494. package/nitrogen/generated/android/c++/JFunc_void.hpp +2 -2
  495. package/nitrogen/generated/android/c++/JFunc_void_BatteryOptimizationStatusChangedEvent.hpp +2 -2
  496. package/nitrogen/generated/android/c++/JFunc_void_BatteryWarningPendingChangedEvent.hpp +2 -2
  497. package/nitrogen/generated/android/c++/JFunc_void_EqualizerSettings.hpp +2 -2
  498. package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +10 -5
  499. package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +2 -2
  500. package/nitrogen/generated/android/c++/JFunc_void_NavigationErrorEvent.hpp +2 -2
  501. package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +2 -2
  502. package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -12
  503. package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +2 -2
  504. package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -2
  505. package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +10 -5
  506. package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -2
  507. package/nitrogen/generated/android/c++/JFunc_void_PlaybackPlayWhenReadyChangedEvent.hpp +2 -2
  508. package/nitrogen/generated/android/c++/JFunc_void_PlaybackProgressUpdatedEvent.hpp +2 -2
  509. package/nitrogen/generated/android/c++/JFunc_void_PlaybackQueueEndedEvent.hpp +2 -2
  510. package/nitrogen/generated/android/c++/JFunc_void_PlayingState.hpp +2 -2
  511. package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpBackwardEvent.hpp +2 -2
  512. package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpForwardEvent.hpp +2 -2
  513. package/nitrogen/generated/android/c++/JFunc_void_RemotePlayIdEvent.hpp +2 -2
  514. package/nitrogen/generated/android/c++/JFunc_void_RemotePlaySearchEvent.hpp +2 -2
  515. package/nitrogen/generated/android/c++/JFunc_void_RemoteSeekEvent.hpp +2 -2
  516. package/nitrogen/generated/android/c++/JFunc_void_RemoteSkipEvent.hpp +2 -2
  517. package/nitrogen/generated/android/c++/JFunc_void_RepeatModeChangedEvent.hpp +2 -2
  518. package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +2 -2
  519. package/nitrogen/generated/android/c++/JFunc_void_TrackMetadata.hpp +2 -2
  520. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +2 -2
  521. package/nitrogen/generated/android/c++/JFunc_void_double.hpp +2 -2
  522. package/nitrogen/generated/android/c++/JFunc_void_std__optional_FormattedNavigationError_.hpp +2 -2
  523. package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +17 -5
  524. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.hpp +2 -2
  525. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +2 -2
  526. package/nitrogen/generated/android/c++/JFunc_void_std__vector_ChapterMetadata_.hpp +16 -16
  527. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +24 -18
  528. package/nitrogen/generated/android/c++/JGate.hpp +2 -2
  529. package/nitrogen/generated/android/c++/JGateDecision.hpp +2 -2
  530. package/nitrogen/generated/android/c++/JGateEvent.hpp +2 -2
  531. package/nitrogen/generated/android/c++/JGateReason.hpp +2 -2
  532. package/nitrogen/generated/android/c++/JGridTile.hpp +64 -0
  533. package/nitrogen/generated/android/c++/JHttpMethod.hpp +2 -2
  534. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +77 -53
  535. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +3 -3
  536. package/nitrogen/generated/android/c++/JIOSCategory.hpp +2 -2
  537. package/nitrogen/generated/android/c++/JIOSCategoryMode.hpp +2 -2
  538. package/nitrogen/generated/android/c++/JIOSCategoryOptions.hpp +2 -2
  539. package/nitrogen/generated/android/c++/JIOSCategoryPolicy.hpp +2 -2
  540. package/nitrogen/generated/android/c++/JIOSOptions.hpp +17 -11
  541. package/nitrogen/generated/android/c++/JImageContext.hpp +2 -2
  542. package/nitrogen/generated/android/c++/JImageQueryParams.hpp +2 -2
  543. package/nitrogen/generated/android/c++/JImageShape.hpp +58 -0
  544. package/nitrogen/generated/android/c++/JImageSource.hpp +2 -2
  545. package/nitrogen/generated/android/c++/JMediaReference.hpp +2 -2
  546. package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +10 -5
  547. package/nitrogen/generated/android/c++/JMediaTransformParams.hpp +2 -2
  548. package/nitrogen/generated/android/c++/JNativeAndroidSetupOptions.hpp +2 -2
  549. package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +48 -21
  550. package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +2 -2
  551. package/nitrogen/generated/android/c++/JNativeIOSSetupOptions.hpp +10 -10
  552. package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +16 -4
  553. package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +17 -14
  554. package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +9 -12
  555. package/nitrogen/generated/android/c++/JNavigationError.hpp +2 -2
  556. package/nitrogen/generated/android/c++/JNavigationErrorEvent.hpp +2 -2
  557. package/nitrogen/generated/android/c++/JNavigationErrorKind.hpp +58 -0
  558. package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +2 -2
  559. package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +12 -12
  560. package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +17 -11
  561. package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +2 -2
  562. package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +2 -2
  563. package/nitrogen/generated/android/c++/JOptions.hpp +9 -12
  564. package/nitrogen/generated/android/c++/JOutput.hpp +2 -2
  565. package/nitrogen/generated/android/c++/JOutputType.hpp +2 -2
  566. package/nitrogen/generated/android/c++/JPlayback.hpp +2 -2
  567. package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +10 -5
  568. package/nitrogen/generated/android/c++/JPlaybackError.hpp +2 -2
  569. package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -2
  570. package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +2 -2
  571. package/nitrogen/generated/android/c++/JPlaybackPlayWhenReadyChangedEvent.hpp +2 -2
  572. package/nitrogen/generated/android/c++/JPlaybackProgressUpdatedEvent.hpp +2 -2
  573. package/nitrogen/generated/android/c++/JPlaybackQueueEndedEvent.hpp +2 -2
  574. package/nitrogen/generated/android/c++/JPlaybackState.hpp +2 -2
  575. package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +7 -13
  576. package/nitrogen/generated/android/c++/JPlayingState.hpp +2 -2
  577. package/nitrogen/generated/android/c++/JProgress.hpp +2 -2
  578. package/nitrogen/generated/android/c++/{JNotificationButton.hpp → JRemoteButton.hpp} +19 -19
  579. package/nitrogen/generated/android/c++/JRemoteButtonLayout.hpp +86 -0
  580. package/nitrogen/generated/android/c++/JRemoteJumpBackwardEvent.hpp +2 -2
  581. package/nitrogen/generated/android/c++/JRemoteJumpForwardEvent.hpp +2 -2
  582. package/nitrogen/generated/android/c++/JRemotePlayIdEvent.hpp +2 -2
  583. package/nitrogen/generated/android/c++/JRemotePlaySearchEvent.hpp +2 -2
  584. package/nitrogen/generated/android/c++/JRemoteSeekEvent.hpp +2 -2
  585. package/nitrogen/generated/android/c++/JRemoteSkipEvent.hpp +2 -2
  586. package/nitrogen/generated/android/c++/JRepeatMode.hpp +2 -2
  587. package/nitrogen/generated/android/c++/JRepeatModeChangedEvent.hpp +2 -2
  588. package/nitrogen/generated/android/c++/JRequestConfig.hpp +2 -2
  589. package/nitrogen/generated/android/c++/JResolvedTrack.hpp +67 -59
  590. package/nitrogen/generated/android/c++/JRetryConfig.hpp +2 -2
  591. package/nitrogen/generated/android/c++/JSearchMode.hpp +2 -2
  592. package/nitrogen/generated/android/c++/JSearchParams.hpp +2 -2
  593. package/nitrogen/generated/android/c++/JSection.hpp +116 -0
  594. package/nitrogen/generated/android/c++/JSectionStyle.hpp +96 -0
  595. package/nitrogen/generated/android/c++/JSleepTimer.hpp +4 -4
  596. package/nitrogen/generated/android/c++/JSleepTimerEndOfTrack.hpp +2 -2
  597. package/nitrogen/generated/android/c++/JSleepTimerTime.hpp +2 -2
  598. package/nitrogen/generated/android/c++/JStallReason.hpp +2 -2
  599. package/nitrogen/generated/android/c++/JStyleDisplay.hpp +58 -0
  600. package/nitrogen/generated/android/c++/JTimedMetadata.hpp +2 -2
  601. package/nitrogen/generated/android/c++/JTrack.hpp +27 -48
  602. package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +18 -12
  603. package/nitrogen/generated/android/c++/JTrackMetadata.hpp +2 -2
  604. package/nitrogen/generated/android/c++/JTrackRequest.hpp +2 -2
  605. package/nitrogen/generated/android/c++/JTrackStyle.hpp +47 -19
  606. package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +2 -2
  607. package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.hpp +3 -3
  608. package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.hpp +3 -3
  609. package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +3 -3
  610. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.cpp +26 -0
  611. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.hpp +75 -0
  612. package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +20 -8
  613. package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +3 -3
  614. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioOffloadSettings.kt +15 -0
  615. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +20 -3
  616. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoritesMatchMode.kt → ArtworkRendering.kt} +5 -5
  617. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +37 -0
  618. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +15 -0
  619. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatusChangedEvent.kt +13 -0
  620. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryWarningPendingChangedEvent.kt +13 -0
  621. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseError.kt +13 -0
  622. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseResult.kt +16 -7
  623. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowserSourceCallbackParam.kt +15 -0
  624. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayPlayingIndicatorLocation.kt +23 -0
  625. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CardImage.kt +23 -0
  626. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ChapterMetadata.kt +19 -0
  627. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/EqualizerSettings.kt +27 -0
  628. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteChangedEvent.kt +15 -0
  629. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNavigationErrorParams.kt +25 -3
  630. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +21 -0
  631. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +15 -0
  632. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +0 -2
  633. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +0 -2
  634. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +0 -2
  635. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.kt +0 -2
  636. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +0 -2
  637. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +0 -2
  638. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +0 -2
  639. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.kt +0 -2
  640. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +0 -2
  641. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.kt +0 -2
  642. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +0 -2
  643. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.kt +0 -2
  644. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.kt +0 -2
  645. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__string__.kt +78 -0
  646. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt +0 -2
  647. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void.kt +0 -2
  648. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryOptimizationStatusChangedEvent.kt +0 -2
  649. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryWarningPendingChangedEvent.kt +0 -2
  650. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_EqualizerSettings.kt +0 -2
  651. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_FavoriteChangedEvent.kt +0 -2
  652. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_GateEvent.kt +0 -2
  653. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NavigationErrorEvent.kt +0 -2
  654. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NowPlayingMetadata.kt +0 -2
  655. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Options.kt +0 -2
  656. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Output.kt +0 -2
  657. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Playback.kt +0 -2
  658. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackActiveTrackChangedEvent.kt +0 -2
  659. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackErrorEvent.kt +0 -2
  660. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackPlayWhenReadyChangedEvent.kt +0 -2
  661. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackProgressUpdatedEvent.kt +0 -2
  662. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackQueueEndedEvent.kt +0 -2
  663. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlayingState.kt +0 -2
  664. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpBackwardEvent.kt +0 -2
  665. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpForwardEvent.kt +0 -2
  666. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlayIdEvent.kt +0 -2
  667. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlaySearchEvent.kt +0 -2
  668. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSeekEvent.kt +0 -2
  669. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSkipEvent.kt +0 -2
  670. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RepeatModeChangedEvent.kt +0 -2
  671. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TimedMetadata.kt +0 -2
  672. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TrackMetadata.kt +0 -2
  673. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +0 -2
  674. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_double.kt +0 -2
  675. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_FormattedNavigationError_.kt +0 -2
  676. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_ResolvedTrack_.kt +0 -2
  677. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.kt +0 -2
  678. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__string.kt +0 -2
  679. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_ChapterMetadata_.kt +0 -2
  680. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_Track_.kt +0 -2
  681. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Gate.kt +15 -0
  682. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateDecision.kt +15 -0
  683. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateEvent.kt +13 -0
  684. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GridTile.kt +25 -0
  685. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +3 -1
  686. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +25 -3
  687. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageContext.kt +15 -0
  688. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageQueryParams.kt +15 -0
  689. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageShape.kt +23 -0
  690. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageSource.kt +19 -0
  691. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +35 -0
  692. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaTransformParams.kt +15 -0
  693. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeAndroidSetupOptions.kt +31 -0
  694. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +51 -5
  695. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeGateRequest.kt +17 -0
  696. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeIOSSetupOptions.kt +21 -0
  697. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +27 -0
  698. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +29 -0
  699. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +23 -0
  700. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationError.kt +19 -0
  701. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorEvent.kt +13 -0
  702. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorKind.kt +23 -0
  703. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +20 -3
  704. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +25 -3
  705. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +29 -0
  706. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +17 -0
  707. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +23 -0
  708. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Output.kt +17 -0
  709. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Playback.kt +15 -0
  710. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackActiveTrackChangedEvent.kt +21 -0
  711. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +21 -0
  712. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorEvent.kt +13 -0
  713. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackPlayWhenReadyChangedEvent.kt +13 -0
  714. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackProgressUpdatedEvent.kt +19 -0
  715. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackQueueEndedEvent.kt +15 -0
  716. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +37 -2
  717. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayingState.kt +15 -0
  718. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Progress.kt +17 -0
  719. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NotificationButton.kt → RemoteButton.kt} +3 -3
  720. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButtonLayout.kt +61 -0
  721. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpBackwardEvent.kt +13 -0
  722. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpForwardEvent.kt +13 -0
  723. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlayIdEvent.kt +15 -0
  724. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlaySearchEvent.kt +13 -0
  725. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSeekEvent.kt +13 -0
  726. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSkipEvent.kt +13 -0
  727. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatModeChangedEvent.kt +13 -0
  728. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RequestConfig.kt +27 -0
  729. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +67 -15
  730. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +17 -0
  731. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +27 -0
  732. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Section.kt +66 -0
  733. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SectionStyle.kt +86 -0
  734. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimer.kt +18 -8
  735. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerEndOfTrack.kt +13 -0
  736. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerTime.kt +13 -0
  737. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StyleDisplay.kt +23 -0
  738. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TimedMetadata.kt +21 -0
  739. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +55 -12
  740. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackLoadEvent.kt +17 -0
  741. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackMetadata.kt +43 -0
  742. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +17 -0
  743. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackStyle.kt +58 -5
  744. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +31 -0
  745. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_AndroidAudioOffloadSettings.kt +16 -7
  746. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_RetryConfig.kt +16 -7
  747. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_Double.kt +16 -7
  748. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Variant_NullType_NotificationButtonLayout.kt → Variant_NullType_RemoteButtonLayout.kt} +24 -15
  749. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +18 -8
  750. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +16 -7
  751. package/nitrogen/generated/ios/AudioBrowser+autolinking.rb +2 -0
  752. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +38 -29
  753. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +779 -665
  754. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +34 -16
  755. package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +36 -18
  756. package/nitrogen/generated/ios/swift/AndroidOptions.swift +12 -12
  757. package/nitrogen/generated/ios/swift/ArtworkRendering.swift +40 -0
  758. package/nitrogen/generated/ios/swift/BrowseResult.swift +12 -0
  759. package/nitrogen/generated/ios/swift/CarPlayPlayingIndicatorLocation.swift +40 -0
  760. package/nitrogen/generated/ios/swift/CardImage.swift +40 -0
  761. package/nitrogen/generated/ios/swift/FormatNavigationErrorParams.swift +7 -2
  762. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__string__.swift +54 -0
  763. package/nitrogen/generated/ios/swift/GridTile.swift +48 -0
  764. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +1 -1
  765. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2 -2
  766. package/nitrogen/generated/ios/swift/IOSOptions.swift +7 -2
  767. package/nitrogen/generated/ios/swift/ImageShape.swift +40 -0
  768. package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +52 -5
  769. package/nitrogen/generated/ios/swift/NavigationErrorKind.swift +40 -0
  770. package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +12 -12
  771. package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +12 -1
  772. package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +8 -27
  773. package/nitrogen/generated/ios/swift/{NotificationButton.swift → RemoteButton.swift} +6 -6
  774. package/nitrogen/generated/ios/swift/RemoteButtonLayout.swift +57 -0
  775. package/nitrogen/generated/ios/swift/ResolvedTrack.swift +62 -73
  776. package/nitrogen/generated/ios/swift/Section.swift +82 -0
  777. package/nitrogen/generated/ios/swift/SectionStyle.swift +133 -0
  778. package/nitrogen/generated/ios/swift/SleepTimer.swift +13 -0
  779. package/nitrogen/generated/ios/swift/StyleDisplay.swift +40 -0
  780. package/nitrogen/generated/ios/swift/Track.swift +28 -63
  781. package/nitrogen/generated/ios/swift/TrackStyle.swift +86 -22
  782. package/nitrogen/generated/ios/swift/Variant_Bool_AndroidAudioOffloadSettings.swift +12 -0
  783. package/nitrogen/generated/ios/swift/Variant_Bool_RetryConfig.swift +12 -0
  784. package/nitrogen/generated/ios/swift/Variant_NullType_Double.swift +12 -0
  785. package/nitrogen/generated/ios/swift/Variant_NullType_RemoteButtonLayout.swift +30 -0
  786. package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +13 -0
  787. package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +12 -0
  788. package/nitrogen/generated/shared/c++/AndroidOptions.hpp +8 -8
  789. package/nitrogen/generated/shared/c++/{FavoritesMatchMode.hpp → ArtworkRendering.hpp} +17 -17
  790. package/nitrogen/generated/shared/c++/CarPlayPlayingIndicatorLocation.hpp +76 -0
  791. package/nitrogen/generated/shared/c++/CardImage.hpp +76 -0
  792. package/nitrogen/generated/shared/c++/FormatNavigationErrorParams.hpp +9 -2
  793. package/nitrogen/generated/shared/c++/GridTile.hpp +84 -0
  794. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +1 -1
  795. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +1 -1
  796. package/nitrogen/generated/shared/c++/IOSOptions.hpp +9 -2
  797. package/nitrogen/generated/shared/c++/ImageShape.hpp +76 -0
  798. package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +10 -6
  799. package/nitrogen/generated/shared/c++/NavigationErrorKind.hpp +76 -0
  800. package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +8 -8
  801. package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +9 -2
  802. package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +6 -9
  803. package/nitrogen/generated/shared/c++/{NotificationButton.hpp → RemoteButton.hpp} +19 -19
  804. package/nitrogen/generated/shared/c++/RemoteButtonLayout.hpp +94 -0
  805. package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +33 -37
  806. package/nitrogen/generated/shared/c++/Section.hpp +102 -0
  807. package/nitrogen/generated/shared/c++/SectionStyle.hpp +126 -0
  808. package/nitrogen/generated/shared/c++/StyleDisplay.hpp +76 -0
  809. package/nitrogen/generated/shared/c++/Track.hpp +18 -30
  810. package/nitrogen/generated/shared/c++/TrackStyle.hpp +73 -34
  811. package/package.json +24 -11
  812. package/src/AudioBrowser.ts +2 -1
  813. package/src/CLAUDE.md +52 -0
  814. package/src/features/battery.test.ts +79 -0
  815. package/src/features/browser-config.test.ts +21 -6
  816. package/src/features/browser-config.ts +12 -8
  817. package/src/features/browser.test.ts +1 -1
  818. package/src/features/browser.ts +11 -3
  819. package/src/features/carConnection.ts +1 -1
  820. package/src/features/equalizer.ts +1 -1
  821. package/src/features/errors.ts +3 -3
  822. package/src/features/favorites.ts +14 -11
  823. package/src/features/gate.ts +16 -1
  824. package/src/features/hook-wiring.test.ts +302 -0
  825. package/src/features/metadata.ts +20 -3
  826. package/src/features/network.ts +1 -1
  827. package/src/features/nowPlaying.ts +1 -1
  828. package/src/features/output.ts +1 -1
  829. package/src/features/playback/controls.ts +4 -2
  830. package/src/features/playback/playWhenReady.ts +1 -1
  831. package/src/features/playback/playing.ts +1 -1
  832. package/src/features/playback/progress.test.ts +169 -0
  833. package/src/features/playback/progress.ts +3 -2
  834. package/src/features/playback/rate.ts +8 -1
  835. package/src/features/playback/state.ts +3 -4
  836. package/src/features/playback/trackPlaybackTime.test.ts +16 -6
  837. package/src/features/playback/trackPlaybackTime.ts +1 -6
  838. package/src/features/playback/volume.ts +1 -1
  839. package/src/features/player/options.ts +126 -76
  840. package/src/features/player/setup.test.ts +24 -7
  841. package/src/features/player/setup.ts +22 -10
  842. package/src/features/player/validateOptions.ts +21 -0
  843. package/src/features/queue/activeTrack.ts +15 -4
  844. package/src/features/queue/queue.ts +13 -6
  845. package/src/features/queue/repeatMode.ts +1 -1
  846. package/src/features/queue/shuffle.ts +1 -1
  847. package/src/features/remoteControls.ts +13 -92
  848. package/src/features/sleepTimer.test.ts +172 -0
  849. package/src/features/sleepTimer.ts +9 -1
  850. package/src/nitro-stub-drift.test.ts +277 -0
  851. package/src/public-surface.test.ts +147 -0
  852. package/src/specs/audio-browser.nitro.ts +5 -4
  853. package/src/style-resolution.test.ts +210 -0
  854. package/src/test-utils/reactNativeStub.ts +60 -0
  855. package/src/types/browser-native.ts +7 -3
  856. package/src/types/browser-nodes.ts +403 -134
  857. package/src/types/browser.ts +97 -63
  858. package/src/utils/LazyNativeEmitter.ts +28 -15
  859. package/src/utils/NativeUpdatedValue.ts +29 -13
  860. package/src/utils/getTrackIdentity.ts +20 -0
  861. package/src/utils/useDebug.test.ts +182 -0
  862. package/src/utils/useNativeUpdatedValue.test.ts +103 -0
  863. package/src/utils/useNativeValueRefreshedBy.ts +38 -0
  864. package/src/web/NativeAudioBrowser.playWhenReady.test.ts +232 -2
  865. package/src/web/NativeAudioBrowser.ts +240 -83
  866. package/src/web/TrackPlayer/LoadAttempt.ts +29 -0
  867. package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +60 -13
  868. package/src/web/TrackPlayer/PlaybackStateMachine.ts +22 -6
  869. package/src/web/TrackPlayer/Player.dispatch.test.ts +5 -3
  870. package/src/web/TrackPlayer/Player.load.test.ts +137 -1
  871. package/src/web/TrackPlayer/Player.ts +284 -37
  872. package/src/web/TrackPlayer/PlayingStateFactory.test.ts +1 -1
  873. package/src/web/TrackPlayer/PlayingStateFactory.ts +1 -1
  874. package/src/web/TrackPlayer/QueueManager.test.ts +29 -0
  875. package/src/web/TrackPlayer/QueueManager.ts +14 -0
  876. package/src/web/TrackPlayer/QueuePlayer.ts +33 -14
  877. package/src/web/__tests__/lifecycle.test.ts +345 -0
  878. package/src/web/__tests__/lifecycleHarness.ts +351 -0
  879. package/src/web/__tests__/loadEdgeCases.test.ts +246 -0
  880. package/src/web/__tests__/loadSupersession.test.ts +175 -0
  881. package/src/web/__tests__/retry.test.ts +169 -0
  882. package/src/web/browser/BrowserManager.ts +209 -111
  883. package/src/web/browser/FavoriteManager.test.ts +84 -0
  884. package/src/web/browser/FavoriteManager.ts +28 -23
  885. package/src/web/browser/NavigationErrorManager.ts +3 -1
  886. package/src/web/browser/SearchManager.test.ts +75 -0
  887. package/src/web/browser/SearchManager.ts +25 -28
  888. package/src/web/browser/__tests__/artwork-resolution.test.ts +117 -0
  889. package/src/web/browser/__tests__/layer-resolver.test.ts +35 -0
  890. package/src/web/browser/__tests__/search-artwork.test.ts +46 -0
  891. package/src/web/browser/__tests__/search-navigation.test.ts +76 -0
  892. package/src/web/browser/assertBrowsePageShape.test.ts +1 -1
  893. package/src/web/browser/assertBrowsePageShape.ts +5 -3
  894. package/src/web/browser/classifyTrackNavigation.test.ts +10 -8
  895. package/src/web/browser/classifyTrackNavigation.ts +9 -9
  896. package/src/web/browser/parseSearchResponse.test.ts +8 -2
  897. package/src/web/browser/sections.test.ts +91 -0
  898. package/src/web/browser/sections.ts +72 -0
  899. package/src/web/http/RequestConfigBuilder.test.ts +241 -1
  900. package/src/web/http/RequestConfigBuilder.ts +140 -33
  901. package/src/web/http/followMediaRedirect.test.ts +289 -0
  902. package/src/web/http/followMediaRedirect.ts +253 -0
  903. package/src/web/player/NowPlayingManager.ts +4 -3
  904. package/src/web/util/BrowserPathHelper.test.ts +68 -0
  905. package/src/web/util/BrowserPathHelper.ts +70 -13
  906. package/website/guide/android-auto.md +114 -0
  907. package/website/guide/android-certificates.md +409 -0
  908. package/website/guide/artwork.md +255 -0
  909. package/website/guide/audio-output.md +135 -0
  910. package/website/guide/automotive.md +86 -0
  911. package/website/guide/basic-usage.md +151 -0
  912. package/website/guide/battery.md +115 -0
  913. package/website/guide/browser.md +587 -0
  914. package/website/guide/carplay.md +650 -0
  915. package/website/guide/configuration.md +173 -0
  916. package/website/guide/equalizer.md +231 -0
  917. package/website/guide/errors.md +310 -0
  918. package/website/guide/favorites.md +154 -0
  919. package/website/guide/gate.md +143 -0
  920. package/website/guide/getting-started.md +46 -0
  921. package/website/guide/hooks.md +238 -0
  922. package/website/guide/live-streams.md +125 -0
  923. package/website/guide/metadata.md +239 -0
  924. package/website/guide/migrating-from-track-player.md +244 -0
  925. package/website/guide/native-callback-fetch.md +127 -0
  926. package/website/guide/network.md +86 -0
  927. package/website/guide/now-playing.md +175 -0
  928. package/website/guide/playback.md +328 -0
  929. package/website/guide/queue.md +300 -0
  930. package/website/guide/remote-controls.md +256 -0
  931. package/website/guide/search.md +255 -0
  932. package/website/guide/sleep-timer.md +268 -0
  933. package/website/guide/track.md +247 -0
  934. package/ios/Bridge.h +0 -8
  935. package/ios/Browser/MediaResolveComposer.swift +0 -114
  936. package/ios/CarPlay/ImageRowItem+CarPlay.swift +0 -19
  937. package/ios/Model/MediaURL.swift +0 -67
  938. package/ios/NowPlayingInfo/MediaItemProperty.swift +0 -78
  939. package/ios/NowPlayingInfo/NowPlayingInfoKeyValue.swift +0 -6
  940. package/ios/NowPlayingInfo/NowPlayingInfoProperty.swift +0 -220
  941. package/ios/Observer/PlayerItemNotificationObserver.swift +0 -119
  942. package/ios/Observer/PlayerItemPropertyObserver.swift +0 -133
  943. package/ios/Observer/PlayerStateObserver.swift +0 -50
  944. package/ios/Observer/PlayerTimeObserver.swift +0 -55
  945. package/ios/Option/PitchAlgorithms.swift +0 -17
  946. package/ios/Option/TimeEventFrequency.swift +0 -18
  947. package/ios/Player/LoadSeekCoordinator.swift +0 -99
  948. package/ios/Player/MediaLoaderDelegate.swift +0 -11
  949. package/ios/Player/PlaybackCoordinator.swift +0 -754
  950. package/ios/Player/PlaybackEffectHandler.swift +0 -54
  951. package/ios/Player/PlaybackErrorHandler.swift +0 -175
  952. package/ios/Player/PlaybackStateStore.swift +0 -27
  953. package/ios/Player/PlayingStateManager.swift +0 -33
  954. package/ios/Player/RetryManager.swift +0 -322
  955. package/ios/Player/SeekCompletionHandler.swift +0 -3
  956. package/ios/Player/SleepTimerHandling.swift +0 -15
  957. package/ios/Support/RNTrackPlayer-Bridging-Header.h +0 -7
  958. package/ios/Tests/LoadSeekCoordinatorTests.swift +0 -325
  959. package/ios/Tests/MediaResolveTests.swift +0 -126
  960. package/ios/Tests/OnceValueTests.swift +0 -79
  961. package/ios/Tests/PlaybackErrorHandlerTests.swift +0 -547
  962. package/ios/Tests/PlaybackStateStoreTests.swift +0 -48
  963. package/ios/Tests/PlayingStateManagerTests.swift +0 -57
  964. package/ios/Tests/RetryManagerTests.swift +0 -89
  965. package/ios/TrackPlayer.swift +0 -1014
  966. package/ios/TrackPlayerCallbacks.swift +0 -86
  967. package/ios/Util/MetadataAdapter.swift +0 -131
  968. package/ios/Util/OnceValue.swift +0 -104
  969. package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +0 -58
  970. package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +0 -58
  971. package/nitrogen/generated/android/c++/JImageRowItem.hpp +0 -105
  972. package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +0 -94
  973. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +0 -26
  974. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +0 -71
  975. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +0 -26
  976. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +0 -75
  977. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteConfig.kt +0 -38
  978. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +0 -68
  979. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +0 -50
  980. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +0 -53
  981. package/nitrogen/generated/ios/swift/FavoriteConfig.swift +0 -29
  982. package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +0 -40
  983. package/nitrogen/generated/ios/swift/ImageRowItem.swift +0 -195
  984. package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +0 -92
  985. package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +0 -18
  986. package/nitrogen/generated/ios/swift/Variant_NullType_NotificationButtonLayout.swift +0 -18
  987. package/nitrogen/generated/shared/c++/FavoriteConfig.hpp +0 -84
  988. package/nitrogen/generated/shared/c++/ImageRowItem.hpp +0 -129
  989. package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +0 -102
@@ -0,0 +1,268 @@
1
+ ---
2
+ description: 'Stop playback after a fixed time or at the end of the current track, counted down natively so it fires with the app backgrounded or the screen off.'
3
+ ---
4
+
5
+ # Sleep Timer
6
+
7
+ A **sleep timer** stops playback on its own after a set time — the classic
8
+ "fall asleep to the radio" feature. The library runs the timer natively, so it
9
+ keeps counting down and fires even when your app is backgrounded or the screen
10
+ is off. There are two kinds:
11
+
12
+ - **Time-based** — pause after a fixed number of seconds (e.g. "in 30 minutes").
13
+ - **End of track** — pause when the current track finishes playing.
14
+
15
+ Only one timer is active at a time; setting a new one replaces the old.
16
+
17
+ ## Setting a timer
18
+
19
+ Call `setSleepTimer` with a duration in **seconds**. This example stops playback
20
+ after 30 minutes:
21
+
22
+ ```ts
23
+ import { setSleepTimer } from 'react-native-audio-browser'
24
+
25
+ setSleepTimer(30 * 60)
26
+ ```
27
+
28
+ Most UIs offer a few presets rather than a free-form duration — multiply the
29
+ minutes you show by 60:
30
+
31
+ ```ts
32
+ const PRESETS_MINUTES = [15, 30, 45, 60]
33
+
34
+ setSleepTimer(PRESETS_MINUTES[1] * 60) // 30 minutes
35
+ ```
36
+
37
+ To pause when the current track ends instead of after a fixed time, use
38
+ `setSleepTimerToEndOfTrack`:
39
+
40
+ ```ts
41
+ import { setSleepTimerToEndOfTrack } from 'react-native-audio-browser'
42
+
43
+ setSleepTimerToEndOfTrack()
44
+ ```
45
+
46
+ When the timer completes, the library **pauses** playback (it doesn't stop or
47
+ tear the player down). Pressing play resumes as normal.
48
+
49
+ ## Fading out
50
+
51
+ Pass a `fadeDuration` (in seconds) to ramp the volume down to silence as the
52
+ timer runs out — a gentler finish than an abrupt pause:
53
+
54
+ ```ts
55
+ // Stop in 30 minutes, fading the last 20 seconds to silence.
56
+ setSleepTimer(30 * 60, { fadeDuration: 20 })
57
+ ```
58
+
59
+ The fade always ends exactly at the deadline (if `fadeDuration` is longer than
60
+ the timer itself, it's clamped to the timer's length). Once playback pauses, the
61
+ library restores the pre-fade volume, so the next time the listener hits play it
62
+ starts at normal loudness.
63
+
64
+ During the fade the timer takes priority: seeking or skipping plays into the
65
+ remaining ramp rather than cancelling it. Only pausing, or clearing/replacing
66
+ the timer, stops the fade. The countdown keeps ticking throughout, so you can
67
+ show a "fading out" hint once `secondsLeft` drops to `fadeDuration` (see the
68
+ [complete example](#a-complete-screen)).
69
+
70
+ ## Clearing a timer
71
+
72
+ `clearSleepTimer` cancels the active timer. It returns `true` if a timer was
73
+ actually cleared, or `false` if none was set:
74
+
75
+ ```ts
76
+ import { clearSleepTimer } from 'react-native-audio-browser'
77
+
78
+ clearSleepTimer()
79
+ ```
80
+
81
+ ## Reading the timer in your UI
82
+
83
+ Use the `useSleepTimer` hook to show a live countdown. It re-renders every
84
+ second and returns:
85
+
86
+ - For a time-based timer: `{ time, secondsLeft }`, where `time` is the deadline
87
+ (epoch milliseconds) and `secondsLeft` counts down to `0`.
88
+ - For an end-of-track timer: `{ sleepWhenPlayedToEnd: true }`.
89
+ - `undefined` when no timer is active.
90
+
91
+ ```tsx
92
+ import { useSleepTimer } from 'react-native-audio-browser'
93
+
94
+ function SleepTimerLabel() {
95
+ const timer = useSleepTimer()
96
+
97
+ if (!timer) return <Text>No sleep timer</Text>
98
+ if ('sleepWhenPlayedToEnd' in timer) {
99
+ return <Text>Stopping at end of track</Text>
100
+ }
101
+
102
+ const minutes = Math.floor(timer.secondsLeft / 60)
103
+ const seconds = timer.secondsLeft % 60
104
+ return (
105
+ <Text>
106
+ Sleeping in {minutes}m {seconds}s
107
+ </Text>
108
+ )
109
+ }
110
+ ```
111
+
112
+ The countdown only ticks while the app is in the foreground — `secondsLeft`
113
+ doesn't advance in the background (the native timer still fires on time
114
+ regardless). The only reason to care is to avoid pointless per-second re-renders
115
+ while backgrounded: derive the `inactive` flag from React Native's `AppState`
116
+ and pass it in. You can also tune the refresh rate with `updateInterval`
117
+ (milliseconds, default `1000`):
118
+
119
+ ```tsx
120
+ import { useEffect, useState } from 'react'
121
+ import { AppState } from 'react-native'
122
+ import { useSleepTimer } from 'react-native-audio-browser'
123
+
124
+ function useAppInactive() {
125
+ const [inactive, setInactive] = useState(
126
+ () => AppState.currentState !== 'active'
127
+ )
128
+ useEffect(() => {
129
+ const sub = AppState.addEventListener('change', (state) =>
130
+ setInactive(state !== 'active')
131
+ )
132
+ return () => sub.remove()
133
+ }, [])
134
+ return inactive
135
+ }
136
+
137
+ // In a component: pause the countdown updates while backgrounded.
138
+ const timer = useSleepTimer({ inactive: useAppInactive() })
139
+ ```
140
+
141
+ ### Just need to know if one is set?
142
+
143
+ If you only want to toggle a button's appearance, `useSleepTimerActive` is a
144
+ lighter-weight hook that returns a boolean and doesn't re-render every second:
145
+
146
+ ```tsx
147
+ import { useSleepTimerActive } from 'react-native-audio-browser'
148
+
149
+ function SleepTimerButton() {
150
+ const active = useSleepTimerActive()
151
+ return <Icon name={active ? 'timer-on' : 'timer-off'} />
152
+ }
153
+ ```
154
+
155
+ ## A complete screen
156
+
157
+ Putting it together — preset durations, an end-of-track option, an off button,
158
+ and a live countdown that switches to a "fading out" hint as the fade begins:
159
+
160
+ ```tsx
161
+ import { View, Button, Text } from 'react-native'
162
+ import {
163
+ setSleepTimer,
164
+ setSleepTimerToEndOfTrack,
165
+ clearSleepTimer,
166
+ useSleepTimer
167
+ } from 'react-native-audio-browser'
168
+
169
+ const PRESETS_MINUTES = [15, 30, 45, 60]
170
+ const FADE_SECONDS = 20
171
+
172
+ function SleepTimerScreen() {
173
+ const timer = useSleepTimer()
174
+
175
+ return (
176
+ <View>
177
+ {PRESETS_MINUTES.map((minutes) => (
178
+ <Button
179
+ key={minutes}
180
+ title={`${minutes} min`}
181
+ onPress={() =>
182
+ setSleepTimer(minutes * 60, { fadeDuration: FADE_SECONDS })
183
+ }
184
+ />
185
+ ))}
186
+ <Button
187
+ title="End of track"
188
+ onPress={() => setSleepTimerToEndOfTrack()}
189
+ />
190
+ <Button title="Off" onPress={() => clearSleepTimer()} />
191
+
192
+ <Status timer={timer} fadeSeconds={FADE_SECONDS} />
193
+ </View>
194
+ )
195
+ }
196
+
197
+ function Status(props: {
198
+ timer: ReturnType<typeof useSleepTimer>
199
+ fadeSeconds: number
200
+ }) {
201
+ const { timer, fadeSeconds } = props
202
+ if (!timer) return <Text>No sleep timer</Text>
203
+ if ('sleepWhenPlayedToEnd' in timer) {
204
+ return <Text>Stopping at end of track</Text>
205
+ }
206
+ if (timer.secondsLeft <= fadeSeconds) return <Text>Fading out…</Text>
207
+
208
+ const minutes = Math.floor(timer.secondsLeft / 60)
209
+ const seconds = timer.secondsLeft % 60
210
+ return (
211
+ <Text>
212
+ Sleeping in {minutes}m {seconds}s
213
+ </Text>
214
+ )
215
+ }
216
+ ```
217
+
218
+ When the timer fires (or is cleared), `useSleepTimer` returns `undefined` and
219
+ the countdown stops on its own — so `Status` falls back to "No sleep timer"
220
+ without any extra handling on your part.
221
+
222
+ ## Outside of React
223
+
224
+ If you're not in a component, read the current timer with `getSleepTimer` or
225
+ subscribe to changes with `onSleepTimerChanged`. Note that `getSleepTimer`
226
+ returns the raw timer state (`{ time }` in epoch milliseconds, or
227
+ `{ sleepWhenPlayedToEnd }`, or `null`) — it doesn't compute `secondsLeft`; that
228
+ convenience is added by the `useSleepTimer` hook.
229
+
230
+ ```ts
231
+ import { getSleepTimer, onSleepTimerChanged } from 'react-native-audio-browser'
232
+
233
+ getSleepTimer() // { time } | { sleepWhenPlayedToEnd } | null
234
+
235
+ // addListener returns a cleanup function — call it to unsubscribe.
236
+ const unsubscribe = onSleepTimerChanged.addListener((timer) => {
237
+ console.log('sleep timer is now', timer)
238
+ })
239
+
240
+ // later, when you no longer need updates:
241
+ unsubscribe()
242
+ ```
243
+
244
+ ## Behavior and edge cases
245
+
246
+ - **Setting replaces, it doesn't stack.** Calling any setter while a timer is
247
+ running swaps it for the new one — there's only ever a single active timer.
248
+ - **Not persisted across launches.** The timer lives in memory. If the app is
249
+ killed (or the OS reclaims it), the timer is gone on next launch — it does not
250
+ resume. Persist your own "timer set at" value if you need to restore the UI.
251
+ - **No input validation.** `seconds` is passed straight through to the native
252
+ scheduler, which isn't clamped — a value of `0` or a negative number fires
253
+ essentially immediately (pausing right away). Validate in your own UI if that
254
+ matters.
255
+ - **Nothing throws.** Every function here is synchronous; the setters return
256
+ `void` and `clearSleepTimer` returns a boolean. No `try/catch` needed.
257
+
258
+ ## API summary
259
+
260
+ | API | Purpose |
261
+ | ----------------------------------------------- | --------------------------------------------------------------- |
262
+ | `setSleepTimer(seconds, { fadeDuration? })` | Pause playback after `seconds`, optionally fading out. |
263
+ | `setSleepTimerToEndOfTrack()` | Pause when the current track finishes. |
264
+ | `clearSleepTimer()` | Cancel the active timer; returns `true` if one was cleared. |
265
+ | `getSleepTimer()` | Read the raw timer state (no `secondsLeft`). |
266
+ | `onSleepTimerChanged` | Subscribe to timer changes outside React; returns a cleanup fn. |
267
+ | `useSleepTimer({ updateInterval?, inactive? })` | Live state with a `secondsLeft` countdown. |
268
+ | `useSleepTimerActive()` | Boolean: is any timer set? |
@@ -0,0 +1,247 @@
1
+ ---
2
+ description: 'The Track shape — the single unit of content: required fields, identity, metadata, and artwork, used for browse rows, queue items, and lock-screen metadata.'
3
+ ---
4
+
5
+ # Track
6
+
7
+ A **Track** is the one unit of content in the library. The same object describes a row in a browse list, an item in the playback queue, and the metadata on the lock screen — so once you know the Track shape, you can read and build content everywhere.
8
+
9
+ A Track is just a plain object. The only required field is `title`, plus **at least one** of `path` (browsable) or `src` (playable):
10
+
11
+ ```ts
12
+ const station: Track = {
13
+ title: 'Smooth Floret FM',
14
+ src: 'https://example.com/floret.mp3'
15
+ }
16
+ ```
17
+
18
+ A real track usually carries more — identity, metadata, and artwork:
19
+
20
+ ```ts
21
+ const episode: Track = {
22
+ id: 'atp-545',
23
+ title: 'Episode 545',
24
+ artist: 'Accidental Tech Podcast',
25
+ album: 'ATP',
26
+ artwork: 'https://example.com/atp.jpg',
27
+ duration: 7200,
28
+ src: 'https://example.com/atp/545.mp3'
29
+ }
30
+ ```
31
+
32
+ This guide is the field-by-field reference. For _where_ tracks come from (routes, callbacks, HTTP) see the [Browser](/guide/browser) guide.
33
+
34
+ ## Browsable, playable, or both
35
+
36
+ Two fields decide what a Track _does_. A Track must set at least one of them, and may set both:
37
+
38
+ | Field | Makes the track | Effect |
39
+ | ------ | --------------- | ---------------------------------------------------- |
40
+ | `path` | **browsable** | a container — tapping it navigates into its children |
41
+ | `src` | **playable** | a leaf — the player can stream it |
42
+
43
+ ```ts
44
+ // Browsable: a folder you navigate into
45
+ { title: 'Jazz', path: '/browse/jazz' }
46
+
47
+ // Playable: a station you stream
48
+ { title: 'Smooth Floret FM', src: 'https://example.com/floret.mp3' }
49
+
50
+ // Both: a podcast episode you can open *and* play
51
+ { title: 'Episode 42', path: '/episodes/42', src: 'https://…/42.mp3' }
52
+ ```
53
+
54
+ `src` is usually an absolute audio URL, but it can be any string — a file path or your own identifier — that you turn into a real request in `media.resolve` (see [Browser → Media and artwork](/guide/browser#media-and-artwork)).
55
+
56
+ ## Identity: `id`
57
+
58
+ `id` is an **opaque, stable identifier** you control. The library never parses it — it round-trips verbatim through `setQueue`, the queue, `getActiveTrack`, and `onActiveTrackChanged`.
59
+
60
+ Why it matters: when playback moves by an _external_ control — a lock-screen / CarPlay / Android Auto / Bluetooth next-or-previous — you find out which of _your_ items became active by matching its `id`, without re-parsing the `src`:
61
+
62
+ ```ts
63
+ // the callback gets a PlaybackActiveTrackChangedEvent — use event.track
64
+ const unsubscribe = onActiveTrackChanged.addListener((event) => {
65
+ const episode = myEpisodes.find((e) => e.id === event.track?.id)
66
+ // …update your UI for `episode`
67
+ })
68
+ ```
69
+
70
+ The event also carries `index`, `lastTrack`, and `lastIndex`; `addListener` returns an unsubscribe function.
71
+
72
+ `id` is also passed to the per-track `resolve` hooks, so you can set `src` to the same stable identifier and synthesise the real request/artwork from it at request time.
73
+
74
+ ::: tip `id` is optional
75
+ A track's identity is its `id`, falling back to `src` — so if the same item's `src` string is identical wherever it appears, you can skip `id` entirely. Set ids consistently across your content or not at all: identity is compared whole, and a row carrying an `id` never matches a track without one.
76
+ :::
77
+
78
+ ## Display fields
79
+
80
+ These set the text shown across surfaces. Only `title` is required.
81
+
82
+ | Field | Shown where |
83
+ | ----------------------- | ---------------------------------------------------------------------------- |
84
+ | `title` | primary line — browse rows **and** now-playing (required) |
85
+ | `subtitle` | secondary line in **browse lists** only |
86
+ | `artist` | secondary line on **now-playing / lock screen**; the head-unit "artist" slot |
87
+ | `album` | album name (and gates the tappable album line — see `albumPath`) |
88
+ | `genre` / `description` | extra metadata |
89
+ | `duration` | catalog metadata in seconds, for your UI |
90
+
91
+ ::: warning `subtitle` and `artist` are separate — neither falls back to the other
92
+ `subtitle` drives browse-list rows; `artist` drives the now-playing line and Bluetooth metadata. Set each one for the surface you want it on.
93
+ :::
94
+
95
+ `duration` is **catalog metadata only** (e.g. an episode list) — it does _not_ drive the now-playing scrubber. Every surface derives elapsed/remaining from the player itself.
96
+
97
+ ## Artwork
98
+
99
+ Set `artwork` to an image URL. It's transformed through your [artwork configuration](/guide/browser#media-and-artwork) and the ready-to-render result comes back on the **output-only** `artworkSource`, shaped for React Native's `<Image>`:
100
+
101
+ ```tsx
102
+ <Image source={track.artworkSource} />
103
+ ```
104
+
105
+ Don't set `artworkSource` yourself — the library populates it.
106
+
107
+ **SF Symbols (iOS).** Prefix `artwork` with `sf:` to use a system symbol, with optional colors — `bg` (background, transparent if omitted) and `fg` (symbol, black if omitted):
108
+
109
+ ```ts
110
+ {
111
+ title: 'Favorites',
112
+ path: '/favorites',
113
+ artwork: 'sf:heart.fill?bg=#FF0090&fg=#fff'
114
+ }
115
+ ```
116
+
117
+ On CarPlay, an SF Symbol with no explicit colors adapts to light/dark mode automatically.
118
+
119
+ **Tinting (`style: { artworkRendering: 'stencil' }`).** For monochrome icons, declare this so CarPlay tints them per appearance — black in light mode, white in dark. Use it for icons, not full-color album art. iOS CarPlay only; Android Auto is dark-only, so ship appropriately-colored (e.g. white) icons there. On Android, an `android.resource://…` artwork URI combines with any declared `display` the library forwards to select Android Auto's icon treatment of that layout (icon margins + system tinting for vector drawables).
120
+
121
+ **Light and dark images.** When the appearances need genuinely different artwork rather than the same shape recolored, set `artwork` to an [`ArtworkVariants`](/api/types/browser-nodes/#artworkvariants) pair — `{ light, dark }`. CarPlay adapts between them in place; everywhere that needs a single image uses `dark`. See [Artwork → Light and dark](/guide/artwork#light-and-dark-artwork).
122
+
123
+ ## Per-track request override
124
+
125
+ [`request`](/api/types/browser-nodes/#trackrequest) is a **narrow** per-track override for _how_ this track's audio request is made — merged last, after the shared `request` and `media` layers:
126
+
127
+ ```ts
128
+ {
129
+ title: 'Member Stream',
130
+ src: 'https://example.com/members/floret.mp3',
131
+ request: { headers: { authorization: 'Bearer …' } }
132
+ }
133
+ ```
134
+
135
+ It carries only `userAgent`, `headers`, and `query` — deliberately **not** `baseUrl` / `path` / `method` / `body`, so a track (often server-sourced) can customise _how_ it's fetched but can't repoint its own host or verb. Like every field, it round-trips verbatim through the queue.
136
+
137
+ ## Presentation on native surfaces
138
+
139
+ Optional fields that change how a Track renders on CarPlay / Android Auto. Each surface applies the ones it supports; an unsupported field is a no-op, never an error.
140
+
141
+ | Field | Effect | Platform |
142
+ | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------- |
143
+ | `style: { display: 'list' \| 'grid' }` | on a browsable track: the layout of the page it opens | Android Auto / AAOS |
144
+ | `style: { artworkRendering: 'stencil' }` | tint monochrome artwork to the surface appearance | CarPlay |
145
+ | `style: { imageShape: 'circular' }` | crop `'image'` and `'condensed'` tile artwork circular (people) | CarPlay (iOS 26+) |
146
+ | `style: { accessorySymbol: '…' }` | SF Symbol accessory; `'none'` restores the derived accessory | CarPlay |
147
+ | `style: { cardTint: '…', cardImage: '…' }` | card color and image mode, when the section renders `gridTile: 'card'` | CarPlay (iOS 26+) |
148
+ | `disabled` | unavailable: never plays; grayed where drawable, hidden elsewhere | all |
149
+ | `favorited` | filled/empty heart (needs the `favorite` capability) | Android Auto, notification |
150
+ | `live` | a "live" indicator | iOS now-playing |
151
+ | `albumPath` | make the now-playing album line tappable | CarPlay |
152
+ | `icyCharset` | decode ICY titles a station sends in a legacy code page | iOS, Android |
153
+
154
+ A couple of constraints worth knowing:
155
+
156
+ - **`display` goes on the browsable track as it appears in its parent's list** — Android Auto reads it there, before the page resolves, to decide how to lay out the page once you navigate in. It is only sent when you declare it — the library never infers it from the page's content. The drilled-into page's own sections override it per section via their `style`.
157
+ - **`albumPath` requires `album`** (CarPlay renders the tappable line from album metadata), and pairs with `resolveAlbumPath` in the [Browser config](/guide/browser).
158
+
159
+ ```ts
160
+ // This track as it appears in its parent's list (no children here — the
161
+ // page supplies those): it declares the layout of the page it opens.
162
+ {
163
+ path: '/genres',
164
+ title: 'Genres',
165
+ // the page this opens lays out as tiles in Android Auto
166
+ style: { display: 'grid' }
167
+ }
168
+ ```
169
+
170
+ ## Sections — grouping and tile layouts
171
+
172
+ A Track appears in two roles. As a **row** in its parent's list it's a handle: its own `style.display` only advertises the layout of the page it opens (see [above](#presentation-on-native-surfaces)). Once resolved, that same Track **is the page** — a [`ResolvedTrack`](/api/types/browser-nodes/#resolvedtrack) — and that is when it carries `sections`.
173
+
174
+ Headers and layout belong to the container role: declare them on the page's [`Section`](/api/types/browser-nodes/#section)s (`{ title?, subtitle?, style?, path?, children }`), never on the rows. A section groups tracks under a header, and its `style` block's `display` picks their layout: `'list'` rows (the default) or `'grid'` artwork tiles — wrapping unless `gridWrap: false` keeps them to a single line. The section's `path` is the navigation target for its header / "view all" surface; without one the header is a plain label, not a link — the section is self-contained.
175
+
176
+ A tile with `src` **plays immediately on tap** (same selection path as a playable list row — a station app can make tiles play their station directly); otherwise its `path` is navigated. Tiles are ordinary Tracks, so playable ones carry the now-playing fields any track would (`id`, `artist`, `album`, `albumPath`, `live`, `request`). Tapping a playable child queues **its section** on every surface (see [Playback behavior](/guide/browser#playback-behavior)):
177
+
178
+ ```ts
179
+ {
180
+ path: '/home',
181
+ title: 'Home',
182
+ sections: [
183
+ {
184
+ title: 'Featured',
185
+ style: { display: 'grid', gridWrap: false },
186
+ path: '/browse/featured', // header tap → the full list
187
+ children: [
188
+ { title: 'Jazz', path: '/browse/jazz', artwork: 'https://…/jazz.jpg' },
189
+ {
190
+ title: 'Beacon FM',
191
+ src: 'https://audio.example.com/beacon.mp3', // tap plays it
192
+ artist: 'Springfield',
193
+ live: true,
194
+ artwork: 'https://…/beacon.jpg'
195
+ }
196
+ ]
197
+ },
198
+ { title: 'All stations', children: [...] }
199
+ ]
200
+ }
201
+ ```
202
+
203
+ Each surface renders a declaration as its nearest supported form — CarPlay truncates a single-line grid (`gridWrap: false`) at the tiles that fit, Android Auto's grid always wraps, app UIs typically render a horizontal scroller — see [Browser → Presentation](/guide/browser#presentation) for the full rundown.
204
+
205
+ ## ResolvedTrack — a resolved page
206
+
207
+ A [**`ResolvedTrack`**](/api/types/browser-nodes/#resolvedtrack) is the same Track plus its resolved content — the page the browser is currently showing. Its `path` is always present, and `sections` is the [`Section`](/api/types/browser-nodes/#section)`[]` to render (optional — a leaf page has none). A page authored with a plain `children` list resolves to a single untitled section: `children` is authoring sugar, never populated on resolved output — read `sections`.
208
+
209
+ Navigation is **fire-and-forget**: `navigate(path)` returns `void`. Read the resolved page from `useContent()` (or `getContent()` / `onContentChanged`):
210
+
211
+ ```tsx
212
+ import { navigate, useContent } from 'react-native-audio-browser'
213
+
214
+ navigate('/browse/jazz') // moves the browser to this path
215
+
216
+ function JazzPage() {
217
+ const page = useContent() // ResolvedTrack | undefined
218
+ // each section: { title?, style?, path?, children: Track[] }
219
+ return <List sections={page?.sections ?? []} /> // sections may be undefined
220
+ }
221
+ ```
222
+
223
+ A `ResolvedTrack` may also set [`carPlaySiriListButton`](/api/types/browser/#carplaysirilistbuttonposition)`: 'top' | 'bottom'` to show the "Ask Siri to Play" cell on that page (needs Siri wiring — see [CarPlay](/guide/carplay)).
224
+
225
+ ## Using tracks in your code
226
+
227
+ Tracks flow through the queue and playback API. A minimal playable track needs just `title` + `src`:
228
+
229
+ ```ts
230
+ import { setQueue, play, useActiveTrack } from 'react-native-audio-browser'
231
+
232
+ setQueue([
233
+ { title: 'Smooth Floret FM', src: 'https://example.com/floret.mp3' },
234
+ { title: 'The Stalk 88.5', src: 'https://example.com/stalk.mp3' }
235
+ ])
236
+ play()
237
+ ```
238
+
239
+ `load(track)` plays a single track, `add(tracks)` appends to the queue, and `getActiveTrack()` / `useActiveTrack()` read what's playing now (with its `artworkSource` populated for your UI). See [Basic Usage](/guide/basic-usage) for the full queue and playback API.
240
+
241
+ ## Where to go next
242
+
243
+ - **[Browser](/guide/browser)** — where tracks come from: tabs, routes, sources.
244
+ - **[Now Playing](/guide/now-playing)** — how a track's fields drive the lock-screen / car metadata.
245
+ - **[Favorites](/guide/favorites)** — the `favorited` field and the heart button.
246
+
247
+ For the exact types — every field and its JSDoc — see [`Track`](/api/types/browser-nodes/#track) and [`ResolvedTrack`](/api/types/browser-nodes/#resolvedtrack) in the API reference.
package/ios/Bridge.h DELETED
@@ -1,8 +0,0 @@
1
- //
2
- // Bridge.h
3
- // audio-browser
4
- //
5
- // Created by puckey on 10/12/2025
6
- //
7
-
8
- #pragma once
@@ -1,114 +0,0 @@
1
- import Foundation
2
-
3
- /// Pure, Nitro-free composition logic for the media `resolve` layer.
4
- ///
5
- /// The two pieces that need testing in isolation from the Nitro bridge are:
6
- /// 1. the variant unwrap — `resolve(track)` returns a `RequestConfig` either
7
- /// synchronously (`.first`) or via a `Promise` (`.second`); both arms must
8
- /// yield the same `RequestConfig`; and
9
- /// 2. the merge — the resolved config is layered over the base with
10
- /// override-wins per field (and per-key dict merge for headers/query).
11
- ///
12
- /// Production (`BrowserManager+URLResolution.swift`) builds the Nitro
13
- /// `RequestConfig` values and calls into `MediaResolveComposer.merge` /
14
- /// `.unwrap`; the SPM test target exercises the same functions against the
15
- /// stub `RequestConfigLike` value type. Keeping the logic here (rather than in
16
- /// the Nitro-only extension) is what makes it reachable from tests.
17
- enum MediaResolveComposer {
18
- /// A minimal field set mirroring `RequestConfig`, used so the merge logic can
19
- /// be expressed once and shared between the Nitro types and the test stub.
20
- struct RequestConfigLike: Equatable {
21
- var method: String?
22
- var path: String?
23
- var baseUrl: String?
24
- var headers: [String: String]?
25
- var query: [String: String]?
26
- var body: String?
27
- var contentType: String?
28
- var userAgent: String?
29
-
30
- init(
31
- method: String? = nil,
32
- path: String? = nil,
33
- baseUrl: String? = nil,
34
- headers: [String: String]? = nil,
35
- query: [String: String]? = nil,
36
- body: String? = nil,
37
- contentType: String? = nil,
38
- userAgent: String? = nil,
39
- ) {
40
- self.method = method
41
- self.path = path
42
- self.baseUrl = baseUrl
43
- self.headers = headers
44
- self.query = query
45
- self.body = body
46
- self.contentType = contentType
47
- self.userAgent = userAgent
48
- }
49
- }
50
-
51
- /// The unwrapped result of a `resolve(track)` variant.
52
- enum ResolveVariant<Config> {
53
- /// `.first` — a synchronous config.
54
- case sync(Config)
55
- /// `.second` — a config delivered via an async closure (a Promise in prod).
56
- case async(() async throws -> Config)
57
- }
58
-
59
- /// Unwraps a sync/async config into a concrete config, awaiting the async arm
60
- /// if needed. (Production no longer uses a Nitro variant — `resolve`/`resolveSync`
61
- /// are separate fields — but this stays as a pure, testable composition helper.)
62
- static func unwrap<Config>(_ variant: ResolveVariant<Config>) async throws -> Config {
63
- switch variant {
64
- case let .sync(config):
65
- config
66
- case let .async(makeConfig):
67
- try await makeConfig()
68
- }
69
- }
70
-
71
- /// Run-both resolve composition: the async-resolved config first, then the
72
- /// sync-resolved merged over it (sync winning) via `combine`. `nil` when neither
73
- /// produced a config. Generic so it is shared verbatim by production (Nitro
74
- /// `RequestConfig` + `mergeRequestConfig`) and tests (`RequestConfigLike` +
75
- /// `merge`) — one implementation, exercised on both sides.
76
- static func composeResolved<C>(
77
- async asyncResolved: C?,
78
- sync syncResolved: C?,
79
- combine: (C, C) -> C,
80
- ) -> C? {
81
- switch (asyncResolved, syncResolved) {
82
- case (nil, nil): nil
83
- case let (value?, nil): value
84
- case let (nil, value?): value
85
- case let (a?, s?): combine(a, s)
86
- }
87
- }
88
-
89
- /// Override-wins per-field merge. Headers and query merge per-key (override
90
- /// key wins). Matches `BrowserManager.mergeRequestConfig`.
91
- static func merge(base: RequestConfigLike, override: RequestConfigLike) -> RequestConfigLike {
92
- RequestConfigLike(
93
- method: override.method ?? base.method,
94
- path: override.path ?? base.path,
95
- baseUrl: override.baseUrl ?? base.baseUrl,
96
- headers: mergeDicts(base.headers, override.headers),
97
- query: mergeDicts(base.query, override.query),
98
- body: override.body ?? base.body,
99
- contentType: override.contentType ?? base.contentType,
100
- userAgent: override.userAgent ?? base.userAgent,
101
- )
102
- }
103
-
104
- /// Per-key dict merge with override-wins; nil-safe (returns the non-nil side,
105
- /// or nil when both are nil). Matches `BrowserManager.mergeDicts`.
106
- static func mergeDicts(_ base: [String: String]?, _ override: [String: String]?) -> [String: String]? {
107
- switch (base, override) {
108
- case (nil, nil): nil
109
- case let (base?, nil): base
110
- case let (nil, override?): override
111
- case let (base?, override?): base.merging(override) { _, new in new }
112
- }
113
- }
114
- }
@@ -1,19 +0,0 @@
1
- import Foundation
2
- import NitroModules
3
-
4
- // MARK: - ImageRowItem → Track Conversion
5
-
6
- extension ImageRowItem {
7
- /// Creates a minimal Track from an ImageRowItem for reuse with item selection and artwork loading.
8
- /// A `src`-bearing item becomes a playable track (thumbnail tap plays it); otherwise the
9
- /// track only navigates via `url`.
10
- func toTrack() -> Track {
11
- Track(
12
- id: id, url: url, src: src, artwork: artwork.map { .first($0) },
13
- artworkSource: artworkSource, request: request,
14
- artworkCarPlayTinted: nil, title: title, subtitle: nil, artist: artist,
15
- albumUrl: albumUrl, album: album, description: nil, genre: nil, duration: nil, style: nil,
16
- childrenStyle: nil, favorited: nil, groupTitle: nil, live: live, imageRow: nil,
17
- )
18
- }
19
- }