@5stones/react-native-audio-browser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AudioBrowser.podspec +43 -0
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +210 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +36 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +1191 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowserPackage.kt +21 -0
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +92 -0
- package/android/src/main/java/com/audiobrowser/HeadlessTaskService.kt +59 -0
- package/android/src/main/java/com/audiobrowser/Service.kt +336 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +1169 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +103 -0
- package/android/src/main/java/com/audiobrowser/browser/RouteMatch.kt +9 -0
- package/android/src/main/java/com/audiobrowser/browser/SimpleRouter.kt +150 -0
- package/android/src/main/java/com/audiobrowser/extension/EnumExtensions.kt +5 -0
- package/android/src/main/java/com/audiobrowser/extension/NumberExt.kt +13 -0
- package/android/src/main/java/com/audiobrowser/http/HttpClient.kt +171 -0
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +251 -0
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +80 -0
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +101 -0
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +125 -0
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +256 -0
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +163 -0
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +177 -0
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +580 -0
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +578 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +58 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +245 -0
- package/android/src/main/java/com/audiobrowser/player/Player.kt +1509 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +230 -0
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +191 -0
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +80 -0
- package/android/src/main/java/com/audiobrowser/util/AndroidAudioContentTypeFactory.kt +17 -0
- package/android/src/main/java/com/audiobrowser/util/BatteryOptimizationHelper.kt +95 -0
- package/android/src/main/java/com/audiobrowser/util/BatteryWarningStore.kt +38 -0
- package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +155 -0
- package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +390 -0
- package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +197 -0
- package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +75 -0
- package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +97 -0
- package/android/src/main/java/com/audiobrowser/util/NetworkConnectivityMonitor.kt +121 -0
- package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +25 -0
- package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +72 -0
- package/android/src/main/java/com/audiobrowser/util/RepeatModeFactory.kt +22 -0
- package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +36 -0
- package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +130 -0
- package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +50 -0
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +125 -0
- package/android/src/main/res/values/strings.xml +6 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +273 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleBrowserTest.kt +33 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +156 -0
- package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +240 -0
- package/ios/Bridge.h +8 -0
- package/ios/Browser/BrowserConfig.swift +85 -0
- package/ios/Browser/BrowserManager.swift +985 -0
- package/ios/Browser/BrowserPathHelper.swift +156 -0
- package/ios/Browser/JsonModels.swift +165 -0
- package/ios/Browser/SimpleRouter.swift +184 -0
- package/ios/CarPlay/CarPlayController.swift +1342 -0
- package/ios/CarPlay/RNABCarPlaySceneDelegate.h +15 -0
- package/ios/CarPlay/RNABCarPlaySceneDelegate.m +59 -0
- package/ios/CarPlay/Track+CarPlay.swift +49 -0
- package/ios/Extension/Capability+RemoteCommand.swift +76 -0
- package/ios/Extension/ChapterMetadata+AVFoundation.swift +37 -0
- package/ios/Extension/TimedMetadata+AVFoundation.swift +126 -0
- package/ios/Extension/Track+AVPlayer.swift +68 -0
- package/ios/Extension/TrackMetadata+AVFoundation.swift +128 -0
- package/ios/Http/HttpClient.swift +237 -0
- package/ios/HybridAudioBrowser.swift +1309 -0
- package/ios/Model/MediaURL.swift +66 -0
- package/ios/Model/PlayerUpdateOptions.swift +116 -0
- package/ios/Model/RemoteCommand.swift +71 -0
- package/ios/Model/SourceType.swift +6 -0
- package/ios/Model/TrackPlayerError.swift +69 -0
- package/ios/NowPlayingInfo/MediaItemProperty.swift +78 -0
- package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +9 -0
- package/ios/NowPlayingInfo/NowPlayingInfoController.swift +283 -0
- package/ios/NowPlayingInfo/NowPlayingInfoKeyValue.swift +6 -0
- package/ios/NowPlayingInfo/NowPlayingInfoProperty.swift +220 -0
- package/ios/Observer/PlayerItemNotificationObserver.swift +83 -0
- package/ios/Observer/PlayerItemPropertyObserver.swift +110 -0
- package/ios/Observer/PlayerStateObserver.swift +52 -0
- package/ios/Observer/PlayerTimeObserver.swift +109 -0
- package/ios/Option/PitchAlgorithms.swift +17 -0
- package/ios/Option/SessionCategories.swift +100 -0
- package/ios/Option/TimeEventFrequency.swift +18 -0
- package/ios/Player/PlaybackProgressUpdateManager.swift +60 -0
- package/ios/Player/PlayingStateManager.swift +29 -0
- package/ios/Player/RetryManager.swift +281 -0
- package/ios/Player/ShuffleOrder.swift +191 -0
- package/ios/Player/SleepTimerManager.swift +137 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +400 -0
- package/ios/Support/RNTrackPlayer-Bridging-Header.h +7 -0
- package/ios/TrackPlayer.swift +1590 -0
- package/ios/TrackPlayerCallbacks.swift +121 -0
- package/ios/Util/Emitter.swift +46 -0
- package/ios/Util/LRUCache.swift +182 -0
- package/ios/Util/MetadataAdapter.swift +131 -0
- package/ios/Util/NetworkMonitor.swift +68 -0
- package/ios/Util/OnceValue.swift +70 -0
- package/ios/Util/SVGProcessor.swift +56 -0
- package/lib/commonjs/AudioBrowser.js +50 -0
- package/lib/commonjs/AudioBrowser.js.map +1 -0
- package/lib/commonjs/features/battery.js +154 -0
- package/lib/commonjs/features/battery.js.map +1 -0
- package/lib/commonjs/features/browser.js +271 -0
- package/lib/commonjs/features/browser.js.map +1 -0
- package/lib/commonjs/features/equalizer.js +69 -0
- package/lib/commonjs/features/equalizer.js.map +1 -0
- package/lib/commonjs/features/errors.js +165 -0
- package/lib/commonjs/features/errors.js.map +1 -0
- package/lib/commonjs/features/favorites.js +101 -0
- package/lib/commonjs/features/favorites.js.map +1 -0
- package/lib/commonjs/features/index.js +160 -0
- package/lib/commonjs/features/index.js.map +1 -0
- package/lib/commonjs/features/metadata.js +54 -0
- package/lib/commonjs/features/metadata.js.map +1 -0
- package/lib/commonjs/features/network.js +40 -0
- package/lib/commonjs/features/network.js.map +1 -0
- package/lib/commonjs/features/nowPlaying.js +61 -0
- package/lib/commonjs/features/nowPlaying.js.map +1 -0
- package/lib/commonjs/features/output.js +54 -0
- package/lib/commonjs/features/output.js.map +1 -0
- package/lib/commonjs/features/playback/controls.js +79 -0
- package/lib/commonjs/features/playback/controls.js.map +1 -0
- package/lib/commonjs/features/playback/index.js +83 -0
- package/lib/commonjs/features/playback/index.js.map +1 -0
- package/lib/commonjs/features/playback/playWhenReady.js +55 -0
- package/lib/commonjs/features/playback/playWhenReady.js.map +1 -0
- package/lib/commonjs/features/playback/playing.js +41 -0
- package/lib/commonjs/features/playback/playing.js.map +1 -0
- package/lib/commonjs/features/playback/progress.js +104 -0
- package/lib/commonjs/features/playback/progress.js.map +1 -0
- package/lib/commonjs/features/playback/rate.js +29 -0
- package/lib/commonjs/features/playback/rate.js.map +1 -0
- package/lib/commonjs/features/playback/state.js +62 -0
- package/lib/commonjs/features/playback/state.js.map +1 -0
- package/lib/commonjs/features/playback/volume.js +68 -0
- package/lib/commonjs/features/playback/volume.js.map +1 -0
- package/lib/commonjs/features/player/index.js +28 -0
- package/lib/commonjs/features/player/index.js.map +1 -0
- package/lib/commonjs/features/player/options.js +182 -0
- package/lib/commonjs/features/player/options.js.map +1 -0
- package/lib/commonjs/features/player/setup.js +143 -0
- package/lib/commonjs/features/player/setup.js.map +1 -0
- package/lib/commonjs/features/queue/activeTrack.js +52 -0
- package/lib/commonjs/features/queue/activeTrack.js.map +1 -0
- package/lib/commonjs/features/queue/index.js +50 -0
- package/lib/commonjs/features/queue/index.js.map +1 -0
- package/lib/commonjs/features/queue/queue.js +177 -0
- package/lib/commonjs/features/queue/queue.js.map +1 -0
- package/lib/commonjs/features/queue/repeatMode.js +58 -0
- package/lib/commonjs/features/queue/repeatMode.js.map +1 -0
- package/lib/commonjs/features/queue/shuffle.js +57 -0
- package/lib/commonjs/features/queue/shuffle.js.map +1 -0
- package/lib/commonjs/features/rating.js +2 -0
- package/lib/commonjs/features/rating.js.map +1 -0
- package/lib/commonjs/features/remoteControls.js +286 -0
- package/lib/commonjs/features/remoteControls.js.map +1 -0
- package/lib/commonjs/features/sleepTimer.js +164 -0
- package/lib/commonjs/features/sleepTimer.js.map +1 -0
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/native.js +9 -0
- package/lib/commonjs/native.js.map +1 -0
- package/lib/commonjs/native.web.js +10 -0
- package/lib/commonjs/native.web.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/audio-browser.nitro.js +6 -0
- package/lib/commonjs/specs/audio-browser.nitro.js.map +1 -0
- package/lib/commonjs/types/browser-native.js +6 -0
- package/lib/commonjs/types/browser-native.js.map +1 -0
- package/lib/commonjs/types/browser-nodes.js +6 -0
- package/lib/commonjs/types/browser-nodes.js.map +1 -0
- package/lib/commonjs/types/browser.js +6 -0
- package/lib/commonjs/types/browser.js.map +1 -0
- package/lib/commonjs/types/index.js +28 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/player.js +2 -0
- package/lib/commonjs/types/player.js.map +1 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js +58 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -0
- package/lib/commonjs/utils/NativeUpdatedValue.js +59 -0
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -0
- package/lib/commonjs/utils/resolveAssetSource.js +11 -0
- package/lib/commonjs/utils/resolveAssetSource.js.map +1 -0
- package/lib/commonjs/utils/useDebug.js +221 -0
- package/lib/commonjs/utils/useDebug.js.map +1 -0
- package/lib/commonjs/utils/useNativeUpdatedValue.js +44 -0
- package/lib/commonjs/utils/useNativeUpdatedValue.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +668 -0
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -0
- package/lib/commonjs/web/SimpleRouter.js +144 -0
- package/lib/commonjs/web/SimpleRouter.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Event.js +19 -0
- package/lib/commonjs/web/TrackPlayer/Event.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +276 -0
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +284 -0
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +12 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/SetupNotCalledError.js +13 -0
- package/lib/commonjs/web/TrackPlayer/SetupNotCalledError.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +75 -0
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/State.js +18 -0
- package/lib/commonjs/web/TrackPlayer/State.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/index.js +52 -0
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -0
- package/lib/commonjs/web/browser/BrowserManager.js +594 -0
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -0
- package/lib/commonjs/web/browser/FavoriteManager.js +80 -0
- package/lib/commonjs/web/browser/FavoriteManager.js.map +1 -0
- package/lib/commonjs/web/browser/NavigationErrorManager.js +106 -0
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -0
- package/lib/commonjs/web/browser/SearchManager.js +80 -0
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -0
- package/lib/commonjs/web/http/HttpClient.js +81 -0
- package/lib/commonjs/web/http/HttpClient.js.map +1 -0
- package/lib/commonjs/web/http/RequestConfigBuilder.js +294 -0
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -0
- package/lib/commonjs/web/player/NowPlayingManager.js +70 -0
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -0
- package/lib/commonjs/web/player/OptionsManager.js +88 -0
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -0
- package/lib/commonjs/web/util/BrowserPathHelper.js +138 -0
- package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -0
- package/lib/commonjs/web/util/shuffle.js +21 -0
- package/lib/commonjs/web/util/shuffle.js.map +1 -0
- package/lib/module/AudioBrowser.js +7 -0
- package/lib/module/AudioBrowser.js.map +1 -0
- package/lib/module/features/battery.js +144 -0
- package/lib/module/features/battery.js.map +1 -0
- package/lib/module/features/browser.js +257 -0
- package/lib/module/features/browser.js.map +1 -0
- package/lib/module/features/equalizer.js +60 -0
- package/lib/module/features/equalizer.js.map +1 -0
- package/lib/module/features/errors.js +156 -0
- package/lib/module/features/errors.js.map +1 -0
- package/lib/module/features/favorites.js +95 -0
- package/lib/module/features/favorites.js.map +1 -0
- package/lib/module/features/index.js +26 -0
- package/lib/module/features/index.js.map +1 -0
- package/lib/module/features/metadata.js +51 -0
- package/lib/module/features/metadata.js.map +1 -0
- package/lib/module/features/network.js +35 -0
- package/lib/module/features/network.js.map +1 -0
- package/lib/module/features/nowPlaying.js +54 -0
- package/lib/module/features/nowPlaying.js.map +1 -0
- package/lib/module/features/output.js +47 -0
- package/lib/module/features/output.js.map +1 -0
- package/lib/module/features/playback/controls.js +69 -0
- package/lib/module/features/playback/controls.js.map +1 -0
- package/lib/module/features/playback/index.js +10 -0
- package/lib/module/features/playback/index.js.map +1 -0
- package/lib/module/features/playback/playWhenReady.js +49 -0
- package/lib/module/features/playback/playWhenReady.js.map +1 -0
- package/lib/module/features/playback/playing.js +36 -0
- package/lib/module/features/playback/playing.js.map +1 -0
- package/lib/module/features/playback/progress.js +98 -0
- package/lib/module/features/playback/progress.js.map +1 -0
- package/lib/module/features/playback/rate.js +25 -0
- package/lib/module/features/playback/rate.js.map +1 -0
- package/lib/module/features/playback/state.js +57 -0
- package/lib/module/features/playback/state.js.map +1 -0
- package/lib/module/features/playback/volume.js +60 -0
- package/lib/module/features/playback/volume.js.map +1 -0
- package/lib/module/features/player/index.js +5 -0
- package/lib/module/features/player/index.js.map +1 -0
- package/lib/module/features/player/options.js +176 -0
- package/lib/module/features/player/options.js.map +1 -0
- package/lib/module/features/player/setup.js +140 -0
- package/lib/module/features/player/setup.js.map +1 -0
- package/lib/module/features/queue/activeTrack.js +46 -0
- package/lib/module/features/queue/activeTrack.js.map +1 -0
- package/lib/module/features/queue/index.js +7 -0
- package/lib/module/features/queue/index.js.map +1 -0
- package/lib/module/features/queue/queue.js +162 -0
- package/lib/module/features/queue/queue.js.map +1 -0
- package/lib/module/features/queue/repeatMode.js +52 -0
- package/lib/module/features/queue/repeatMode.js.map +1 -0
- package/lib/module/features/queue/shuffle.js +50 -0
- package/lib/module/features/queue/shuffle.js.map +1 -0
- package/lib/module/features/rating.js +2 -0
- package/lib/module/features/rating.js.map +1 -0
- package/lib/module/features/remoteControls.js +275 -0
- package/lib/module/features/remoteControls.js.map +1 -0
- package/lib/module/features/sleepTimer.js +155 -0
- package/lib/module/features/sleepTimer.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native.js +5 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/native.web.js +7 -0
- package/lib/module/native.web.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/specs/audio-browser.nitro.js +4 -0
- package/lib/module/specs/audio-browser.nitro.js.map +1 -0
- package/lib/module/types/browser-native.js +4 -0
- package/lib/module/types/browser-native.js.map +1 -0
- package/lib/module/types/browser-nodes.js +4 -0
- package/lib/module/types/browser-nodes.js.map +1 -0
- package/lib/module/types/browser.js +4 -0
- package/lib/module/types/browser.js.map +1 -0
- package/lib/module/types/index.js +5 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/player.js +2 -0
- package/lib/module/types/player.js.map +1 -0
- package/lib/module/utils/LazyNativeEmitter.js +53 -0
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -0
- package/lib/module/utils/NativeUpdatedValue.js +54 -0
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -0
- package/lib/module/utils/resolveAssetSource.js +7 -0
- package/lib/module/utils/resolveAssetSource.js.map +1 -0
- package/lib/module/utils/useDebug.js +218 -0
- package/lib/module/utils/useDebug.js.map +1 -0
- package/lib/module/utils/useNativeUpdatedValue.js +40 -0
- package/lib/module/utils/useNativeUpdatedValue.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +664 -0
- package/lib/module/web/NativeAudioBrowser.js.map +1 -0
- package/lib/module/web/SimpleRouter.js +139 -0
- package/lib/module/web/SimpleRouter.js.map +1 -0
- package/lib/module/web/TrackPlayer/Event.js +15 -0
- package/lib/module/web/TrackPlayer/Event.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +271 -0
- package/lib/module/web/TrackPlayer/Player.js.map +1 -0
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +279 -0
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +8 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -0
- package/lib/module/web/TrackPlayer/SetupNotCalledError.js +8 -0
- package/lib/module/web/TrackPlayer/SetupNotCalledError.js.map +1 -0
- package/lib/module/web/TrackPlayer/SleepTimer.js +70 -0
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -0
- package/lib/module/web/TrackPlayer/State.js +14 -0
- package/lib/module/web/TrackPlayer/State.js.map +1 -0
- package/lib/module/web/TrackPlayer/index.js +7 -0
- package/lib/module/web/TrackPlayer/index.js.map +1 -0
- package/lib/module/web/browser/BrowserManager.js +590 -0
- package/lib/module/web/browser/BrowserManager.js.map +1 -0
- package/lib/module/web/browser/FavoriteManager.js +75 -0
- package/lib/module/web/browser/FavoriteManager.js.map +1 -0
- package/lib/module/web/browser/NavigationErrorManager.js +101 -0
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -0
- package/lib/module/web/browser/SearchManager.js +76 -0
- package/lib/module/web/browser/SearchManager.js.map +1 -0
- package/lib/module/web/http/HttpClient.js +76 -0
- package/lib/module/web/http/HttpClient.js.map +1 -0
- package/lib/module/web/http/RequestConfigBuilder.js +291 -0
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -0
- package/lib/module/web/player/NowPlayingManager.js +65 -0
- package/lib/module/web/player/NowPlayingManager.js.map +1 -0
- package/lib/module/web/player/OptionsManager.js +83 -0
- package/lib/module/web/player/OptionsManager.js.map +1 -0
- package/lib/module/web/util/BrowserPathHelper.js +134 -0
- package/lib/module/web/util/BrowserPathHelper.js.map +1 -0
- package/lib/module/web/util/shuffle.js +17 -0
- package/lib/module/web/util/shuffle.js.map +1 -0
- package/lib/typescript/src/AudioBrowser.d.ts +5 -0
- package/lib/typescript/src/AudioBrowser.d.ts.map +1 -0
- package/lib/typescript/src/features/battery.d.ts +112 -0
- package/lib/typescript/src/features/battery.d.ts.map +1 -0
- package/lib/typescript/src/features/browser.d.ts +68 -0
- package/lib/typescript/src/features/browser.d.ts.map +1 -0
- package/lib/typescript/src/features/equalizer.d.ts +35 -0
- package/lib/typescript/src/features/equalizer.d.ts.map +1 -0
- package/lib/typescript/src/features/errors.d.ts +136 -0
- package/lib/typescript/src/features/errors.d.ts.map +1 -0
- package/lib/typescript/src/features/favorites.d.ts +84 -0
- package/lib/typescript/src/features/favorites.d.ts.map +1 -0
- package/lib/typescript/src/features/index.d.ts +23 -0
- package/lib/typescript/src/features/index.d.ts.map +1 -0
- package/lib/typescript/src/features/metadata.d.ts +103 -0
- package/lib/typescript/src/features/metadata.d.ts.map +1 -0
- package/lib/typescript/src/features/network.d.ts +18 -0
- package/lib/typescript/src/features/network.d.ts.map +1 -0
- package/lib/typescript/src/features/nowPlaying.d.ts +36 -0
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -0
- package/lib/typescript/src/features/output.d.ts +28 -0
- package/lib/typescript/src/features/output.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/controls.d.ts +40 -0
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/index.d.ts +8 -0
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/playWhenReady.d.ts +30 -0
- package/lib/typescript/src/features/playback/playWhenReady.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/playing.d.ts +21 -0
- package/lib/typescript/src/features/playback/playing.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/progress.d.ts +51 -0
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/rate.d.ts +12 -0
- package/lib/typescript/src/features/playback/rate.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/state.d.ts +43 -0
- package/lib/typescript/src/features/playback/state.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/volume.d.ts +32 -0
- package/lib/typescript/src/features/playback/volume.d.ts.map +1 -0
- package/lib/typescript/src/features/player/index.d.ts +3 -0
- package/lib/typescript/src/features/player/index.d.ts.map +1 -0
- package/lib/typescript/src/features/player/options.d.ts +413 -0
- package/lib/typescript/src/features/player/options.d.ts.map +1 -0
- package/lib/typescript/src/features/player/setup.d.ts +471 -0
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/activeTrack.d.ts +38 -0
- package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/index.d.ts +5 -0
- package/lib/typescript/src/features/queue/index.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/queue.d.ts +111 -0
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/repeatMode.d.ts +34 -0
- package/lib/typescript/src/features/queue/repeatMode.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/shuffle.d.ts +27 -0
- package/lib/typescript/src/features/queue/shuffle.d.ts.map +1 -0
- package/lib/typescript/src/features/rating.d.ts +14 -0
- package/lib/typescript/src/features/rating.d.ts.map +1 -0
- package/lib/typescript/src/features/remoteControls.d.ts +164 -0
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -0
- package/lib/typescript/src/features/sleepTimer.d.ts +80 -0
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/native.d.ts +3 -0
- package/lib/typescript/src/native.d.ts.map +1 -0
- package/lib/typescript/src/native.web.d.ts +3 -0
- package/lib/typescript/src/native.web.d.ts.map +1 -0
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +242 -0
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -0
- package/lib/typescript/src/types/browser-native.d.ts +39 -0
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -0
- package/lib/typescript/src/types/browser-nodes.d.ts +153 -0
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -0
- package/lib/typescript/src/types/browser.d.ts +710 -0
- package/lib/typescript/src/types/browser.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +3 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/types/player.d.ts +64 -0
- package/lib/typescript/src/types/player.d.ts.map +1 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +35 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -0
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +39 -0
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts +4 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -0
- package/lib/typescript/src/utils/useDebug.d.ts +65 -0
- package/lib/typescript/src/utils/useDebug.d.ts.map +1 -0
- package/lib/typescript/src/utils/useNativeUpdatedValue.d.ts +14 -0
- package/lib/typescript/src/utils/useNativeUpdatedValue.d.ts.map +1 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +176 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +1 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts +40 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts +11 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +71 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +39 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +6 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +4 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +34 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts +13 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts +5 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts +154 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts +42 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +40 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts +22 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +1 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts +25 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +1 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +98 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +1 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts +34 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +1 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts +32 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +1 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +69 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +1 -0
- package/lib/typescript/src/web/util/shuffle.d.ts +8 -0
- package/lib/typescript/src/web/util/shuffle.d.ts.map +1 -0
- package/nitro.json +24 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +88 -0
- package/nitrogen/generated/android/AudioBrowser+autolinking.gradle +27 -0
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +124 -0
- package/nitrogen/generated/android/AudioBrowserOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +68 -0
- package/nitrogen/generated/android/c++/JAndroidAudioOffloadSettings.hpp +61 -0
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JAndroidPlayerWakeMode.hpp +62 -0
- package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JAppKilledPlaybackBehavior.hpp +62 -0
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +163 -0
- package/nitrogen/generated/android/c++/JBatteryOptimizationStatus.hpp +62 -0
- package/nitrogen/generated/android/c++/JBatteryOptimizationStatusChangedEvent.hpp +58 -0
- package/nitrogen/generated/android/c++/JBatteryWarningPendingChangedEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JBrowseError.hpp +57 -0
- package/nitrogen/generated/android/c++/JBrowseResult.cpp +26 -0
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +83 -0
- package/nitrogen/generated/android/c++/JBrowserSourceCallbackParam.hpp +76 -0
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +65 -0
- package/nitrogen/generated/android/c++/JChapterMetadata.hpp +70 -0
- package/nitrogen/generated/android/c++/JEqualizerSettings.hpp +125 -0
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +71 -0
- package/nitrogen/generated/android/c++/JFormatNavigationErrorParams.hpp +72 -0
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +61 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.hpp +111 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.hpp +134 -0
- 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 +143 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +136 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +143 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +157 -0
- package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_BatteryOptimizationStatusChangedEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_BatteryWarningPendingChangedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_EqualizerSettings.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +88 -0
- package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_NavigationErrorEvent.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +89 -0
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +98 -0
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +88 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +81 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackPlayWhenReadyChangedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackProgressUpdatedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackQueueEndedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlayingState.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpBackwardEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpForwardEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemotePlayIdEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemotePlaySearchEvent.hpp +78 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSeekEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +87 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSkipEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RepeatModeChangedEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_TrackMetadata.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_FormattedNavigationError_.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +89 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.hpp +84 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_ChapterMetadata_.hpp +98 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +105 -0
- package/nitrogen/generated/android/c++/JHeartRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JHttpMethod.hpp +74 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +1811 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +250 -0
- package/nitrogen/generated/android/c++/JIOSCategory.hpp +71 -0
- package/nitrogen/generated/android/c++/JIOSCategoryMode.hpp +80 -0
- package/nitrogen/generated/android/c++/JIOSCategoryOptions.hpp +74 -0
- package/nitrogen/generated/android/c++/JIOSCategoryPolicy.hpp +62 -0
- package/nitrogen/generated/android/c++/JImageContext.hpp +61 -0
- package/nitrogen/generated/android/c++/JImageQueryParams.hpp +62 -0
- package/nitrogen/generated/android/c++/JImageSource.hpp +86 -0
- package/nitrogen/generated/android/c++/JIosOutput.hpp +67 -0
- package/nitrogen/generated/android/c++/JIosOutputType.hpp +86 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +153 -0
- package/nitrogen/generated/android/c++/JMediaTransformParams.hpp +69 -0
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +196 -0
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +147 -0
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +105 -0
- package/nitrogen/generated/android/c++/JNavigationError.hpp +72 -0
- package/nitrogen/generated/android/c++/JNavigationErrorEvent.hpp +62 -0
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +68 -0
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JNotificationButton.hpp +68 -0
- package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +94 -0
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +104 -0
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +62 -0
- package/nitrogen/generated/android/c++/JOptions.hpp +97 -0
- package/nitrogen/generated/android/c++/JPartialAndroidSetupPlayerOptions.hpp +104 -0
- package/nitrogen/generated/android/c++/JPartialIOSSetupPlayerOptions.hpp +100 -0
- package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JPercentageRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +66 -0
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +83 -0
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +61 -0
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +60 -0
- package/nitrogen/generated/android/c++/JPlaybackPlayWhenReadyChangedEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JPlaybackProgressUpdatedEvent.hpp +69 -0
- package/nitrogen/generated/android/c++/JPlaybackQueueEndedEvent.hpp +61 -0
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +80 -0
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +101 -0
- package/nitrogen/generated/android/c++/JPlayingState.hpp +61 -0
- package/nitrogen/generated/android/c++/JProgress.hpp +65 -0
- package/nitrogen/generated/android/c++/JRatingType.hpp +74 -0
- package/nitrogen/generated/android/c++/JRemoteJumpBackwardEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteJumpForwardEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemotePlayIdEvent.hpp +62 -0
- package/nitrogen/generated/android/c++/JRemotePlaySearchEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteSeekEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +66 -0
- package/nitrogen/generated/android/c++/JRemoteSkipEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRepeatMode.hpp +62 -0
- package/nitrogen/generated/android/c++/JRepeatModeChangedEvent.hpp +58 -0
- package/nitrogen/generated/android/c++/JRequestConfig.hpp +115 -0
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +154 -0
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +61 -0
- package/nitrogen/generated/android/c++/JSearchMode.hpp +71 -0
- package/nitrogen/generated/android/c++/JSearchParams.hpp +84 -0
- package/nitrogen/generated/android/c++/JSleepTimer.cpp +30 -0
- package/nitrogen/generated/android/c++/JSleepTimer.hpp +88 -0
- package/nitrogen/generated/android/c++/JSleepTimerEndOfTrack.hpp +57 -0
- package/nitrogen/generated/android/c++/JSleepTimerTime.hpp +57 -0
- package/nitrogen/generated/android/c++/JStarRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JThumbsRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JTimedMetadata.hpp +74 -0
- package/nitrogen/generated/android/c++/JTrack.hpp +129 -0
- package/nitrogen/generated/android/c++/JTrackMetadata.hpp +118 -0
- package/nitrogen/generated/android/c++/JTrackStyle.hpp +59 -0
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +134 -0
- package/nitrogen/generated/android/c++/JUpdateOptions.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.hpp +70 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.hpp +70 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +34 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +69 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioOffloadSettings.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidPlayerWakeMode.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AppKilledPlaybackBehavior.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AudioBrowserOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatus.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatusChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryWarningPendingChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseError.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseResult.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowserSourceCallbackParam.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ChapterMetadata.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/EqualizerSettings.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteChangedEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNavigationErrorParams.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.kt +80 -0
- 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 +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryOptimizationStatusChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryWarningPendingChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_EqualizerSettings.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_FavoriteChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_IosOutput.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NavigationErrorEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NowPlayingMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Options.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Playback.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackActiveTrackChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackErrorEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackPlayWhenReadyChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackProgressUpdatedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackQueueEndedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlayingState.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpBackwardEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpForwardEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlayIdEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlaySearchEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSeekEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSetRatingEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSkipEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RepeatModeChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TimedMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TrackMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_FormattedNavigationError_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_ResolvedTrack_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_ChapterMetadata_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_Track_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HeartRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HttpMethod.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +1137 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategory.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryMode.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryOptions.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryPolicy.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageContext.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageQueryParams.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageSource.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutput.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +30 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaTransformParams.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +63 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationError.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialAndroidSetupPlayerOptions.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialIOSSetupPlayerOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PercentageRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Playback.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackActiveTrackChangedEvent.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackPlayWhenReadyChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackProgressUpdatedEvent.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackQueueEndedEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +71 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayingState.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Progress.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RatingType.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpBackwardEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpForwardEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlayIdEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlaySearchEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSeekEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSetRatingEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSkipEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatMode.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatModeChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RequestConfig.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +89 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimer.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerEndOfTrack.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerTime.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StarRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ThumbsRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TimedMetadata.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +86 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackMetadata.kt +83 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackStyle.kt +21 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_AndroidAudioOffloadSettings.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_RetryConfig.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +85 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_Double.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_NotificationButtonLayout.kt +59 -0
- package/nitrogen/generated/ios/AudioBrowser+autolinking.rb +60 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +407 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +2822 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +300 -0
- package/nitrogen/generated/ios/AudioBrowserAutolinking.mm +33 -0
- package/nitrogen/generated/ios/AudioBrowserAutolinking.swift +25 -0
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +1190 -0
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +52 -0
- package/nitrogen/generated/ios/swift/AndroidAudioOffloadSettings.swift +85 -0
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +125 -0
- package/nitrogen/generated/ios/swift/AndroidPlayerWakeMode.swift +44 -0
- package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +187 -0
- package/nitrogen/generated/ios/swift/AppKilledPlaybackBehavior.swift +44 -0
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +445 -0
- package/nitrogen/generated/ios/swift/BatteryOptimizationStatus.swift +44 -0
- package/nitrogen/generated/ios/swift/BatteryOptimizationStatusChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/BatteryWarningPendingChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/BrowseError.swift +36 -0
- package/nitrogen/generated/ios/swift/BrowseResult.swift +18 -0
- package/nitrogen/generated/ios/swift/BrowserSourceCallbackParam.swift +86 -0
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +48 -0
- package/nitrogen/generated/ios/swift/ChapterMetadata.swift +107 -0
- package/nitrogen/generated/ios/swift/EqualizerSettings.swift +168 -0
- package/nitrogen/generated/ios/swift/FavoriteChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/FormatNavigationErrorParams.swift +58 -0
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.swift +62 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +77 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.swift +62 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.swift +68 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_BatteryOptimizationStatusChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_BatteryWarningPendingChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_EqualizerSettings.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_FavoriteChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_IosOutput.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NavigationErrorEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NowPlayingMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_Options.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_Playback.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackActiveTrackChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackErrorEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackPlayWhenReadyChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackProgressUpdatedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackQueueEndedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlayingState.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteJumpBackwardEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteJumpForwardEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemotePlayIdEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemotePlaySearchEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSeekEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSetRatingEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSkipEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RepeatModeChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RequestConfig.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_TimedMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_TrackMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_double.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_FormattedNavigationError_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_ResolvedTrack_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_RequestConfig__.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__vector_Track___.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError_.swift +59 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_ChapterMetadata_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_Track_.swift +47 -0
- package/nitrogen/generated/ios/swift/HeartRating.swift +36 -0
- package/nitrogen/generated/ios/swift/HttpMethod.swift +60 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +181 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2352 -0
- package/nitrogen/generated/ios/swift/IOSCategory.swift +56 -0
- package/nitrogen/generated/ios/swift/IOSCategoryMode.swift +68 -0
- package/nitrogen/generated/ios/swift/IOSCategoryOptions.swift +60 -0
- package/nitrogen/generated/ios/swift/IOSCategoryPolicy.swift +44 -0
- package/nitrogen/generated/ios/swift/ImageContext.swift +71 -0
- package/nitrogen/generated/ios/swift/ImageQueryParams.swift +85 -0
- package/nitrogen/generated/ios/swift/ImageSource.swift +139 -0
- package/nitrogen/generated/ios/swift/IosOutput.swift +58 -0
- package/nitrogen/generated/ios/swift/IosOutputType.swift +76 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +434 -0
- package/nitrogen/generated/ios/swift/MediaTransformParams.swift +59 -0
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +360 -0
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +275 -0
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +215 -0
- package/nitrogen/generated/ios/swift/NavigationError.swift +100 -0
- package/nitrogen/generated/ios/swift/NavigationErrorEvent.swift +48 -0
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +52 -0
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +187 -0
- package/nitrogen/generated/ios/swift/NotificationButton.swift +52 -0
- package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +159 -0
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +351 -0
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +85 -0
- package/nitrogen/generated/ios/swift/Options.swift +148 -0
- package/nitrogen/generated/ios/swift/PartialAndroidSetupPlayerOptions.swift +328 -0
- package/nitrogen/generated/ios/swift/PartialIOSSetupPlayerOptions.swift +159 -0
- package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +157 -0
- package/nitrogen/generated/ios/swift/PercentageRating.swift +36 -0
- package/nitrogen/generated/ios/swift/Playback.swift +59 -0
- package/nitrogen/generated/ios/swift/PlaybackActiveTrackChangedEvent.swift +128 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +47 -0
- package/nitrogen/generated/ios/swift/PlaybackErrorEvent.swift +48 -0
- package/nitrogen/generated/ios/swift/PlaybackPlayWhenReadyChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/PlaybackProgressUpdatedEvent.swift +69 -0
- package/nitrogen/generated/ios/swift/PlaybackQueueEndedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/PlaybackState.swift +68 -0
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +385 -0
- package/nitrogen/generated/ios/swift/PlayingState.swift +47 -0
- package/nitrogen/generated/ios/swift/Progress.swift +58 -0
- package/nitrogen/generated/ios/swift/RatingType.swift +60 -0
- package/nitrogen/generated/ios/swift/RemoteJumpBackwardEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteJumpForwardEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemotePlayIdEvent.swift +59 -0
- package/nitrogen/generated/ios/swift/RemotePlaySearchEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteSeekEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +76 -0
- package/nitrogen/generated/ios/swift/RemoteSkipEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RepeatMode.swift +44 -0
- package/nitrogen/generated/ios/swift/RepeatModeChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RequestConfig.swift +298 -0
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +511 -0
- package/nitrogen/generated/ios/swift/RetryConfig.swift +59 -0
- package/nitrogen/generated/ios/swift/SearchMode.swift +56 -0
- package/nitrogen/generated/ios/swift/SearchParams.swift +209 -0
- package/nitrogen/generated/ios/swift/SleepTimer.swift +19 -0
- package/nitrogen/generated/ios/swift/SleepTimerEndOfTrack.swift +36 -0
- package/nitrogen/generated/ios/swift/SleepTimerTime.swift +36 -0
- package/nitrogen/generated/ios/swift/StarRating.swift +36 -0
- package/nitrogen/generated/ios/swift/ThumbsRating.swift +36 -0
- package/nitrogen/generated/ios/swift/TimedMetadata.swift +175 -0
- package/nitrogen/generated/ios/swift/Track.swift +488 -0
- package/nitrogen/generated/ios/swift/TrackMetadata.swift +505 -0
- package/nitrogen/generated/ios/swift/TrackStyle.swift +40 -0
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +372 -0
- package/nitrogen/generated/ios/swift/UpdateOptions.swift +215 -0
- package/nitrogen/generated/ios/swift/Variant_Bool_AndroidAudioOffloadSettings.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_Bool_RetryConfig.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +20 -0
- package/nitrogen/generated/ios/swift/Variant_NullType_Double.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_NullType_NotificationButtonLayout.swift +18 -0
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +88 -0
- package/nitrogen/generated/shared/c++/AndroidAudioOffloadSettings.hpp +79 -0
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/AndroidPlayerWakeMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/AppKilledPlaybackBehavior.hpp +80 -0
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +133 -0
- package/nitrogen/generated/shared/c++/BatteryOptimizationStatus.hpp +80 -0
- package/nitrogen/generated/shared/c++/BatteryOptimizationStatusChangedEvent.hpp +76 -0
- package/nitrogen/generated/shared/c++/BatteryWarningPendingChangedEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/BrowseError.hpp +75 -0
- package/nitrogen/generated/shared/c++/BrowserSourceCallbackParam.hpp +81 -0
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +84 -0
- package/nitrogen/generated/shared/c++/ChapterMetadata.hpp +88 -0
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +105 -0
- package/nitrogen/generated/shared/c++/FavoriteChangedEvent.hpp +80 -0
- package/nitrogen/generated/shared/c++/FormatNavigationErrorParams.hpp +88 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +79 -0
- package/nitrogen/generated/shared/c++/HeartRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/HttpMethod.hpp +96 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +207 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +375 -0
- package/nitrogen/generated/shared/c++/IOSCategory.hpp +92 -0
- package/nitrogen/generated/shared/c++/IOSCategoryMode.hpp +104 -0
- package/nitrogen/generated/shared/c++/IOSCategoryOptions.hpp +96 -0
- package/nitrogen/generated/shared/c++/IOSCategoryPolicy.hpp +80 -0
- package/nitrogen/generated/shared/c++/ImageContext.hpp +79 -0
- package/nitrogen/generated/shared/c++/ImageQueryParams.hpp +80 -0
- package/nitrogen/generated/shared/c++/ImageSource.hpp +91 -0
- package/nitrogen/generated/shared/c++/IosOutput.hpp +85 -0
- package/nitrogen/generated/shared/c++/IosOutputType.hpp +112 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +123 -0
- package/nitrogen/generated/shared/c++/MediaTransformParams.hpp +84 -0
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +135 -0
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +131 -0
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +103 -0
- package/nitrogen/generated/shared/c++/NavigationError.hpp +90 -0
- package/nitrogen/generated/shared/c++/NavigationErrorEvent.hpp +77 -0
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +88 -0
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/NotificationButton.hpp +88 -0
- package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +94 -0
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +124 -0
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +80 -0
- package/nitrogen/generated/shared/c++/Options.hpp +105 -0
- package/nitrogen/generated/shared/c++/PartialAndroidSetupPlayerOptions.hpp +121 -0
- package/nitrogen/generated/shared/c++/PartialIOSSetupPlayerOptions.hpp +103 -0
- package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +96 -0
- package/nitrogen/generated/shared/c++/PercentageRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/Playback.hpp +84 -0
- package/nitrogen/generated/shared/c++/PlaybackActiveTrackChangedEvent.hpp +93 -0
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +79 -0
- package/nitrogen/generated/shared/c++/PlaybackErrorEvent.hpp +77 -0
- package/nitrogen/generated/shared/c++/PlaybackPlayWhenReadyChangedEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/PlaybackProgressUpdatedEvent.hpp +87 -0
- package/nitrogen/generated/shared/c++/PlaybackQueueEndedEvent.hpp +79 -0
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +104 -0
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +119 -0
- package/nitrogen/generated/shared/c++/PlayingState.hpp +79 -0
- package/nitrogen/generated/shared/c++/Progress.hpp +83 -0
- package/nitrogen/generated/shared/c++/RatingType.hpp +96 -0
- package/nitrogen/generated/shared/c++/RemoteJumpBackwardEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteJumpForwardEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemotePlayIdEvent.hpp +80 -0
- package/nitrogen/generated/shared/c++/RemotePlaySearchEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteSeekEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +86 -0
- package/nitrogen/generated/shared/c++/RemoteSkipEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RepeatMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/RepeatModeChangedEvent.hpp +76 -0
- package/nitrogen/generated/shared/c++/RequestConfig.hpp +107 -0
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +153 -0
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +79 -0
- package/nitrogen/generated/shared/c++/SearchMode.hpp +92 -0
- package/nitrogen/generated/shared/c++/SearchParams.hpp +102 -0
- package/nitrogen/generated/shared/c++/SleepTimerEndOfTrack.hpp +75 -0
- package/nitrogen/generated/shared/c++/SleepTimerTime.hpp +75 -0
- package/nitrogen/generated/shared/c++/StarRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/ThumbsRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/TimedMetadata.hpp +92 -0
- package/nitrogen/generated/shared/c++/Track.hpp +145 -0
- package/nitrogen/generated/shared/c++/TrackMetadata.hpp +136 -0
- package/nitrogen/generated/shared/c++/TrackStyle.hpp +76 -0
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +116 -0
- package/nitrogen/generated/shared/c++/UpdateOptions.hpp +103 -0
- package/package.json +120 -0
- package/src/AudioBrowser.ts +4 -0
- package/src/features/battery.ts +176 -0
- package/src/features/browser.ts +315 -0
- package/src/features/equalizer.ts +64 -0
- package/src/features/errors.ts +196 -0
- package/src/features/favorites.ts +102 -0
- package/src/features/index.ts +23 -0
- package/src/features/metadata.ts +130 -0
- package/src/features/network.ts +34 -0
- package/src/features/nowPlaying.ts +56 -0
- package/src/features/output.ts +50 -0
- package/src/features/playback/controls.ts +66 -0
- package/src/features/playback/index.ts +7 -0
- package/src/features/playback/playWhenReady.ts +57 -0
- package/src/features/playback/playing.ts +40 -0
- package/src/features/playback/progress.ts +122 -0
- package/src/features/playback/rate.ts +22 -0
- package/src/features/playback/state.ts +72 -0
- package/src/features/playback/volume.ts +59 -0
- package/src/features/player/index.ts +2 -0
- package/src/features/player/options.ts +479 -0
- package/src/features/player/setup.ts +551 -0
- package/src/features/queue/activeTrack.ts +59 -0
- package/src/features/queue/index.ts +4 -0
- package/src/features/queue/queue.ts +173 -0
- package/src/features/queue/repeatMode.ts +58 -0
- package/src/features/queue/shuffle.ts +49 -0
- package/src/features/rating.ts +17 -0
- package/src/features/remoteControls.ts +341 -0
- package/src/features/sleepTimer.ts +186 -0
- package/src/index.ts +5 -0
- package/src/native.ts +5 -0
- package/src/native.web.ts +4 -0
- package/src/specs/audio-browser.nitro.ts +326 -0
- package/src/types/browser-native.ts +66 -0
- package/src/types/browser-nodes.ts +174 -0
- package/src/types/browser.ts +792 -0
- package/src/types/index.ts +2 -0
- package/src/types/player.ts +69 -0
- package/src/utils/LazyNativeEmitter.ts +58 -0
- package/src/utils/NativeUpdatedValue.ts +56 -0
- package/src/utils/resolveAssetSource.ts +4 -0
- package/src/utils/useDebug.ts +283 -0
- package/src/utils/useNativeUpdatedValue.ts +41 -0
- package/src/web/NativeAudioBrowser.ts +781 -0
- package/src/web/SimpleRouter.ts +177 -0
- package/src/web/TrackPlayer/Event.ts +11 -0
- package/src/web/TrackPlayer/Player.ts +323 -0
- package/src/web/TrackPlayer/PlaylistPlayer.ts +337 -0
- package/src/web/TrackPlayer/RepeatMode.ts +7 -0
- package/src/web/TrackPlayer/SetupNotCalledError.ts +5 -0
- package/src/web/TrackPlayer/SleepTimer.ts +71 -0
- package/src/web/TrackPlayer/State.ts +15 -0
- package/src/web/TrackPlayer/index.ts +4 -0
- package/src/web/browser/BrowserManager.ts +642 -0
- package/src/web/browser/FavoriteManager.ts +77 -0
- package/src/web/browser/NavigationErrorManager.ts +112 -0
- package/src/web/browser/SearchManager.ts +82 -0
- package/src/web/http/HttpClient.ts +107 -0
- package/src/web/http/RequestConfigBuilder.ts +347 -0
- package/src/web/player/NowPlayingManager.ts +83 -0
- package/src/web/player/OptionsManager.ts +101 -0
- package/src/web/util/BrowserPathHelper.ts +147 -0
- package/src/web/util/shuffle.ts +14 -0
|
@@ -0,0 +1,985 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
import os.log
|
|
4
|
+
|
|
5
|
+
/// Custom browser errors.
|
|
6
|
+
enum BrowserError: Error {
|
|
7
|
+
case contentNotFound(path: String)
|
|
8
|
+
case httpError(code: Int, body: String)
|
|
9
|
+
case networkError(Error)
|
|
10
|
+
case invalidConfiguration(String)
|
|
11
|
+
case callbackError(String)
|
|
12
|
+
|
|
13
|
+
var localizedDescription: String {
|
|
14
|
+
switch self {
|
|
15
|
+
case .contentNotFound:
|
|
16
|
+
return "Content not found"
|
|
17
|
+
case let .httpError(code, body):
|
|
18
|
+
// Try to extract error message from JSON response: { "error": "message" }
|
|
19
|
+
if let data = body.data(using: .utf8),
|
|
20
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
21
|
+
let errorMessage = json["error"] as? String
|
|
22
|
+
{
|
|
23
|
+
return errorMessage
|
|
24
|
+
}
|
|
25
|
+
// Fall back to localized HTTP status description
|
|
26
|
+
return HTTPURLResponse.localizedString(forStatusCode: code)
|
|
27
|
+
case let .networkError(error):
|
|
28
|
+
return "Network error: \(error.localizedDescription)"
|
|
29
|
+
case let .invalidConfiguration(message):
|
|
30
|
+
return "Invalid configuration: \(message)"
|
|
31
|
+
case let .callbackError(message):
|
|
32
|
+
return message
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// Core browser manager that handles navigation, search, and media browsing.
|
|
38
|
+
///
|
|
39
|
+
/// This class contains the main business logic for:
|
|
40
|
+
/// - Route resolution and path matching with parameter extraction
|
|
41
|
+
/// - HTTP API requests and response processing
|
|
42
|
+
/// - JavaScript callback invocation
|
|
43
|
+
/// - Fallback handling and error management
|
|
44
|
+
final class BrowserManager: @unchecked Sendable {
|
|
45
|
+
private let logger = Logger(subsystem: "com.audiobrowser", category: "BrowserManager")
|
|
46
|
+
|
|
47
|
+
// MARK: - Constants (match Kotlin companion object)
|
|
48
|
+
|
|
49
|
+
/// Internal path used for the default/root browse source
|
|
50
|
+
static let defaultRoutePath = "__default__"
|
|
51
|
+
|
|
52
|
+
/// Internal path used for navigation tabs
|
|
53
|
+
static let tabsRoutePath = "__tabs__"
|
|
54
|
+
|
|
55
|
+
/// Internal path used for search
|
|
56
|
+
static let searchRoutePath = "__search__"
|
|
57
|
+
|
|
58
|
+
// MARK: - Private Properties
|
|
59
|
+
|
|
60
|
+
private let router = SimpleRouter()
|
|
61
|
+
private let httpClient = HttpClient()
|
|
62
|
+
|
|
63
|
+
// LRU cache for individual tracks - keyed by both url and src for O(1) lookup
|
|
64
|
+
private let trackCache = LRUCache<String, Track>(maxSize: 3000)
|
|
65
|
+
|
|
66
|
+
// LRU cache for resolved content - keyed by path
|
|
67
|
+
private let contentCache = LRUCache<String, ResolvedTrack>(maxSize: 20)
|
|
68
|
+
|
|
69
|
+
// Cache for search results
|
|
70
|
+
private var lastSearchQuery: String?
|
|
71
|
+
private var lastSearchResults: [Track]?
|
|
72
|
+
|
|
73
|
+
// Set of favorited track identifiers (src)
|
|
74
|
+
private var favoriteIds: Set<String> = []
|
|
75
|
+
|
|
76
|
+
// Navigation tracking to prevent race conditions
|
|
77
|
+
private var currentNavigationId: Int = 0
|
|
78
|
+
|
|
79
|
+
// MARK: - Public State
|
|
80
|
+
|
|
81
|
+
/// Current navigation path. Must be modified on main thread.
|
|
82
|
+
private(set) var path: String = "/" {
|
|
83
|
+
didSet {
|
|
84
|
+
assertMainThread()
|
|
85
|
+
if oldValue != path {
|
|
86
|
+
onPathChanged?(path)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// Current resolved content. Must be modified on main thread.
|
|
92
|
+
private(set) var content: ResolvedTrack? {
|
|
93
|
+
didSet {
|
|
94
|
+
assertMainThread()
|
|
95
|
+
// Note: Can't compare ResolvedTrack directly, always fire callback
|
|
96
|
+
onContentChanged?(content)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Current tabs. Must be modified on main thread.
|
|
101
|
+
private(set) var tabs: [Track]? {
|
|
102
|
+
didSet {
|
|
103
|
+
assertMainThread()
|
|
104
|
+
if let tabs {
|
|
105
|
+
onTabsChanged?(tabs)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private func assertMainThread() {
|
|
111
|
+
assert(Thread.isMainThread, "BrowserManager state must be modified on main thread")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// MARK: - Configuration
|
|
115
|
+
|
|
116
|
+
/// Whether configureBrowser() has been called
|
|
117
|
+
private(set) var isConfigured = false
|
|
118
|
+
|
|
119
|
+
/// Browser configuration containing routes, search, tabs, and request settings.
|
|
120
|
+
var config: BrowserConfig = .init() {
|
|
121
|
+
didSet {
|
|
122
|
+
isConfigured = true
|
|
123
|
+
onConfigChanged?(config)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Callback to transform artwork URLs for tracks.
|
|
128
|
+
/// - Parameters:
|
|
129
|
+
/// - track: The track whose artwork URL should be transformed
|
|
130
|
+
/// - artworkConfig: Per-route artwork config (or nil to use global)
|
|
131
|
+
/// - imageContext: Optional size context for CDN URL generation (nil at browse-time)
|
|
132
|
+
var artworkUrlResolver: ((Track, ArtworkRequestConfig?, ImageContext?) async -> ImageSource?)?
|
|
133
|
+
|
|
134
|
+
// MARK: - Callbacks
|
|
135
|
+
|
|
136
|
+
var onPathChanged: ((String) -> Void)?
|
|
137
|
+
var onContentChanged: ((ResolvedTrack?) -> Void)?
|
|
138
|
+
var onTabsChanged: (([Track]) -> Void)?
|
|
139
|
+
var onConfigChanged: ((BrowserConfig) -> Void)?
|
|
140
|
+
|
|
141
|
+
// MARK: - Favorites
|
|
142
|
+
|
|
143
|
+
/// Sets the favorited track identifiers.
|
|
144
|
+
func setFavorites(_ favorites: [String]) {
|
|
145
|
+
favoriteIds = Set(favorites)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/// Updates the favorite state for a single track identifier.
|
|
149
|
+
func updateFavorite(id: String, favorited: Bool) {
|
|
150
|
+
if favorited {
|
|
151
|
+
favoriteIds.insert(id)
|
|
152
|
+
} else {
|
|
153
|
+
favoriteIds.remove(id)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/// Hydrates the favorited field on a track based on the favoriteIds set.
|
|
158
|
+
/// Local favoriteIds always take precedence over API-provided values.
|
|
159
|
+
private func hydrateFavorite(_ track: Track) -> Track {
|
|
160
|
+
guard let src = track.src else { return track }
|
|
161
|
+
|
|
162
|
+
// Check if this track is in our local favorites set
|
|
163
|
+
let isFavorited = favoriteIds.contains(src)
|
|
164
|
+
|
|
165
|
+
// Only create a new track if the favorited state differs
|
|
166
|
+
if track.favorited == isFavorited { return track }
|
|
167
|
+
|
|
168
|
+
return Track(
|
|
169
|
+
url: track.url,
|
|
170
|
+
src: track.src,
|
|
171
|
+
artwork: track.artwork,
|
|
172
|
+
artworkSource: track.artworkSource,
|
|
173
|
+
artworkCarPlayTinted: track.artworkCarPlayTinted,
|
|
174
|
+
title: track.title,
|
|
175
|
+
subtitle: track.subtitle,
|
|
176
|
+
artist: track.artist,
|
|
177
|
+
album: track.album,
|
|
178
|
+
description: track.description,
|
|
179
|
+
genre: track.genre,
|
|
180
|
+
duration: track.duration,
|
|
181
|
+
style: track.style,
|
|
182
|
+
childrenStyle: track.childrenStyle,
|
|
183
|
+
favorited: isFavorited,
|
|
184
|
+
groupTitle: track.groupTitle,
|
|
185
|
+
live: track.live,
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Hydrates favorites on all children of a ResolvedTrack.
|
|
190
|
+
private func hydrateChildren(_ resolvedTrack: ResolvedTrack) -> ResolvedTrack {
|
|
191
|
+
guard let children = resolvedTrack.children else { return resolvedTrack }
|
|
192
|
+
let hydratedChildren = children.map { hydrateFavorite($0) }
|
|
193
|
+
return ResolvedTrack(
|
|
194
|
+
url: resolvedTrack.url,
|
|
195
|
+
children: hydratedChildren,
|
|
196
|
+
src: resolvedTrack.src,
|
|
197
|
+
artwork: resolvedTrack.artwork,
|
|
198
|
+
artworkSource: resolvedTrack.artworkSource,
|
|
199
|
+
artworkCarPlayTinted: resolvedTrack.artworkCarPlayTinted,
|
|
200
|
+
title: resolvedTrack.title,
|
|
201
|
+
subtitle: resolvedTrack.subtitle,
|
|
202
|
+
artist: resolvedTrack.artist,
|
|
203
|
+
album: resolvedTrack.album,
|
|
204
|
+
description: resolvedTrack.description,
|
|
205
|
+
genre: resolvedTrack.genre,
|
|
206
|
+
duration: resolvedTrack.duration,
|
|
207
|
+
style: resolvedTrack.style,
|
|
208
|
+
childrenStyle: resolvedTrack.childrenStyle,
|
|
209
|
+
favorited: resolvedTrack.favorited,
|
|
210
|
+
groupTitle: resolvedTrack.groupTitle,
|
|
211
|
+
live: resolvedTrack.live,
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// MARK: - Track Cache
|
|
216
|
+
|
|
217
|
+
/// Cache a track by both url and src for O(1) lookup from either key.
|
|
218
|
+
private func cacheTrack(_ track: Track) {
|
|
219
|
+
if let url = track.url {
|
|
220
|
+
trackCache.set(url, value: track)
|
|
221
|
+
}
|
|
222
|
+
if let src = track.src {
|
|
223
|
+
trackCache.set(src, value: track)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private func cacheChildren(_ resolvedTrack: ResolvedTrack) {
|
|
228
|
+
resolvedTrack.children?.forEach { cacheTrack($0) }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/// Get a cached Track by mediaId (url or src), or nil if not cached.
|
|
232
|
+
func getCachedTrack(_ mediaId: String) -> Track? {
|
|
233
|
+
// Try direct lookup first (matches url or src)
|
|
234
|
+
if let track = trackCache.get(mediaId) {
|
|
235
|
+
return hydrateFavorite(track)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Try extracting src from contextual URL
|
|
239
|
+
if let trackId = BrowserPathHelper.extractTrackId(mediaId) {
|
|
240
|
+
if let track = trackCache.get(trackId) {
|
|
241
|
+
return hydrateFavorite(track)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return nil
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// MARK: - Navigation
|
|
249
|
+
|
|
250
|
+
/// Main navigation method - updates path and resolves content.
|
|
251
|
+
///
|
|
252
|
+
/// Uses a navigation ID to prevent race conditions when multiple navigations
|
|
253
|
+
/// overlap. Only the most recent navigation's result is applied.
|
|
254
|
+
@MainActor
|
|
255
|
+
func navigate(_ path: String) async throws {
|
|
256
|
+
// Increment navigation ID and capture for this navigation
|
|
257
|
+
currentNavigationId += 1
|
|
258
|
+
let navigationId = currentNavigationId
|
|
259
|
+
|
|
260
|
+
self.path = path
|
|
261
|
+
content = nil // Clear for loading state
|
|
262
|
+
|
|
263
|
+
let resolved = try await resolve(path, useCache: false)
|
|
264
|
+
|
|
265
|
+
// Only apply result if this is still the current navigation
|
|
266
|
+
guard navigationId == currentNavigationId else { return }
|
|
267
|
+
|
|
268
|
+
content = resolved
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/// Resolves content for a path with optional caching.
|
|
272
|
+
func resolve(_ path: String, useCache: Bool = true) async throws -> ResolvedTrack {
|
|
273
|
+
// Strip __trackId from contextual URLs
|
|
274
|
+
let normalizedPath = BrowserPathHelper.stripTrackId(path)
|
|
275
|
+
|
|
276
|
+
// Check content cache first
|
|
277
|
+
if useCache, let cached = contentCache.get(normalizedPath) {
|
|
278
|
+
return hydrateChildren(cached)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let resolvedTrack = try await resolveUncached(normalizedPath)
|
|
282
|
+
|
|
283
|
+
// Cache the resolved content for future navigation
|
|
284
|
+
contentCache.set(normalizedPath, value: resolvedTrack)
|
|
285
|
+
|
|
286
|
+
// Cache children for track lookups
|
|
287
|
+
cacheChildren(resolvedTrack)
|
|
288
|
+
|
|
289
|
+
return hydrateChildren(resolvedTrack)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/// Invalidates the content cache for a specific path.
|
|
293
|
+
func invalidateContentCache(_ path: String) {
|
|
294
|
+
contentCache.remove(path)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/// Refreshes the current path by invalidating cache and re-resolving.
|
|
298
|
+
///
|
|
299
|
+
/// Uses navigation ID tracking to prevent race conditions.
|
|
300
|
+
@MainActor
|
|
301
|
+
func refresh() async throws {
|
|
302
|
+
// Increment navigation ID and capture for this refresh
|
|
303
|
+
currentNavigationId += 1
|
|
304
|
+
let navigationId = currentNavigationId
|
|
305
|
+
|
|
306
|
+
let currentPath = path
|
|
307
|
+
contentCache.remove(currentPath)
|
|
308
|
+
let resolved = try await resolve(currentPath, useCache: false)
|
|
309
|
+
|
|
310
|
+
// Only apply result if this is still the current navigation
|
|
311
|
+
guard navigationId == currentNavigationId else { return }
|
|
312
|
+
|
|
313
|
+
content = resolved
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private func resolveUncached(_ path: String) async throws -> ResolvedTrack {
|
|
317
|
+
guard let routes = config.routes, !routes.isEmpty else {
|
|
318
|
+
throw BrowserError.contentNotFound(path: path)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Find best matching route
|
|
322
|
+
guard let (routeEntry, routeMatch) = findBestRouteMatch(path: path, routes: routes) else {
|
|
323
|
+
throw BrowserError.contentNotFound(path: path)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Resolve the track from the route
|
|
327
|
+
let resolvedTrack = try await resolveRouteEntry(routeEntry, path: path, params: routeMatch.params)
|
|
328
|
+
|
|
329
|
+
// Validate and transform children
|
|
330
|
+
var transformedChildren: [Track]?
|
|
331
|
+
if let children = resolvedTrack.children {
|
|
332
|
+
transformedChildren = try await transformChildren(children, parentPath: path, routeEntry: routeEntry)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if transformedChildren != nil {
|
|
336
|
+
return ResolvedTrack(
|
|
337
|
+
url: resolvedTrack.url,
|
|
338
|
+
children: transformedChildren,
|
|
339
|
+
src: resolvedTrack.src,
|
|
340
|
+
artwork: resolvedTrack.artwork,
|
|
341
|
+
artworkSource: resolvedTrack.artworkSource,
|
|
342
|
+
artworkCarPlayTinted: resolvedTrack.artworkCarPlayTinted,
|
|
343
|
+
title: resolvedTrack.title,
|
|
344
|
+
subtitle: resolvedTrack.subtitle,
|
|
345
|
+
artist: resolvedTrack.artist,
|
|
346
|
+
album: resolvedTrack.album,
|
|
347
|
+
description: resolvedTrack.description,
|
|
348
|
+
genre: resolvedTrack.genre,
|
|
349
|
+
duration: resolvedTrack.duration,
|
|
350
|
+
style: resolvedTrack.style,
|
|
351
|
+
childrenStyle: resolvedTrack.childrenStyle,
|
|
352
|
+
favorited: resolvedTrack.favorited,
|
|
353
|
+
groupTitle: resolvedTrack.groupTitle,
|
|
354
|
+
live: resolvedTrack.live,
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return resolvedTrack
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// MARK: - Route Resolution
|
|
362
|
+
|
|
363
|
+
private func findBestRouteMatch(
|
|
364
|
+
path: String,
|
|
365
|
+
routes: [NativeRouteEntry],
|
|
366
|
+
) -> (NativeRouteEntry, RouteMatch)? {
|
|
367
|
+
// Filter out special routes
|
|
368
|
+
let browseRoutes = routes.filter {
|
|
369
|
+
$0.path != Self.tabsRoutePath &&
|
|
370
|
+
$0.path != Self.searchRoutePath &&
|
|
371
|
+
$0.path != Self.defaultRoutePath
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Try to find a matching route
|
|
375
|
+
if let match = router.findBestMatch(path: path, routes: browseRoutes) {
|
|
376
|
+
return match
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Fall back to __default__ if present
|
|
380
|
+
if let defaultRoute = routes.first(where: { $0.path == Self.defaultRoutePath }) {
|
|
381
|
+
return (defaultRoute, RouteMatch(params: ["path": path]))
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return nil
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
private func resolveRouteEntry(
|
|
388
|
+
_ entry: NativeRouteEntry,
|
|
389
|
+
path: String,
|
|
390
|
+
params: [String: String],
|
|
391
|
+
) async throws -> ResolvedTrack {
|
|
392
|
+
// Priority: callback > config > static
|
|
393
|
+
if let callback = entry.browseCallback {
|
|
394
|
+
let callbackParam = BrowserSourceCallbackParam(path: path, routeParams: params)
|
|
395
|
+
// Callback returns Promise<Promise<BrowseResult>> - await both layers
|
|
396
|
+
let outerPromise = callback(callbackParam)
|
|
397
|
+
let innerPromise = try await outerPromise.await()
|
|
398
|
+
let result = try await innerPromise.await()
|
|
399
|
+
|
|
400
|
+
// Handle the BrowseResult union type
|
|
401
|
+
switch result {
|
|
402
|
+
case let .first(resolvedTrack):
|
|
403
|
+
return resolvedTrack
|
|
404
|
+
case let .second(browseError):
|
|
405
|
+
throw BrowserError.callbackError(browseError.error)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if let browseConfig = entry.browseConfig {
|
|
410
|
+
return try await resolveFromConfig(browseConfig, path: path, params: params)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if let staticContent = entry.browseStatic {
|
|
414
|
+
return staticContent
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
throw BrowserError.contentNotFound(path: path)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
private func resolveFromConfig(
|
|
421
|
+
_ routeConfig: TransformableRequestConfig,
|
|
422
|
+
path: String,
|
|
423
|
+
params _: [String: String],
|
|
424
|
+
) async throws -> ResolvedTrack {
|
|
425
|
+
// Build the request URL - route config takes precedence over global config
|
|
426
|
+
let baseUrl = routeConfig.baseUrl ?? config.request?.baseUrl
|
|
427
|
+
guard let baseUrl else {
|
|
428
|
+
throw BrowserError.invalidConfiguration("No URL configured for route")
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
var url = BrowserPathHelper.buildUrl(baseUrl: baseUrl, path: path)
|
|
432
|
+
|
|
433
|
+
// Add query parameters from config - route config values override global config
|
|
434
|
+
let queryParams = mergeQuery(config.request?.query, routeConfig.query)
|
|
435
|
+
if let queryParams, !queryParams.isEmpty {
|
|
436
|
+
let queryString = queryParams
|
|
437
|
+
.map { key, value in
|
|
438
|
+
let encodedKey = key.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? key
|
|
439
|
+
let encodedValue = value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? value
|
|
440
|
+
return "\(encodedKey)=\(encodedValue)"
|
|
441
|
+
}
|
|
442
|
+
.joined(separator: "&")
|
|
443
|
+
let separator = url.contains("?") ? "&" : "?"
|
|
444
|
+
url = "\(url)\(separator)\(queryString)"
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Build HTTP request - route config takes precedence
|
|
448
|
+
let method = (routeConfig.method ?? config.request?.method)?.stringValue ?? "GET"
|
|
449
|
+
let request = HttpClient.HttpRequest(
|
|
450
|
+
url: url,
|
|
451
|
+
method: method,
|
|
452
|
+
headers: mergeHeaders(config.request?.headers, routeConfig.headers),
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
logger.debug("Resolving content from API")
|
|
456
|
+
logger.debug(" path: \(path)")
|
|
457
|
+
logger.debug(" url: \(url)")
|
|
458
|
+
|
|
459
|
+
// Execute request
|
|
460
|
+
let result: JsonResolvedTrack = try await httpClient.requestJson(request, as: JsonResolvedTrack.self)
|
|
461
|
+
let nitroResult = result.toNitro()
|
|
462
|
+
|
|
463
|
+
logger.debug("Resolved: \(nitroResult.title)")
|
|
464
|
+
if let children = nitroResult.children {
|
|
465
|
+
logger.debug(" children: \(children.count) tracks")
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return nitroResult
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
private func mergeQuery(
|
|
472
|
+
_ base: [String: String]?,
|
|
473
|
+
_ override: [String: String]?,
|
|
474
|
+
) -> [String: String]? {
|
|
475
|
+
guard let base else { return override }
|
|
476
|
+
guard let override else { return base }
|
|
477
|
+
return base.merging(override) { _, new in new }
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
private func mergeHeaders(
|
|
481
|
+
_ base: [String: String]?,
|
|
482
|
+
_ override: [String: String]?,
|
|
483
|
+
) -> [String: String]? {
|
|
484
|
+
guard let base else { return override }
|
|
485
|
+
guard let override else { return base }
|
|
486
|
+
return base.merging(override) { _, new in new }
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// MARK: - Child Transformation
|
|
490
|
+
|
|
491
|
+
private func transformChildren(
|
|
492
|
+
_ children: [Track],
|
|
493
|
+
parentPath: String,
|
|
494
|
+
routeEntry: NativeRouteEntry,
|
|
495
|
+
) async throws -> [Track] {
|
|
496
|
+
var transformed: [Track] = []
|
|
497
|
+
|
|
498
|
+
for track in children {
|
|
499
|
+
// Validate track has stable identifier
|
|
500
|
+
if track.url == nil, track.src == nil {
|
|
501
|
+
throw BrowserError.invalidConfiguration(
|
|
502
|
+
"Track must have either 'url' or 'src' for stable identification: \(track.title)",
|
|
503
|
+
)
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
var transformedTrack = track
|
|
507
|
+
|
|
508
|
+
// Generate contextual URL for playable-only tracks (has src but no url)
|
|
509
|
+
if track.src != nil, track.url == nil {
|
|
510
|
+
let contextualUrl = BrowserPathHelper.build(parentPath: parentPath, trackId: track.src!)
|
|
511
|
+
transformedTrack = Track(
|
|
512
|
+
url: contextualUrl,
|
|
513
|
+
src: track.src,
|
|
514
|
+
artwork: track.artwork,
|
|
515
|
+
artworkSource: track.artworkSource,
|
|
516
|
+
artworkCarPlayTinted: track.artworkCarPlayTinted,
|
|
517
|
+
title: track.title,
|
|
518
|
+
subtitle: track.subtitle,
|
|
519
|
+
artist: track.artist,
|
|
520
|
+
album: track.album,
|
|
521
|
+
description: track.description,
|
|
522
|
+
genre: track.genre,
|
|
523
|
+
duration: track.duration,
|
|
524
|
+
style: track.style,
|
|
525
|
+
childrenStyle: track.childrenStyle,
|
|
526
|
+
favorited: track.favorited,
|
|
527
|
+
groupTitle: track.groupTitle,
|
|
528
|
+
live: track.live,
|
|
529
|
+
)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Transform artwork URL if resolver is configured
|
|
533
|
+
// At browse-time, we don't have display size info
|
|
534
|
+
if let resolver = artworkUrlResolver {
|
|
535
|
+
let artworkConfig = routeEntry.artwork ?? config.artwork
|
|
536
|
+
let browseContext = ImageContext(width: nil, height: nil)
|
|
537
|
+
if let imageSource = await resolver(transformedTrack, artworkConfig, browseContext) {
|
|
538
|
+
transformedTrack = Track(
|
|
539
|
+
url: transformedTrack.url,
|
|
540
|
+
src: transformedTrack.src,
|
|
541
|
+
artwork: transformedTrack.artwork,
|
|
542
|
+
artworkSource: imageSource,
|
|
543
|
+
artworkCarPlayTinted: transformedTrack.artworkCarPlayTinted,
|
|
544
|
+
title: transformedTrack.title,
|
|
545
|
+
subtitle: transformedTrack.subtitle,
|
|
546
|
+
artist: transformedTrack.artist,
|
|
547
|
+
album: transformedTrack.album,
|
|
548
|
+
description: transformedTrack.description,
|
|
549
|
+
genre: transformedTrack.genre,
|
|
550
|
+
duration: transformedTrack.duration,
|
|
551
|
+
style: transformedTrack.style,
|
|
552
|
+
childrenStyle: transformedTrack.childrenStyle,
|
|
553
|
+
favorited: transformedTrack.favorited,
|
|
554
|
+
groupTitle: transformedTrack.groupTitle,
|
|
555
|
+
live: transformedTrack.live,
|
|
556
|
+
)
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
transformed.append(transformedTrack)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return transformed
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// MARK: - Search
|
|
567
|
+
|
|
568
|
+
/// Execute a search query.
|
|
569
|
+
func search(_ query: String) async throws -> ResolvedTrack {
|
|
570
|
+
// Check cache - re-hydrate favorites since they may have changed
|
|
571
|
+
if query == lastSearchQuery, let results = lastSearchResults {
|
|
572
|
+
let hydratedResults = results.map { hydrateFavorite($0) }
|
|
573
|
+
return ResolvedTrack(
|
|
574
|
+
url: BrowserPathHelper.createSearchPath(query),
|
|
575
|
+
children: hydratedResults,
|
|
576
|
+
src: nil,
|
|
577
|
+
artwork: nil,
|
|
578
|
+
artworkSource: nil,
|
|
579
|
+
artworkCarPlayTinted: nil,
|
|
580
|
+
title: "Search: \(query)",
|
|
581
|
+
subtitle: nil,
|
|
582
|
+
artist: nil,
|
|
583
|
+
album: nil,
|
|
584
|
+
description: nil,
|
|
585
|
+
genre: nil,
|
|
586
|
+
duration: nil,
|
|
587
|
+
style: nil,
|
|
588
|
+
childrenStyle: nil,
|
|
589
|
+
favorited: nil,
|
|
590
|
+
groupTitle: nil,
|
|
591
|
+
live: nil,
|
|
592
|
+
)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
guard let routes = config.routes else {
|
|
596
|
+
throw BrowserError.contentNotFound(path: Self.searchRoutePath)
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
guard let searchEntry = routes.first(where: { $0.path == Self.searchRoutePath }) else {
|
|
600
|
+
throw BrowserError.contentNotFound(path: Self.searchRoutePath)
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
let searchParams = SearchParams(
|
|
604
|
+
mode: nil,
|
|
605
|
+
query: query,
|
|
606
|
+
genre: nil,
|
|
607
|
+
artist: nil,
|
|
608
|
+
album: nil,
|
|
609
|
+
title: nil,
|
|
610
|
+
playlist: nil,
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
var results: [Track]
|
|
614
|
+
|
|
615
|
+
if let callback = searchEntry.searchCallback {
|
|
616
|
+
// Callback returns Promise<Promise<[Track]>> - await both layers
|
|
617
|
+
let outerPromise = callback(searchParams)
|
|
618
|
+
let innerPromise = try await outerPromise.await()
|
|
619
|
+
results = try await innerPromise.await()
|
|
620
|
+
} else if let searchConfig = searchEntry.searchConfig {
|
|
621
|
+
let resolved = try await resolveFromConfig(searchConfig, path: "/__search", params: ["q": query])
|
|
622
|
+
results = resolved.children ?? []
|
|
623
|
+
} else {
|
|
624
|
+
throw BrowserError.contentNotFound(path: Self.searchRoutePath)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Hydrate favorites in results
|
|
628
|
+
let hydratedResults = results.map { hydrateFavorite($0) }
|
|
629
|
+
|
|
630
|
+
// Cache results
|
|
631
|
+
lastSearchQuery = query
|
|
632
|
+
lastSearchResults = hydratedResults
|
|
633
|
+
|
|
634
|
+
// Cache individual tracks
|
|
635
|
+
hydratedResults.forEach { cacheTrack($0) }
|
|
636
|
+
|
|
637
|
+
return ResolvedTrack(
|
|
638
|
+
url: BrowserPathHelper.createSearchPath(query),
|
|
639
|
+
children: hydratedResults,
|
|
640
|
+
src: nil,
|
|
641
|
+
artwork: nil,
|
|
642
|
+
artworkSource: nil,
|
|
643
|
+
artworkCarPlayTinted: nil,
|
|
644
|
+
title: "Search: \(query)",
|
|
645
|
+
subtitle: nil,
|
|
646
|
+
artist: nil,
|
|
647
|
+
album: nil,
|
|
648
|
+
description: nil,
|
|
649
|
+
genre: nil,
|
|
650
|
+
duration: nil,
|
|
651
|
+
style: nil,
|
|
652
|
+
childrenStyle: nil,
|
|
653
|
+
favorited: nil,
|
|
654
|
+
groupTitle: nil,
|
|
655
|
+
live: nil,
|
|
656
|
+
)
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// MARK: - Tabs
|
|
660
|
+
|
|
661
|
+
/// Query navigation tabs.
|
|
662
|
+
@MainActor
|
|
663
|
+
func queryTabs() async throws -> [Track] {
|
|
664
|
+
guard let routes = config.routes else {
|
|
665
|
+
return []
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
guard let tabsEntry = routes.first(where: { $0.path == Self.tabsRoutePath }) else {
|
|
669
|
+
return []
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let resolved = try await resolveRouteEntry(tabsEntry, path: Self.tabsRoutePath, params: [:])
|
|
673
|
+
let tabTracks = resolved.children ?? []
|
|
674
|
+
|
|
675
|
+
tabs = tabTracks
|
|
676
|
+
return tabTracks
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// MARK: - Queue Expansion (for CarPlay/external controllers)
|
|
680
|
+
|
|
681
|
+
/// Expands a contextual URL to a full queue of playable tracks.
|
|
682
|
+
func expandQueueFromContextualUrl(_ url: String) async throws -> (tracks: [Track], selectedIndex: Int)? {
|
|
683
|
+
guard BrowserPathHelper.isContextual(url) else { return nil }
|
|
684
|
+
|
|
685
|
+
let parentPath = BrowserPathHelper.stripTrackId(url)
|
|
686
|
+
guard let trackId = BrowserPathHelper.extractTrackId(url) else { return nil }
|
|
687
|
+
|
|
688
|
+
logger.debug("Expanding queue from contextual URL")
|
|
689
|
+
logger.debug(" url: \(url)")
|
|
690
|
+
logger.debug(" parentPath: \(parentPath)")
|
|
691
|
+
logger.debug(" trackId: \(trackId)")
|
|
692
|
+
|
|
693
|
+
// Resolve the parent container
|
|
694
|
+
let resolved = try await resolve(parentPath, useCache: true)
|
|
695
|
+
guard let children = resolved.children else { return nil }
|
|
696
|
+
|
|
697
|
+
// Filter to playable tracks (have src)
|
|
698
|
+
let playableTracks = children.filter { $0.src != nil }
|
|
699
|
+
guard !playableTracks.isEmpty else { return nil }
|
|
700
|
+
|
|
701
|
+
logger.debug("Found \(playableTracks.count) playable tracks")
|
|
702
|
+
for (index, track) in playableTracks.enumerated() {
|
|
703
|
+
logger.debug(" [\(index)] \(track.title) - src: \(track.src ?? "nil")")
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Find selected track index
|
|
707
|
+
let selectedIndex = playableTracks.firstIndex { $0.src == trackId } ?? 0
|
|
708
|
+
logger.debug("Selected track index: \(selectedIndex)")
|
|
709
|
+
|
|
710
|
+
// If singleTrack mode, return just the selected track
|
|
711
|
+
if config.singleTrack {
|
|
712
|
+
return (tracks: [playableTracks[selectedIndex]], selectedIndex: 0)
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return (tracks: playableTracks, selectedIndex: selectedIndex)
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// MARK: - Media URL Resolution
|
|
719
|
+
|
|
720
|
+
/// Resolves a media URL using the configured media transform.
|
|
721
|
+
/// Returns the transformed URL, headers, and user-agent for playback.
|
|
722
|
+
func resolveMediaUrl(_ originalUrl: String) async -> MediaResolvedUrl {
|
|
723
|
+
guard let mediaConfig = config.media else {
|
|
724
|
+
logger.debug("No media config, using original URL: \(originalUrl)")
|
|
725
|
+
return MediaResolvedUrl(url: originalUrl, headers: nil, userAgent: nil)
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
logger.debug("Resolving media URL: \(originalUrl)")
|
|
729
|
+
|
|
730
|
+
// If there's a transform function, call it
|
|
731
|
+
if let transform = mediaConfig.transform {
|
|
732
|
+
do {
|
|
733
|
+
// Create base request config with original URL as path
|
|
734
|
+
let baseRequest = RequestConfig(
|
|
735
|
+
method: config.request?.method,
|
|
736
|
+
path: originalUrl,
|
|
737
|
+
baseUrl: config.request?.baseUrl,
|
|
738
|
+
headers: config.request?.headers,
|
|
739
|
+
query: config.request?.query,
|
|
740
|
+
body: config.request?.body,
|
|
741
|
+
contentType: config.request?.contentType,
|
|
742
|
+
userAgent: config.request?.userAgent,
|
|
743
|
+
)
|
|
744
|
+
|
|
745
|
+
logger.debug("resolveMediaUrl: calling transform callback...")
|
|
746
|
+
// MediaRequestConfig.transform takes (request, routeParams) - pass nil for routeParams
|
|
747
|
+
let outerPromise = transform(baseRequest, nil)
|
|
748
|
+
logger.debug("resolveMediaUrl: awaiting outer promise...")
|
|
749
|
+
let innerPromise = try await outerPromise.await()
|
|
750
|
+
logger.debug("resolveMediaUrl: awaiting inner promise...")
|
|
751
|
+
let transformedConfig = try await innerPromise.await()
|
|
752
|
+
logger.debug("resolveMediaUrl: transform complete")
|
|
753
|
+
|
|
754
|
+
// Extract values immediately to Swift native types to avoid
|
|
755
|
+
// memory corruption in Nitro's Swift-C++ bridge when the
|
|
756
|
+
// Promise<RequestConfig> is deallocated
|
|
757
|
+
let finalUrl = buildUrl(from: transformedConfig)
|
|
758
|
+
let headers = transformedConfig.headers
|
|
759
|
+
let userAgent = transformedConfig.userAgent
|
|
760
|
+
|
|
761
|
+
logger.debug("Media URL transformed: \(originalUrl) -> \(finalUrl)")
|
|
762
|
+
|
|
763
|
+
return MediaResolvedUrl(
|
|
764
|
+
url: finalUrl,
|
|
765
|
+
headers: headers,
|
|
766
|
+
userAgent: userAgent,
|
|
767
|
+
)
|
|
768
|
+
} catch {
|
|
769
|
+
logger.error("Media transform failed: \(error.localizedDescription)")
|
|
770
|
+
return MediaResolvedUrl(url: originalUrl, headers: nil, userAgent: nil)
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// No transform, just apply baseUrl if configured
|
|
775
|
+
let baseUrl = mediaConfig.baseUrl ?? config.request?.baseUrl
|
|
776
|
+
if let baseUrl {
|
|
777
|
+
let finalUrl = BrowserPathHelper.buildUrl(baseUrl: baseUrl, path: originalUrl)
|
|
778
|
+
logger.debug("Media URL with baseUrl: \(originalUrl) -> \(finalUrl)")
|
|
779
|
+
return MediaResolvedUrl(
|
|
780
|
+
url: finalUrl,
|
|
781
|
+
headers: mediaConfig.headers ?? config.request?.headers,
|
|
782
|
+
userAgent: mediaConfig.userAgent ?? config.request?.userAgent,
|
|
783
|
+
)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return MediaResolvedUrl(url: originalUrl, headers: nil, userAgent: nil)
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
private func buildUrl(from config: RequestConfig) -> String {
|
|
790
|
+
let path = config.path ?? ""
|
|
791
|
+
let baseUrl = config.baseUrl
|
|
792
|
+
|
|
793
|
+
var url = BrowserPathHelper.buildUrl(baseUrl: baseUrl, path: path)
|
|
794
|
+
|
|
795
|
+
// Add query parameters if any
|
|
796
|
+
if let query = config.query, !query.isEmpty {
|
|
797
|
+
let queryString = query
|
|
798
|
+
.map { key, value in
|
|
799
|
+
let encodedKey = key.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? key
|
|
800
|
+
let encodedValue = value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? value
|
|
801
|
+
return "\(encodedKey)=\(encodedValue)"
|
|
802
|
+
}
|
|
803
|
+
.joined(separator: "&")
|
|
804
|
+
let separator = url.contains("?") ? "&" : "?"
|
|
805
|
+
url = "\(url)\(separator)\(queryString)"
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
return url
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// MARK: - Artwork URL Resolution
|
|
812
|
+
|
|
813
|
+
/// Resolves an artwork URL for a track using the configured artwork transform.
|
|
814
|
+
/// Returns an ImageSource with transformed URL and headers for image loading.
|
|
815
|
+
///
|
|
816
|
+
/// - Parameters:
|
|
817
|
+
/// - track: The track whose artwork URL should be transformed
|
|
818
|
+
/// - perRouteConfig: Optional per-route artwork config that overrides global config
|
|
819
|
+
/// - imageContext: Optional size context for CDN URL generation (nil at browse-time)
|
|
820
|
+
/// - Returns: ImageSource ready for image loading, or nil if no artwork
|
|
821
|
+
func resolveArtworkUrl(track: Track, perRouteConfig: ArtworkRequestConfig?, imageContext: ImageContext? = nil) async -> ImageSource? {
|
|
822
|
+
// Determine effective artwork config: per-route overrides global
|
|
823
|
+
let effectiveArtworkConfig = perRouteConfig ?? config.artwork
|
|
824
|
+
|
|
825
|
+
// If no artwork config and no track.artwork, nothing to transform
|
|
826
|
+
if effectiveArtworkConfig == nil, track.artwork == nil {
|
|
827
|
+
return nil
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// If no artwork config, return original artwork URL as simple ImageSource
|
|
831
|
+
guard let artworkConfig = effectiveArtworkConfig else {
|
|
832
|
+
guard let artwork = track.artwork else { return nil }
|
|
833
|
+
return ImageSource(uri: artwork, method: nil, headers: nil, body: nil)
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
do {
|
|
837
|
+
// Create base config from global request config
|
|
838
|
+
var mergedConfig = RequestConfig(
|
|
839
|
+
method: config.request?.method,
|
|
840
|
+
path: track.artwork, // Use track.artwork as default path
|
|
841
|
+
baseUrl: config.request?.baseUrl,
|
|
842
|
+
headers: config.request?.headers,
|
|
843
|
+
query: config.request?.query,
|
|
844
|
+
body: config.request?.body,
|
|
845
|
+
contentType: config.request?.contentType,
|
|
846
|
+
userAgent: config.request?.userAgent,
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
// If there's a resolve callback, call it for per-track config
|
|
850
|
+
if let resolve = artworkConfig.resolve {
|
|
851
|
+
let outerPromise = resolve(track)
|
|
852
|
+
let innerPromise = try await outerPromise.await()
|
|
853
|
+
let resolvedConfig = try await innerPromise.await()
|
|
854
|
+
|
|
855
|
+
// Merge resolved config (extractConfig avoids Nitro bridge memory issues)
|
|
856
|
+
mergedConfig = mergeRequestConfig(base: mergedConfig, override: extractConfig(resolvedConfig))
|
|
857
|
+
} else {
|
|
858
|
+
// No resolve callback - apply artwork static config
|
|
859
|
+
let artworkStaticConfig = RequestConfig(
|
|
860
|
+
method: artworkConfig.method,
|
|
861
|
+
path: artworkConfig.path,
|
|
862
|
+
baseUrl: artworkConfig.baseUrl,
|
|
863
|
+
headers: artworkConfig.headers,
|
|
864
|
+
query: artworkConfig.query,
|
|
865
|
+
body: artworkConfig.body,
|
|
866
|
+
contentType: artworkConfig.contentType,
|
|
867
|
+
userAgent: artworkConfig.userAgent,
|
|
868
|
+
)
|
|
869
|
+
mergedConfig = mergeRequestConfig(base: mergedConfig, override: artworkStaticConfig)
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// Apply image query params if configured and imageContext is provided
|
|
873
|
+
let queryParams = artworkConfig.imageQueryParams
|
|
874
|
+
if let queryParams, let imageContext {
|
|
875
|
+
var contextQuery: [String: String] = [:]
|
|
876
|
+
if let widthKey = queryParams.width, let width = imageContext.width {
|
|
877
|
+
contextQuery[widthKey] = String(Int(width))
|
|
878
|
+
}
|
|
879
|
+
if let heightKey = queryParams.height, let height = imageContext.height {
|
|
880
|
+
contextQuery[heightKey] = String(Int(height))
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if !contextQuery.isEmpty {
|
|
884
|
+
logger.debug("Adding image query params: \(contextQuery)")
|
|
885
|
+
var existingQuery = mergedConfig.query ?? [:]
|
|
886
|
+
for (key, value) in contextQuery {
|
|
887
|
+
existingQuery[key] = value
|
|
888
|
+
}
|
|
889
|
+
mergedConfig = RequestConfig(
|
|
890
|
+
method: mergedConfig.method,
|
|
891
|
+
path: mergedConfig.path,
|
|
892
|
+
baseUrl: mergedConfig.baseUrl,
|
|
893
|
+
headers: mergedConfig.headers,
|
|
894
|
+
query: existingQuery,
|
|
895
|
+
body: mergedConfig.body,
|
|
896
|
+
contentType: mergedConfig.contentType,
|
|
897
|
+
userAgent: mergedConfig.userAgent,
|
|
898
|
+
)
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// Apply transform callback if present (can override imageQueryParams)
|
|
903
|
+
// Skip transform at browse-time (no size context) to avoid excessive JS callbacks
|
|
904
|
+
// Transform will be called at load-time when actual display size is known
|
|
905
|
+
let hasSize = imageContext?.width != nil || imageContext?.height != nil
|
|
906
|
+
if let transform = artworkConfig.transform, hasSize {
|
|
907
|
+
let outerPromise = transform(MediaTransformParams(request: mergedConfig, context: imageContext))
|
|
908
|
+
let innerPromise = try await outerPromise.await()
|
|
909
|
+
let transformedConfig = try await innerPromise.await()
|
|
910
|
+
|
|
911
|
+
// Extract values immediately to avoid Nitro bridge memory issues
|
|
912
|
+
mergedConfig = extractConfig(transformedConfig)
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// Build final URL - if no path after merging, no artwork to transform
|
|
916
|
+
guard mergedConfig.path != nil else {
|
|
917
|
+
return nil
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
let uri = buildUrl(from: mergedConfig)
|
|
921
|
+
|
|
922
|
+
// Build headers map, merging explicit headers with userAgent
|
|
923
|
+
var headers = mergedConfig.headers ?? [:]
|
|
924
|
+
if let userAgent = mergedConfig.userAgent, headers["User-Agent"] == nil {
|
|
925
|
+
headers["User-Agent"] = userAgent
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
logger.debug("Artwork URL transformed: \(track.artwork ?? "nil") -> \(uri)")
|
|
929
|
+
|
|
930
|
+
return ImageSource(
|
|
931
|
+
uri: uri,
|
|
932
|
+
method: mergedConfig.method,
|
|
933
|
+
headers: headers.isEmpty ? nil : headers,
|
|
934
|
+
body: mergedConfig.body,
|
|
935
|
+
)
|
|
936
|
+
} catch {
|
|
937
|
+
logger.error("Failed to transform artwork URL for track: \(track.title), error: \(error.localizedDescription)")
|
|
938
|
+
// On error, return nil to avoid broken images
|
|
939
|
+
return nil
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/// Extracts all values from a RequestConfig into a new instance to avoid
|
|
944
|
+
/// memory corruption in Nitro's Swift-C++ bridge when the Promise is deallocated.
|
|
945
|
+
private func extractConfig(_ config: RequestConfig) -> RequestConfig {
|
|
946
|
+
RequestConfig(
|
|
947
|
+
method: config.method,
|
|
948
|
+
path: config.path,
|
|
949
|
+
baseUrl: config.baseUrl,
|
|
950
|
+
headers: config.headers,
|
|
951
|
+
query: config.query,
|
|
952
|
+
body: config.body,
|
|
953
|
+
contentType: config.contentType,
|
|
954
|
+
userAgent: config.userAgent,
|
|
955
|
+
)
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/// Merges two RequestConfig objects, with override values taking precedence.
|
|
959
|
+
private func mergeRequestConfig(base: RequestConfig, override: RequestConfig) -> RequestConfig {
|
|
960
|
+
RequestConfig(
|
|
961
|
+
method: override.method ?? base.method,
|
|
962
|
+
path: override.path ?? base.path,
|
|
963
|
+
baseUrl: override.baseUrl ?? base.baseUrl,
|
|
964
|
+
headers: mergeHeaders(base.headers, override.headers),
|
|
965
|
+
query: mergeQuery(base.query, override.query),
|
|
966
|
+
body: override.body ?? base.body,
|
|
967
|
+
contentType: override.contentType ?? base.contentType,
|
|
968
|
+
userAgent: override.userAgent ?? base.userAgent,
|
|
969
|
+
)
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// MARK: - Accessors
|
|
973
|
+
|
|
974
|
+
func getPath() -> String {
|
|
975
|
+
path
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
func getContent() -> ResolvedTrack? {
|
|
979
|
+
content
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
func getTabs() -> [Track]? {
|
|
983
|
+
tabs
|
|
984
|
+
}
|
|
985
|
+
}
|