react-native-audio-browser 0.1.1 → 0.2.0-next.1
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 +1 -1
- package/README.md +180 -2
- package/android/build.gradle +10 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +401 -141
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +4 -6
- package/android/src/main/java/com/audiobrowser/Service.kt +67 -18
- package/android/src/main/java/com/audiobrowser/browser/ArtworkResolutionRegistry.kt +37 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowseArtworkRegistry.kt +34 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +443 -178
- package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +300 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonArtwork.kt +79 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +41 -4
- package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +43 -0
- package/android/src/main/java/com/audiobrowser/browser/TrackLoadHandler.kt +4 -4
- package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +35 -0
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +109 -97
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +6 -10
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +40 -8
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +31 -37
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +4 -1
- package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +119 -0
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +18 -1
- package/android/src/main/java/com/audiobrowser/player/EqualizerController.kt +153 -0
- package/android/src/main/java/com/audiobrowser/player/InterceptingPlayer.kt +141 -0
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +15 -3
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +415 -131
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +154 -276
- package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +348 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackErrorClassifier.kt +129 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateMachine.kt +85 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +27 -5
- package/android/src/main/java/com/audiobrowser/player/PlaybackTimer.kt +56 -0
- package/android/src/main/java/com/audiobrowser/player/Player.kt +452 -576
- package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +20 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerEngineFactory.kt +130 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +190 -67
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +117 -53
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +37 -3
- package/android/src/main/java/com/audiobrowser/player/SleepTimerManager.kt +80 -0
- package/android/src/main/java/com/audiobrowser/player/StuckRecoveryPolicy.kt +50 -0
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +84 -40
- package/android/src/main/java/com/audiobrowser/player/VolumeFader.kt +81 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +141 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +37 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +41 -0
- package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +209 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkContentProvider.kt +161 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkUris.kt +28 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +26 -0
- package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +24 -0
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoader.kt +49 -0
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoaderHolder.kt +36 -0
- package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +23 -300
- package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +13 -23
- package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +2 -2
- package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +4 -3
- package/android/src/main/java/com/audiobrowser/util/OutputMonitor.kt +211 -0
- package/android/src/main/java/com/audiobrowser/util/OutputSwitcher.kt +58 -0
- package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +2 -1
- package/android/src/main/java/com/audiobrowser/util/RatingFavorites.kt +14 -0
- package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +6 -111
- package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +22 -8
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +111 -80
- package/android/src/main/res/values/strings.xml +4 -0
- package/android/src/test/java/com/audiobrowser/TestFixtures.kt +166 -0
- package/android/src/test/java/com/audiobrowser/browser/ArtworkResolutionRegistryTest.kt +46 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowseArtworkRegistryTest.kt +39 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerBuildApiRequestTest.kt +114 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +141 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +4 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +177 -0
- package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +54 -0
- package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +96 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +1 -2
- package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +72 -0
- package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +159 -0
- package/android/src/test/java/com/audiobrowser/player/DynamicLoadControlTest.kt +56 -0
- package/android/src/test/java/com/audiobrowser/player/EqualizerControllerTest.kt +216 -0
- package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +442 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +191 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackStateMachineTest.kt +198 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackTimerTest.kt +137 -0
- package/android/src/test/java/com/audiobrowser/player/PlayerEngineFactoryTest.kt +36 -0
- package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +268 -0
- package/android/src/test/java/com/audiobrowser/player/SessionErrorMaskTest.kt +68 -0
- package/android/src/test/java/com/audiobrowser/player/StuckRecoveryPolicyTest.kt +40 -0
- package/android/src/test/java/com/audiobrowser/player/TransformingDataSourceTest.kt +193 -0
- package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +107 -0
- package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +73 -0
- package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +75 -0
- package/android/src/test/java/com/audiobrowser/tls/CertFixtures.kt +18 -0
- package/android/src/test/java/com/audiobrowser/util/ArtworkContentProviderTest.kt +163 -0
- package/android/src/test/java/com/audiobrowser/util/ArtworkUrisTest.kt +34 -0
- package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +28 -0
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderHolderTest.kt +53 -0
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderTest.kt +58 -0
- package/android/src/test/java/com/audiobrowser/util/FakeImageLoader.kt +57 -0
- package/android/src/test/java/com/audiobrowser/util/PlayingStateFactoryTest.kt +40 -0
- package/android/src/test/java/com/audiobrowser/util/RatingFavoritesTest.kt +34 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryBrowseTest.kt +50 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +63 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryRatingTest.kt +35 -0
- package/android/src/test/resources/certs/isrg-root-x1.pem +31 -0
- package/android/src/test/resources/certs/letsencrypt-r13.der +0 -0
- package/android/src/test/resources/certs/letsencrypt-r13.pem +29 -0
- package/android/src/test/resources/certs/stationplaylist-leaf.pem +34 -0
- package/ios/Browser/BrowserConfig.swift +41 -11
- package/ios/Browser/BrowserManager+URLResolution.swift +213 -93
- package/ios/Browser/BrowserManager.swift +303 -110
- package/ios/Browser/BrowserPathHelper.swift +32 -3
- package/ios/Browser/JsonModels.swift +287 -66
- package/ios/Browser/MediaResolveComposer.swift +114 -0
- package/ios/Browser/SearchDrillIn.swift +44 -0
- package/ios/Browser/SectionScope.swift +35 -0
- package/ios/Browser/TabBarEntries.swift +15 -0
- package/ios/CarPlay/CPInterfaceController+Safe.swift +126 -0
- package/ios/CarPlay/CarPlayArtworkResolver.swift +6 -6
- package/ios/CarPlay/CarPlayController.swift +739 -149
- package/ios/CarPlay/CarPlayImageLoader.swift +57 -8
- package/ios/CarPlay/CarPlayListItemFactory.swift +44 -35
- package/ios/CarPlay/CarPlayNowPlayingManager.swift +180 -36
- package/ios/CarPlay/ImageRowItem+CarPlay.swift +19 -0
- package/ios/CarPlay/RNABAudioBrowser.h +15 -10
- package/ios/CarPlay/RNABAudioBrowser.m +15 -14
- package/ios/CarPlay/RNABCarPlaySceneDelegate.m +2 -0
- package/ios/CarPlay/RNABMediaAddHandler.swift +75 -0
- package/ios/CarPlay/RNABMediaAffinityHandler.swift +69 -0
- package/ios/CarPlay/RNABMediaIntentHandler.swift +53 -43
- package/ios/Extension/Capability+RemoteCommand.swift +7 -9
- package/ios/Extension/ChapterMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/NavigationError+Conversion.swift +8 -1
- package/ios/Extension/PlayerCapabilities+Favorite.swift +20 -0
- package/ios/Extension/RequestConfig+Copying.swift +31 -0
- package/ios/Extension/ResolvedTrack+Copying.swift +10 -4
- package/ios/Extension/TimedMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/Track+AVPlayer.swift +4 -4
- package/ios/Extension/Track+Copying.swift +9 -3
- package/ios/Extension/TrackMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/Variant+Artwork.swift +49 -0
- package/ios/HybridAudioBrowser.swift +750 -173
- package/ios/Model/NitroTypeStubs.swift +299 -224
- package/ios/Model/PlayerUpdateOptions.swift +23 -23
- package/ios/Model/RemoteCommand.swift +6 -6
- package/ios/Model/TrackPlayerError.swift +82 -18
- package/ios/NowPlayingInfo/NowPlayingInfoController.swift +99 -121
- package/ios/NowPlayingInfo/SilentAudioPrimer.swift +73 -0
- package/ios/Observer/PlayerItemNotificationObserver.swift +45 -5
- package/ios/Observer/PlayerItemPropertyObserver.swift +27 -4
- package/ios/Observer/PlayerTimeObserver.swift +3 -53
- package/ios/Option/SessionCategories.swift +33 -11
- package/ios/Player/AirPlayStallJudgement.swift +25 -0
- package/ios/Player/EndOfTrackJudgement.swift +32 -0
- package/ios/Player/LoadSeekCoordinator.swift +16 -1
- package/ios/Player/MediaIntentCriteria.swift +139 -0
- package/ios/Player/MediaLoader.swift +28 -10
- package/ios/Player/NowPlayingUpdater.swift +119 -26
- package/ios/Player/PersistedPlaybackState.swift +11 -0
- package/ios/Player/PlaybackCoordinator.swift +282 -51
- package/ios/Player/PlaybackCoordinatorCallbacks.swift +6 -1
- package/ios/Player/PlaybackEffectHandler.swift +19 -9
- package/ios/Player/PlaybackErrorHandler.swift +97 -13
- package/ios/Player/PlaybackStateMachine.swift +18 -13
- package/ios/Player/PlaybackStateStore.swift +27 -0
- package/ios/Player/PlaybackTimer.swift +61 -0
- package/ios/Player/PlayingStateManager.swift +3 -2
- package/ios/Player/QueueManager.swift +67 -61
- package/ios/Player/RetryManager.swift +97 -21
- package/ios/Player/SleepTimerHandling.swift +8 -0
- package/ios/Player/SleepTimerManager.swift +38 -5
- package/ios/Player/VolumeFader.swift +77 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +31 -15
- package/ios/Tests/AirPlayStallJudgementTests.swift +52 -0
- package/ios/Tests/BrowserPathHelperTests.swift +28 -0
- package/ios/Tests/CarPlayArtworkResolverTests.swift +39 -39
- package/ios/Tests/ChapterMetadataAVFoundationTests.swift +2 -2
- package/ios/Tests/EndOfTrackJudgementTests.swift +35 -0
- package/ios/Tests/JsonModelsTests.swift +58 -0
- package/ios/Tests/LoadSeekCoordinatorTests.swift +38 -7
- package/ios/Tests/MediaIntentCriteriaTests.swift +170 -0
- package/ios/Tests/MediaLoaderAssetOptionsTests.swift +46 -0
- package/ios/Tests/MediaLoaderTests.swift +23 -8
- package/ios/Tests/MediaResolveTests.swift +126 -0
- package/ios/Tests/OnceValueTests.swift +79 -0
- package/ios/Tests/PlaybackCoordinatorTests.swift +784 -13
- package/ios/Tests/PlaybackErrorHandlerTests.swift +380 -46
- package/ios/Tests/PlaybackStateMachineTests.swift +33 -8
- package/ios/Tests/PlaybackStateStoreTests.swift +48 -0
- package/ios/Tests/PlaybackTimerTests.swift +55 -0
- package/ios/Tests/PlayingStateManagerTests.swift +57 -0
- package/ios/Tests/QueueManagerTests.swift +149 -18
- package/ios/Tests/ResolvedTrackCopyingTests.swift +15 -8
- package/ios/Tests/RetryManagerTests.swift +89 -0
- package/ios/Tests/SearchDrillInTests.swift +63 -0
- package/ios/Tests/SectionScopeTests.swift +82 -0
- package/ios/Tests/SleepTimerManagerTests.swift +104 -0
- package/ios/Tests/Support/TestTypes.swift +61 -20
- package/ios/Tests/TabBarEntriesTests.swift +71 -0
- package/ios/Tests/TrackSelectorTests.swift +15 -15
- package/ios/TrackPlayer.swift +380 -58
- package/ios/TrackPlayerCallbacks.swift +0 -6
- package/ios/TrackSelector.swift +5 -5
- package/ios/Util/ArtworkImageFetcher.swift +4 -2
- package/ios/Util/NetworkMonitor.swift +7 -3
- package/ios/Util/OnceValue.swift +34 -0
- package/lib/commonjs/features/browser-config.js +227 -0
- package/lib/commonjs/features/browser-config.js.map +1 -0
- package/lib/commonjs/features/browser.js +59 -158
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/carConnection.js +42 -0
- package/lib/commonjs/features/carConnection.js.map +1 -0
- package/lib/commonjs/features/errors.js +34 -2
- package/lib/commonjs/features/errors.js.map +1 -1
- package/lib/commonjs/features/gate.js +149 -0
- package/lib/commonjs/features/gate.js.map +1 -0
- package/lib/commonjs/features/index.js +22 -0
- package/lib/commonjs/features/index.js.map +1 -1
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/nowPlaying.js +35 -0
- package/lib/commonjs/features/nowPlaying.js.map +1 -1
- package/lib/commonjs/features/output.js +37 -23
- package/lib/commonjs/features/output.js.map +1 -1
- package/lib/commonjs/features/playback/controls.js +9 -0
- package/lib/commonjs/features/playback/controls.js.map +1 -1
- package/lib/commonjs/features/playback/index.js +11 -0
- package/lib/commonjs/features/playback/index.js.map +1 -1
- package/lib/commonjs/features/playback/progress.js +28 -12
- package/lib/commonjs/features/playback/progress.js.map +1 -1
- package/lib/commonjs/features/playback/trackPlaybackTime.js +92 -0
- package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/commonjs/features/playback/volume.js +1 -1
- package/lib/commonjs/features/player/options.js +49 -13
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/player/setup.js +249 -3
- package/lib/commonjs/features/player/setup.js.map +1 -1
- package/lib/commonjs/features/queue/queue.js +10 -3
- package/lib/commonjs/features/queue/queue.js.map +1 -1
- package/lib/commonjs/features/remoteControls.js +1 -12
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/features/sleepTimer.js +9 -4
- package/lib/commonjs/features/sleepTimer.js.map +1 -1
- package/lib/commonjs/native.js +5 -0
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.web.js +4 -1
- package/lib/commonjs/native.web.js.map +1 -1
- package/lib/commonjs/utils/LazyNativeEmitter.js +0 -3
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/commonjs/utils/NativeUpdatedValue.js +0 -3
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/commonjs/utils/artwork.js +31 -0
- package/lib/commonjs/utils/artwork.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +301 -124
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +71 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js +34 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +90 -26
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +21 -0
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js +273 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +158 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js +75 -0
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/index.js +13 -5
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +176 -50
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js +3 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/commonjs/web/browser/SearchManager.js +11 -9
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
- package/lib/commonjs/web/browser/assertBrowsePageShape.js +22 -0
- package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js +41 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js +20 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/commonjs/web/http/HttpClient.js +4 -23
- package/lib/commonjs/web/http/HttpClient.js.map +1 -1
- package/lib/commonjs/web/http/RequestConfigBuilder.js +107 -58
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/commonjs/web/playbackErrorKind.js +57 -0
- package/lib/commonjs/web/playbackErrorKind.js.map +1 -0
- package/lib/commonjs/web/player/MediaSessionManager.js +121 -0
- package/lib/commonjs/web/player/MediaSessionManager.js.map +1 -0
- package/lib/commonjs/web/player/NowPlayingManager.js +6 -5
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
- package/lib/commonjs/web/player/OptionsManager.js +9 -17
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
- package/lib/commonjs/web/player/RemoteCommandController.js +96 -0
- package/lib/commonjs/web/player/RemoteCommandController.js.map +1 -0
- package/lib/module/features/browser-config.js +221 -0
- package/lib/module/features/browser-config.js.map +1 -0
- package/lib/module/features/browser.js +53 -156
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/carConnection.js +37 -0
- package/lib/module/features/carConnection.js.map +1 -0
- package/lib/module/features/errors.js +34 -2
- package/lib/module/features/errors.js.map +1 -1
- package/lib/module/features/gate.js +144 -0
- package/lib/module/features/gate.js.map +1 -0
- package/lib/module/features/index.js +2 -0
- package/lib/module/features/index.js.map +1 -1
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/nowPlaying.js +33 -0
- package/lib/module/features/nowPlaying.js.map +1 -1
- package/lib/module/features/output.js +32 -19
- package/lib/module/features/output.js.map +1 -1
- package/lib/module/features/playback/controls.js +8 -0
- package/lib/module/features/playback/controls.js.map +1 -1
- package/lib/module/features/playback/index.js +1 -0
- package/lib/module/features/playback/index.js.map +1 -1
- package/lib/module/features/playback/progress.js +28 -12
- package/lib/module/features/playback/progress.js.map +1 -1
- package/lib/module/features/playback/trackPlaybackTime.js +88 -0
- package/lib/module/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/module/features/playback/volume.js +1 -1
- package/lib/module/features/player/options.js +48 -13
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/player/setup.js +249 -3
- package/lib/module/features/player/setup.js.map +1 -1
- package/lib/module/features/queue/queue.js +10 -3
- package/lib/module/features/queue/queue.js.map +1 -1
- package/lib/module/features/remoteControls.js +0 -11
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/features/sleepTimer.js +9 -4
- package/lib/module/features/sleepTimer.js.map +1 -1
- package/lib/module/native.js +5 -0
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.web.js +4 -1
- package/lib/module/native.web.js.map +1 -1
- package/lib/module/utils/LazyNativeEmitter.js +0 -3
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/module/utils/NativeUpdatedValue.js +0 -3
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/module/utils/artwork.js +26 -0
- package/lib/module/utils/artwork.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +302 -125
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +67 -0
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js +29 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +90 -26
- package/lib/module/web/TrackPlayer/Player.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js +17 -0
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueueManager.js +269 -0
- package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js +154 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/module/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/module/web/TrackPlayer/VolumeFader.js +70 -0
- package/lib/module/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/module/web/TrackPlayer/index.js +2 -1
- package/lib/module/web/TrackPlayer/index.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +176 -50
- package/lib/module/web/browser/BrowserManager.js.map +1 -1
- package/lib/module/web/browser/NavigationErrorManager.js +3 -1
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/module/web/browser/SearchManager.js +11 -9
- package/lib/module/web/browser/SearchManager.js.map +1 -1
- package/lib/module/web/browser/assertBrowsePageShape.js +18 -0
- package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/module/web/browser/classifyTrackNavigation.js +38 -0
- package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/module/web/browser/parseSearchResponse.js +16 -0
- package/lib/module/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/module/web/http/HttpClient.js +4 -23
- package/lib/module/web/http/HttpClient.js.map +1 -1
- package/lib/module/web/http/RequestConfigBuilder.js +107 -58
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/module/web/playbackErrorKind.js +52 -0
- package/lib/module/web/playbackErrorKind.js.map +1 -0
- package/lib/module/web/player/MediaSessionManager.js +116 -0
- package/lib/module/web/player/MediaSessionManager.js.map +1 -0
- package/lib/module/web/player/NowPlayingManager.js +7 -5
- package/lib/module/web/player/NowPlayingManager.js.map +1 -1
- package/lib/module/web/player/OptionsManager.js +9 -17
- package/lib/module/web/player/OptionsManager.js.map +1 -1
- package/lib/module/web/player/RemoteCommandController.js +92 -0
- package/lib/module/web/player/RemoteCommandController.js.map +1 -0
- package/lib/typescript/src/features/browser-config.d.ts +12 -0
- package/lib/typescript/src/features/browser-config.d.ts.map +1 -0
- package/lib/typescript/src/features/browser.d.ts +40 -1
- package/lib/typescript/src/features/browser.d.ts.map +1 -1
- package/lib/typescript/src/features/carConnection.d.ts +20 -0
- package/lib/typescript/src/features/carConnection.d.ts.map +1 -0
- package/lib/typescript/src/features/errors.d.ts +58 -3
- package/lib/typescript/src/features/errors.d.ts.map +1 -1
- package/lib/typescript/src/features/gate.d.ts +77 -0
- package/lib/typescript/src/features/gate.d.ts.map +1 -0
- package/lib/typescript/src/features/index.d.ts +2 -0
- package/lib/typescript/src/features/index.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +6 -4
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +27 -0
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
- package/lib/typescript/src/features/output.d.ts +28 -18
- package/lib/typescript/src/features/output.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/controls.d.ts +5 -0
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/index.d.ts +1 -0
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/progress.d.ts +3 -0
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +34 -0
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/volume.d.ts +1 -1
- package/lib/typescript/src/features/player/options.d.ts +92 -93
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/player/setup.d.ts +206 -167
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts +9 -2
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
- package/lib/typescript/src/features/remoteControls.d.ts +0 -13
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts +18 -3
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native.d.ts +1 -2
- package/lib/typescript/src/native.d.ts.map +1 -1
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +17 -225
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-native.d.ts +9 -3
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-nodes.d.ts +145 -13
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
- package/lib/typescript/src/types/browser.d.ts +349 -85
- package/lib/typescript/src/types/browser.d.ts.map +1 -1
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +0 -2
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +0 -2
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
- package/lib/typescript/src/utils/artwork.d.ts +19 -0
- package/lib/typescript/src/utils/artwork.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +3 -1
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +24 -10
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +6 -6
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/JArtworkVariants.hpp +61 -0
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +5 -0
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +58 -0
- package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +58 -0
- package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +100 -0
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +3 -2
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +112 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +123 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +133 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +139 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +134 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +8 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +131 -0
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +0 -10
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -4
- package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +10 -10
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +6 -0
- package/nitrogen/generated/android/c++/JGate.hpp +62 -0
- package/nitrogen/generated/android/c++/JGateDecision.hpp +64 -0
- package/nitrogen/generated/android/c++/{JThumbsRating.hpp → JGateEvent.hpp} +16 -15
- package/nitrogen/generated/android/c++/JGateReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +236 -212
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +25 -22
- package/nitrogen/generated/android/c++/JIOSOptions.hpp +95 -0
- package/nitrogen/generated/android/c++/JImageRowItem.hpp +33 -3
- package/nitrogen/generated/android/c++/JMediaReference.hpp +58 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/{JPartialAndroidSetupPlayerOptions.hpp → JNativeAndroidSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +61 -28
- package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +74 -0
- package/nitrogen/generated/android/c++/{JPartialIOSSetupPlayerOptions.hpp → JNativeIOSSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +20 -9
- package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +182 -0
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +16 -19
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +6 -0
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JNotificationButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +3 -17
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +7 -3
- package/nitrogen/generated/android/c++/JOptions.hpp +14 -9
- package/nitrogen/generated/android/c++/{JIosOutput.hpp → JOutput.hpp} +15 -15
- package/nitrogen/generated/android/c++/JOutputType.hpp +82 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +18 -3
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +76 -0
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +3 -3
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +11 -5
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +11 -7
- package/nitrogen/generated/android/c++/JSearchMode.hpp +27 -9
- package/nitrogen/generated/android/c++/JSearchParams.hpp +9 -3
- package/nitrogen/generated/android/c++/JStallReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JTrackRequest.hpp +93 -0
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +14 -1
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +71 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.cpp +41 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +121 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{ThumbsRating.kt → FavoriteConfig.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RatingType.kt → FavoritesMatchMode.kt} +5 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.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 → Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_RemoteSetRatingEvent.kt → Func_void_GateEvent.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_IosOutput.kt → Func_void_Output.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{HeartRating.kt → Gate.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PercentageRating.kt → GateDecision.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{StarRating.kt → GateEvent.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +103 -109
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +24 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaReference.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialAndroidSetupPlayerOptions.kt → NativeAndroidSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +18 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RemoteSetRatingEvent.kt → NativeGateRequest.kt} +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialIOSSetupPlayerOptions.kt → NativeIOSSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +3 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{IosOutput.kt → Output.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/OutputType.kt +31 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorKind.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StallReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +53 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +139 -28
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +1098 -447
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +60 -39
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +170 -112
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +8 -8
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +2 -12
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +95 -1
- package/nitrogen/generated/ios/swift/ArtworkVariants.swift +34 -0
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +4 -4
- package/nitrogen/generated/ios/swift/FavoriteConfig.swift +29 -0
- package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +40 -0
- package/nitrogen/generated/ios/swift/FormatNowPlayingParams.swift +67 -0
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +17 -4
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___Track.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_std__string____Track.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.swift +77 -0
- package/nitrogen/generated/ios/swift/Func_void_GateDecision.swift +46 -0
- package/nitrogen/generated/ios/swift/{Func_void_RemoteSetRatingEvent.swift → Func_void_GateEvent.swift} +10 -10
- package/nitrogen/generated/ios/swift/{Func_void_IosOutput.swift → Func_void_Output.swift} +10 -10
- package/nitrogen/generated/ios/swift/Func_void_TransformableRequestConfig.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NowPlayingUpdate_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +53 -0
- package/nitrogen/generated/ios/swift/{Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift → Func_void_std__shared_ptr_Promise_GateDecision__.swift} +17 -17
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_TransformableRequestConfig__.swift +66 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError____.swift +81 -0
- package/nitrogen/generated/ios/swift/Gate.swift +47 -0
- package/nitrogen/generated/ios/swift/GateDecision.swift +40 -0
- package/nitrogen/generated/ios/swift/GateEvent.swift +29 -0
- package/nitrogen/generated/ios/swift/GateReason.swift +40 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +20 -14
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +230 -197
- package/nitrogen/generated/ios/swift/IOSOptions.swift +51 -0
- package/nitrogen/generated/ios/swift/ImageRowItem.swift +121 -2
- package/nitrogen/generated/ios/swift/MediaReference.swift +40 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +107 -1
- package/nitrogen/generated/ios/swift/{PartialAndroidSetupPlayerOptions.swift → NativeAndroidSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +161 -22
- package/nitrogen/generated/ios/swift/NativeGateRequest.swift +58 -0
- package/nitrogen/generated/ios/swift/{PartialIOSSetupPlayerOptions.swift → NativeIOSSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +19 -19
- package/nitrogen/generated/ios/swift/NativeSetupPlayerOptions.swift +206 -0
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +12 -25
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +8 -0
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +1 -30
- package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +90 -0
- package/nitrogen/generated/ios/swift/NotificationButton.swift +4 -4
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +1 -48
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +19 -1
- package/nitrogen/generated/ios/swift/Options.swift +10 -4
- package/nitrogen/generated/ios/swift/{IosOutput.swift → Output.swift} +7 -7
- package/nitrogen/generated/ios/swift/OutputType.swift +72 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +43 -2
- package/nitrogen/generated/ios/swift/PlaybackErrorKind.swift +64 -0
- package/nitrogen/generated/ios/swift/PlaybackState.swift +4 -4
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +27 -8
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +74 -8
- package/nitrogen/generated/ios/swift/RetryConfig.swift +35 -4
- package/nitrogen/generated/ios/swift/SearchMode.swift +36 -12
- package/nitrogen/generated/ios/swift/SearchParams.swift +7 -2
- package/nitrogen/generated/ios/swift/StallReason.swift +40 -0
- package/nitrogen/generated/ios/swift/Track.swift +74 -8
- package/nitrogen/generated/ios/swift/TrackRequest.swift +106 -0
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +60 -1
- package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +19 -0
- package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +18 -0
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +10 -10
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/ArtworkVariants.hpp +87 -0
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +6 -6
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +0 -2
- package/nitrogen/generated/shared/c++/{StarRating.hpp → FavoriteConfig.hpp} +18 -17
- package/nitrogen/generated/shared/c++/FavoritesMatchMode.hpp +76 -0
- package/nitrogen/generated/shared/c++/FormatNowPlayingParams.hpp +110 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +6 -5
- package/nitrogen/generated/shared/c++/{HeartRating.hpp → Gate.hpp} +21 -16
- package/nitrogen/generated/shared/c++/{ThumbsRating.hpp → GateDecision.hpp} +23 -17
- package/nitrogen/generated/shared/c++/{PercentageRating.hpp → GateEvent.hpp} +18 -17
- package/nitrogen/generated/shared/c++/GateReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +21 -18
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +44 -35
- package/nitrogen/generated/shared/c++/IOSOptions.hpp +91 -0
- package/nitrogen/generated/shared/c++/ImageRowItem.hpp +33 -2
- package/nitrogen/generated/shared/c++/MediaReference.hpp +76 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/{PartialAndroidSetupPlayerOptions.hpp → NativeAndroidSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +31 -15
- package/nitrogen/generated/shared/c++/NativeGateRequest.hpp +97 -0
- package/nitrogen/generated/shared/c++/{PartialIOSSetupPlayerOptions.hpp → NativeIOSSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +5 -5
- package/nitrogen/generated/shared/c++/NativeSetupPlayerOptions.hpp +138 -0
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +9 -7
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +8 -0
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +92 -0
- package/nitrogen/generated/shared/c++/NotificationButton.hpp +8 -8
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +3 -19
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +6 -2
- package/nitrogen/generated/shared/c++/Options.hpp +8 -8
- package/nitrogen/generated/shared/c++/{IosOutput.hpp → Output.hpp} +18 -18
- package/nitrogen/generated/shared/c++/OutputType.hpp +108 -0
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +18 -3
- package/nitrogen/generated/shared/c++/PlaybackErrorKind.hpp +100 -0
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +9 -9
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +9 -6
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +24 -5
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +10 -6
- package/nitrogen/generated/shared/c++/SearchMode.hpp +39 -15
- package/nitrogen/generated/shared/c++/SearchParams.hpp +9 -2
- package/nitrogen/generated/shared/c++/StallReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/Track.hpp +24 -5
- package/nitrogen/generated/shared/c++/TrackRequest.hpp +93 -0
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +6 -2
- package/package.json +11 -6
- package/src/codegen-no-config-variant.test.ts +70 -0
- package/src/features/browser-config.test.ts +110 -0
- package/src/features/browser-config.ts +293 -0
- package/src/features/browser.test.ts +19 -0
- package/src/features/browser.ts +58 -201
- package/src/features/carConnection.ts +36 -0
- package/src/features/errors.ts +68 -2
- package/src/features/gate.test.ts +72 -0
- package/src/features/gate.ts +155 -0
- package/src/features/index.ts +2 -0
- package/src/features/metadata.ts +6 -12
- package/src/features/nowPlaying.ts +36 -0
- package/src/features/output.ts +35 -22
- package/src/features/playback/controls.ts +8 -0
- package/src/features/playback/index.ts +1 -0
- package/src/features/playback/progress.ts +31 -12
- package/src/features/playback/trackPlaybackTime.test.ts +66 -0
- package/src/features/playback/trackPlaybackTime.ts +106 -0
- package/src/features/playback/volume.ts +1 -1
- package/src/features/player/options.test.ts +38 -0
- package/src/features/player/options.ts +140 -75
- package/src/features/player/setup.test.ts +117 -0
- package/src/features/player/setup.ts +390 -175
- package/src/features/queue/queue.test.ts +36 -0
- package/src/features/queue/queue.ts +15 -4
- package/src/features/remoteControls.ts +0 -23
- package/src/features/sleepTimer.ts +23 -4
- package/src/native.ts +5 -0
- package/src/native.web.ts +4 -1
- package/src/specs/audio-browser.nitro.ts +131 -41
- package/src/types/browser-native.ts +19 -6
- package/src/types/browser-nodes.ts +160 -13
- package/src/types/browser.ts +377 -89
- package/src/utils/LazyNativeEmitter.ts +0 -2
- package/src/utils/NativeUpdatedValue.ts +0 -2
- package/src/utils/artwork.ts +30 -0
- package/src/web/NativeAudioBrowser.playWhenReady.test.ts +301 -0
- package/src/web/NativeAudioBrowser.ts +365 -158
- package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +139 -0
- package/src/web/TrackPlayer/PlaybackStateMachine.ts +82 -0
- package/src/web/TrackPlayer/PlaybackTimer.test.ts +67 -0
- package/src/web/TrackPlayer/PlaybackTimer.ts +33 -0
- package/src/web/TrackPlayer/Player.dispatch.test.ts +229 -0
- package/src/web/TrackPlayer/Player.load.test.ts +86 -0
- package/src/web/TrackPlayer/Player.ts +113 -39
- package/src/web/TrackPlayer/PlayingStateFactory.test.ts +51 -0
- package/src/web/TrackPlayer/PlayingStateFactory.ts +24 -0
- package/src/web/TrackPlayer/QueueManager.test.ts +289 -0
- package/src/web/TrackPlayer/QueueManager.ts +302 -0
- package/src/web/TrackPlayer/QueuePlayer.ts +188 -0
- package/src/web/TrackPlayer/RepeatMode.ts +1 -1
- package/src/web/TrackPlayer/SleepTimer.ts +38 -3
- package/src/web/TrackPlayer/VolumeFader.ts +74 -0
- package/src/web/TrackPlayer/index.ts +2 -1
- package/src/web/browser/BrowserManager.ts +231 -62
- package/src/web/browser/NavigationErrorManager.ts +3 -1
- package/src/web/browser/SearchManager.ts +11 -15
- package/src/web/browser/__tests__/layer-resolver.test.ts +69 -0
- package/src/web/browser/assertBrowsePageShape.test.ts +27 -0
- package/src/web/browser/assertBrowsePageShape.ts +27 -0
- package/src/web/browser/classifyTrackNavigation.test.ts +41 -0
- package/src/web/browser/classifyTrackNavigation.ts +35 -0
- package/src/web/browser/parseSearchResponse.test.ts +25 -0
- package/src/web/browser/parseSearchResponse.ts +15 -0
- package/src/web/http/HttpClient.ts +5 -35
- package/src/web/http/RequestConfigBuilder.test.ts +59 -0
- package/src/web/http/RequestConfigBuilder.ts +120 -63
- package/src/web/playbackErrorKind.test.ts +55 -0
- package/src/web/playbackErrorKind.ts +56 -0
- package/src/web/player/MediaSessionManager.test.ts +220 -0
- package/src/web/player/MediaSessionManager.ts +151 -0
- package/src/web/player/NowPlayingManager.test.ts +46 -0
- package/src/web/player/NowPlayingManager.ts +6 -5
- package/src/web/player/OptionsManager.ts +12 -18
- package/src/web/player/RemoteCommandController.test.ts +171 -0
- package/src/web/player/RemoteCommandController.ts +166 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +0 -59
- package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +0 -72
- package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +0 -36
- package/android/src/test/java/com/audiobrowser/player/PlaybackProgressUpdateManagerTest.kt +0 -146
- package/ios/CarPlay/Track+CarPlay.swift +0 -63
- package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +0 -9
- package/ios/Player/PlaybackProgressUpdateManager.swift +0 -68
- package/ios/Tests/PlaybackProgressUpdateManagerTests.swift +0 -166
- package/lib/commonjs/features/rating.js +0 -2
- package/lib/commonjs/features/rating.js.map +0 -1
- package/lib/commonjs/types/player.js +0 -2
- package/lib/commonjs/types/player.js.map +0 -1
- package/lib/commonjs/web/SimpleRouter.test.js +0 -174
- package/lib/commonjs/web/SimpleRouter.test.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +0 -293
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
- package/lib/module/features/rating.js +0 -2
- package/lib/module/features/rating.js.map +0 -1
- package/lib/module/types/player.js +0 -2
- package/lib/module/types/player.js.map +0 -1
- package/lib/module/web/SimpleRouter.test.js +0 -174
- package/lib/module/web/SimpleRouter.test.js.map +0 -1
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +0 -288
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
- package/lib/typescript/src/features/rating.d.ts +0 -14
- package/lib/typescript/src/features/rating.d.ts.map +0 -1
- package/lib/typescript/src/native.web.d.ts +0 -3
- package/lib/typescript/src/native.web.d.ts.map +0 -1
- package/lib/typescript/src/types/player.d.ts +0 -64
- package/lib/typescript/src/types/player.d.ts.map +0 -1
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +0 -188
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +0 -1
- package/lib/typescript/src/web/SimpleRouter.d.ts +0 -40
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +0 -1
- package/lib/typescript/src/web/SimpleRouter.test.d.ts +0 -2
- package/lib/typescript/src/web/SimpleRouter.test.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts +0 -11
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +0 -59
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +0 -39
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +0 -6
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +0 -4
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +0 -34
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/State.d.ts +0 -13
- package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/index.d.ts +0 -5
- package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/BrowserManager.d.ts +0 -154
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts +0 -42
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +0 -40
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/SearchManager.d.ts +0 -22
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +0 -1
- package/lib/typescript/src/web/http/HttpClient.d.ts +0 -25
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +0 -1
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +0 -98
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +0 -1
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts +0 -34
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +0 -1
- package/lib/typescript/src/web/player/OptionsManager.d.ts +0 -32
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +0 -1
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +0 -69
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +0 -1
- package/lib/typescript/src/web/util/shuffle.d.ts +0 -8
- package/lib/typescript/src/web/util/shuffle.d.ts.map +0 -1
- package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +0 -86
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +0 -147
- package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +0 -80
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +0 -87
- package/nitrogen/generated/android/c++/JHeartRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JIosOutputType.hpp +0 -85
- package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +0 -96
- package/nitrogen/generated/android/c++/JPercentageRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JRatingType.hpp +0 -73
- package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +0 -66
- package/nitrogen/generated/android/c++/JStarRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JUpdateOptions.hpp +0 -105
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +0 -34
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +0 -105
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +0 -50
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +0 -32
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +0 -47
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +0 -53
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +0 -77
- package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +0 -119
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +0 -68
- package/nitrogen/generated/ios/swift/HeartRating.swift +0 -29
- package/nitrogen/generated/ios/swift/IosOutputType.swift +0 -76
- package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +0 -101
- package/nitrogen/generated/ios/swift/PercentageRating.swift +0 -29
- package/nitrogen/generated/ios/swift/RatingType.swift +0 -60
- package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +0 -58
- package/nitrogen/generated/ios/swift/StarRating.swift +0 -29
- package/nitrogen/generated/ios/swift/ThumbsRating.swift +0 -29
- package/nitrogen/generated/ios/swift/UpdateOptions.swift +0 -143
- package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +0 -20
- package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +0 -109
- package/nitrogen/generated/shared/c++/IosOutputType.hpp +0 -112
- package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +0 -104
- package/nitrogen/generated/shared/c++/RatingType.hpp +0 -96
- package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +0 -94
- package/nitrogen/generated/shared/c++/UpdateOptions.hpp +0 -111
- package/src/features/rating.ts +0 -17
- package/src/types/player.ts +0 -69
- package/src/web/TrackPlayer/PlaylistPlayer.ts +0 -346
|
@@ -36,10 +36,6 @@ final class CarPlayImageLoader {
|
|
|
36
36
|
return sfSymbolImageForSize(symbolName, canvasSize: canvasSize, backgroundColor: bg, symbolColor: fg)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
func defaultTabImage() -> UIImage? {
|
|
40
|
-
sfSymbolImage("music.note.list")
|
|
41
|
-
}
|
|
42
|
-
|
|
43
39
|
/// Cached empty placeholder image to reserve space while artwork loads
|
|
44
40
|
lazy var placeholderImage: UIImage? = {
|
|
45
41
|
let size = CPListItem.maximumImageSize
|
|
@@ -57,6 +53,16 @@ final class CarPlayImageLoader {
|
|
|
57
53
|
/// - size: The target size in points (will be multiplied by CarPlay display scale)
|
|
58
54
|
/// - completion: Called with the loaded image, or nil on failure
|
|
59
55
|
func loadArtwork(for track: Track, size: CGSize, completion: @escaping @Sendable (UIImage?) -> Void) {
|
|
56
|
+
// A track that ships one image per appearance is loaded as two ordinary
|
|
57
|
+
// single-URL loads and combined below. Recursing rather than branching
|
|
58
|
+
// inside the loader means each variant still goes through the whole
|
|
59
|
+
// pipeline — route config, headers, SVG rasterising, the resolve transform
|
|
60
|
+
// — instead of a second, thinner fetch path that would drift from it.
|
|
61
|
+
if let variants = track.artwork?.variants {
|
|
62
|
+
loadVariants(for: track, variants: variants, size: size, completion: completion)
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
60
66
|
// Build URL resolver closure that wraps BrowserManager
|
|
61
67
|
let urlResolver: ((Double, Double) async -> ArtworkResolvedImage?)? = browserManager.map { bm in
|
|
62
68
|
{ [weak bm] pixelWidth, pixelHeight in
|
|
@@ -69,19 +75,19 @@ final class CarPlayImageLoader {
|
|
|
69
75
|
|
|
70
76
|
Task {
|
|
71
77
|
let action = await CarPlayArtworkResolver.resolve(
|
|
72
|
-
artwork: track.artwork,
|
|
78
|
+
artwork: track.artwork?.url,
|
|
73
79
|
artworkSourceUri: track.artworkSource?.uri,
|
|
74
80
|
artworkCarPlayTinted: track.artworkCarPlayTinted,
|
|
75
81
|
targetWidth: Double(size.width),
|
|
76
82
|
targetHeight: Double(size.height),
|
|
77
83
|
displayScale: Double(self.carTraitCollection.displayScale),
|
|
78
|
-
urlResolver: urlResolver
|
|
84
|
+
urlResolver: urlResolver,
|
|
79
85
|
)
|
|
80
86
|
|
|
81
87
|
switch action {
|
|
82
|
-
case .sfSymbol(
|
|
88
|
+
case let .sfSymbol(artwork, width, height):
|
|
83
89
|
completion(self.sfSymbolImage(forArtwork: artwork, canvasSize: CGSize(width: width, height: height)))
|
|
84
|
-
case .fetch(
|
|
90
|
+
case let .fetch(uri, headers, shouldTint, isSvg):
|
|
85
91
|
let image = await self.fetchImage(uri: uri, headers: headers, isSvg: isSvg)
|
|
86
92
|
if let image, shouldTint {
|
|
87
93
|
completion(self.createAdaptiveImage(image, carTraitCollection: self.carTraitCollection))
|
|
@@ -96,6 +102,49 @@ final class CarPlayImageLoader {
|
|
|
96
102
|
|
|
97
103
|
// MARK: - Private
|
|
98
104
|
|
|
105
|
+
/// Loads both images of an `ArtworkVariants` pair and returns them as one
|
|
106
|
+
/// adaptive image.
|
|
107
|
+
///
|
|
108
|
+
/// The pair is registered on a `UIImageAsset`, which is what makes an
|
|
109
|
+
/// appearance change mid-drive re-resolve in place: CarPlay re-reads the
|
|
110
|
+
/// asset against the new trait collection, so the row swaps image without
|
|
111
|
+
/// another fetch or a re-query of the browse tree.
|
|
112
|
+
///
|
|
113
|
+
/// If either half fails to load, the other is used alone rather than dropping
|
|
114
|
+
/// the row's image entirely — a glyph that is wrong for one appearance still
|
|
115
|
+
/// beats an empty slot, and this is usually a transient fetch failure.
|
|
116
|
+
private func loadVariants(
|
|
117
|
+
for track: Track,
|
|
118
|
+
variants: ArtworkVariants,
|
|
119
|
+
size: CGSize,
|
|
120
|
+
completion: @escaping @Sendable (UIImage?) -> Void,
|
|
121
|
+
) {
|
|
122
|
+
Task {
|
|
123
|
+
async let light = self.loadArtworkAsync(for: track.copying(artwork: .some(.first(variants.light))), size: size)
|
|
124
|
+
async let dark = self.loadArtworkAsync(for: track.copying(artwork: .some(.first(variants.dark))), size: size)
|
|
125
|
+
let (lightImage, darkImage) = await (light, dark)
|
|
126
|
+
|
|
127
|
+
guard let lightImage, let darkImage else {
|
|
128
|
+
completion(lightImage ?? darkImage)
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let asset = UIImageAsset()
|
|
133
|
+
asset.register(lightImage, with: UITraitCollection(userInterfaceStyle: .light))
|
|
134
|
+
asset.register(darkImage, with: UITraitCollection(userInterfaceStyle: .dark))
|
|
135
|
+
completion(asset.image(with: self.carTraitCollection))
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// `loadArtwork` as an awaitable, so the two variants can load concurrently.
|
|
140
|
+
private func loadArtworkAsync(for track: Track, size: CGSize) async -> UIImage? {
|
|
141
|
+
await withCheckedContinuation { continuation in
|
|
142
|
+
self.loadArtwork(for: track, size: size) { image in
|
|
143
|
+
continuation.resume(returning: image)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
99
148
|
/// Fetches an image from a URL with optional headers and SVG processing.
|
|
100
149
|
private func fetchImage(uri: String, headers: [String: String]?, isSvg: Bool) async -> UIImage? {
|
|
101
150
|
let source = ImageSource(uri: uri, method: nil, headers: headers, body: nil)
|
|
@@ -7,6 +7,7 @@ import os.log
|
|
|
7
7
|
|
|
8
8
|
/// Typed metadata stored on CPListItems, replacing stringly-typed userInfo dictionaries.
|
|
9
9
|
struct CarPlayItemInfo {
|
|
10
|
+
let id: String?
|
|
10
11
|
let src: String?
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -28,12 +29,12 @@ final class CarPlayListItemFactory {
|
|
|
28
29
|
private let logger = Logger(subsystem: "com.audiobrowser", category: "CarPlayListItemFactory")
|
|
29
30
|
|
|
30
31
|
var imageLoader: CarPlayImageLoader?
|
|
31
|
-
private let isActiveTrack: (String) -> Bool
|
|
32
|
+
private let isActiveTrack: (_ id: String?, _ src: String?) -> Bool
|
|
32
33
|
private let onItemSelected: (Track, @escaping () -> Void) -> Void
|
|
33
34
|
|
|
34
35
|
init(
|
|
35
|
-
isActiveTrack: @escaping (String) -> Bool,
|
|
36
|
-
onItemSelected: @escaping (Track, @escaping () -> Void) -> Void
|
|
36
|
+
isActiveTrack: @escaping (_ id: String?, _ src: String?) -> Bool,
|
|
37
|
+
onItemSelected: @escaping (Track, @escaping () -> Void) -> Void,
|
|
37
38
|
) {
|
|
38
39
|
self.isActiveTrack = isActiveTrack
|
|
39
40
|
self.onItemSelected = onItemSelected
|
|
@@ -49,49 +50,44 @@ final class CarPlayListItemFactory {
|
|
|
49
50
|
let maxSections = CPListTemplate.maximumSectionCount
|
|
50
51
|
let maxTotalItems = CPListTemplate.maximumItemCount
|
|
51
52
|
|
|
52
|
-
//
|
|
53
|
-
|
|
53
|
+
// Contiguous runs sharing a groupTitle form a section (the same semantics
|
|
54
|
+
// Android Auto's GROUP_TITLE hint has), so sections — titled or not —
|
|
55
|
+
// render in exact source (server) order. Ungrouped runs become headerless
|
|
56
|
+
// sections in place rather than being hoisted to the top.
|
|
57
|
+
var runs: [(title: String?, tracks: [Track])] = []
|
|
54
58
|
for track in children {
|
|
55
|
-
let
|
|
56
|
-
|
|
59
|
+
if let last = runs.indices.last, runs[last].title == track.groupTitle {
|
|
60
|
+
runs[last].tracks.append(track)
|
|
61
|
+
} else {
|
|
62
|
+
runs.append((track.groupTitle, [track]))
|
|
63
|
+
}
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
// Create sections (respecting both section and total item limits)
|
|
60
67
|
var sections: [CPListSection] = []
|
|
61
68
|
var totalItemCount = 0
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
if let ungrouped = groups[nil], !ungrouped.isEmpty {
|
|
65
|
-
let availableSlots = maxTotalItems - totalItemCount
|
|
66
|
-
let items: [CPListTemplateItem] = ungrouped.prefix(availableSlots).map { track in
|
|
67
|
-
if track.imageRow != nil {
|
|
68
|
-
return createImageRowItem(for: track)
|
|
69
|
-
}
|
|
70
|
-
return createListItem(for: track)
|
|
71
|
-
}
|
|
72
|
-
if !items.isEmpty {
|
|
73
|
-
sections.append(CPListSection(items: items))
|
|
74
|
-
totalItemCount += items.count
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Then grouped items (respecting section and item limits)
|
|
79
|
-
for (groupTitle, tracks) in groups.sorted(by: { ($0.key ?? "") < ($1.key ?? "") }) {
|
|
70
|
+
for run in runs {
|
|
80
71
|
guard sections.count < maxSections else { break }
|
|
81
72
|
guard totalItemCount < maxTotalItems else { break }
|
|
82
|
-
guard groupTitle != nil else { continue }
|
|
83
73
|
|
|
84
74
|
let availableSlots = maxTotalItems - totalItemCount
|
|
85
|
-
let items: [CPListTemplateItem] = tracks.prefix(availableSlots).map { track in
|
|
86
|
-
|
|
75
|
+
let items: [CPListTemplateItem] = run.tracks.prefix(availableSlots).map { track in
|
|
76
|
+
// Empty image rows fall through to a plain list item: zero-image
|
|
77
|
+
// CPListImageRowItem init is undocumented territory, and a header-only
|
|
78
|
+
// row is a dead end regardless (a "popular" row with no entries yet).
|
|
79
|
+
if let imageRow = track.imageRow, !imageRow.isEmpty {
|
|
87
80
|
return createImageRowItem(for: track)
|
|
88
81
|
}
|
|
89
82
|
return createListItem(for: track)
|
|
90
83
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
guard !items.isEmpty else { continue }
|
|
85
|
+
if let title = run.title {
|
|
86
|
+
sections.append(CPListSection(items: items, header: title, sectionIndexTitle: nil))
|
|
87
|
+
} else {
|
|
88
|
+
sections.append(CPListSection(items: items))
|
|
94
89
|
}
|
|
90
|
+
totalItemCount += items.count
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
return sections
|
|
@@ -105,21 +101,28 @@ final class CarPlayListItemFactory {
|
|
|
105
101
|
/// - handler: Optional custom handler. If nil, uses default browse/play handling.
|
|
106
102
|
func createListItem(
|
|
107
103
|
for track: Track,
|
|
108
|
-
handler: ((CPSelectableListItem, @escaping () -> Void) -> Void)? = nil
|
|
104
|
+
handler: ((CPSelectableListItem, @escaping () -> Void) -> Void)? = nil,
|
|
109
105
|
) -> CPListItem {
|
|
110
106
|
let item = CPListItem(
|
|
111
107
|
text: track.title,
|
|
112
|
-
detailText: track.subtitle
|
|
108
|
+
detailText: track.subtitle,
|
|
113
109
|
)
|
|
114
110
|
|
|
115
111
|
// Store typed info for updatePlayingIndicators()
|
|
116
|
-
item.setCarPlayItemInfo(CarPlayItemInfo(src: track.src))
|
|
112
|
+
item.setCarPlayItemInfo(CarPlayItemInfo(id: track.id, src: track.src))
|
|
117
113
|
|
|
118
114
|
// Set accessory type based on whether track is browsable or playable
|
|
119
115
|
if let src = track.src {
|
|
120
116
|
// Playable track - check if it's currently playing
|
|
121
117
|
item.accessoryType = .none
|
|
122
|
-
|
|
118
|
+
// Leading (the system default, set explicitly to make the choice
|
|
119
|
+
// deliberate): the indicator draws in the artwork slot. Note the
|
|
120
|
+
// indicator's rendering is owned by the phone's CarPlay service, and on
|
|
121
|
+
// some iOS/CarPlay-Simulator combinations it isn't drawn at all — for
|
|
122
|
+
// ANY third-party app. Verify on a real head unit before assuming a
|
|
123
|
+
// logic bug here.
|
|
124
|
+
item.playingIndicatorLocation = .leading
|
|
125
|
+
item.isPlaying = isActiveTrack(track.id, src)
|
|
123
126
|
if item.isPlaying {
|
|
124
127
|
logger.debug("Setting isPlaying=true for: \(track.title) (src: \(src))")
|
|
125
128
|
}
|
|
@@ -173,8 +176,14 @@ final class CarPlayListItemFactory {
|
|
|
173
176
|
CPListImageRowItem(text: track.title, images: placeholders)
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
// Handler for row header tap → navigate to track.url if present
|
|
179
|
+
// Handler for row header tap → navigate to track.url if present. A row
|
|
180
|
+
// without a url (pure preview) has nothing to open, so its header tap is
|
|
181
|
+
// a no-op rather than a selection that can't resolve.
|
|
177
182
|
item.handler = { [onItemSelected] _, completion in
|
|
183
|
+
guard track.url != nil else {
|
|
184
|
+
completion()
|
|
185
|
+
return
|
|
186
|
+
}
|
|
178
187
|
onItemSelected(track, completion)
|
|
179
188
|
}
|
|
180
189
|
|
|
@@ -16,19 +16,59 @@ final class CarPlayNowPlayingManager {
|
|
|
16
16
|
|
|
17
17
|
private let interfaceController: CPInterfaceController
|
|
18
18
|
var listItemFactory: (Track, ((CPSelectableListItem, @escaping () -> Void) -> Void)?) -> CPListItem
|
|
19
|
+
/// Pushes a browse destination (wired to the controller's navigateToUrl).
|
|
20
|
+
var navigateToUrl: ((_ url: String, _ title: String) -> Void)?
|
|
19
21
|
|
|
20
22
|
private weak var audioBrowser: HybridAudioBrowser?
|
|
21
23
|
private var nowPlayingObserver: NowPlayingObserver?
|
|
22
24
|
private weak var upNextTemplate: CPListTemplate?
|
|
25
|
+
/// Everything the built button row renders — button types, the heart's
|
|
26
|
+
/// favorited state, and the shuffle/repeat `isSelected` state. Rebuilds are
|
|
27
|
+
/// skipped while this is unchanged (`onConfigChanged` fires on unrelated
|
|
28
|
+
/// churn, and every `updateNowPlayingButtons` call re-renders ALL buttons).
|
|
29
|
+
///
|
|
30
|
+
/// shuffle/repeat selected state is part of the snapshot because CarPlay
|
|
31
|
+
/// SERIALIZES the buttons (NSSecureCoding) to its UI process: whenever the
|
|
32
|
+
/// now-playing screen re-renders (it does on every metadata change), the
|
|
33
|
+
/// stateful buttons first draw from their serialized `isSelected`, and only
|
|
34
|
+
/// then overlay the live state the app reports via the command center. A
|
|
35
|
+
/// button built with the default `isSelected = false` while repeat/shuffle
|
|
36
|
+
/// is on therefore flashes background-off → background-on at every
|
|
37
|
+
/// re-render. Stamping `isSelected` at build time (and rebuilding when the
|
|
38
|
+
/// mode changes) makes the first-frame render match the live state.
|
|
39
|
+
private struct BuiltButtonRow: Equatable {
|
|
40
|
+
let types: [CarPlayNowPlayingButton]
|
|
41
|
+
let favorited: Bool?
|
|
42
|
+
let shuffleSelected: Bool?
|
|
43
|
+
let repeatSelected: Bool?
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private var builtRow: BuiltButtonRow?
|
|
47
|
+
|
|
48
|
+
/// Browse path the album line navigates to for the active track —
|
|
49
|
+
/// `track.albumUrl`, or the pre-resolved `resolveAlbumUrl` result. Resolved
|
|
50
|
+
/// at track-change time (not at tap) so the album line only surfaces when a
|
|
51
|
+
/// destination actually exists.
|
|
52
|
+
private var albumArtistDestination: String?
|
|
53
|
+
/// Drops a stale async `resolveAlbumUrl` result when the track changed while
|
|
54
|
+
/// the resolver was in flight (latest-update-wins).
|
|
55
|
+
private var albumArtistGeneration: UInt = 0
|
|
56
|
+
/// The just-tapped track whose load is still in flight. CarPlay reads
|
|
57
|
+
/// `isAlbumArtistButtonEnabled` when the template is displayed (a change while
|
|
58
|
+
/// visible doesn't re-render), and Now Playing is pushed at tap time — before
|
|
59
|
+
/// the player's `currentTrack` reflects the tap — so the flag must be derived
|
|
60
|
+
/// from the tapped track at push time. Cleared when the active track changes.
|
|
61
|
+
private var pendingAlbumArtistTrack: Track?
|
|
23
62
|
|
|
24
63
|
/// Convenience accessor for browser config
|
|
25
64
|
private var config: BrowserConfig {
|
|
26
65
|
audioBrowser?.browserManager.config ?? BrowserConfig()
|
|
27
66
|
}
|
|
28
67
|
|
|
29
|
-
///
|
|
68
|
+
/// The active track's favorited state, from the authoritative favorite set
|
|
69
|
+
/// (see `HybridAudioBrowser.isActiveTrackFavorited`).
|
|
30
70
|
private var isActiveTrackFavorited: Bool {
|
|
31
|
-
|
|
71
|
+
audioBrowser?.isActiveTrackFavorited() ?? false
|
|
32
72
|
}
|
|
33
73
|
|
|
34
74
|
init(interfaceController: CPInterfaceController) {
|
|
@@ -48,6 +88,7 @@ final class CarPlayNowPlayingManager {
|
|
|
48
88
|
CPNowPlayingTemplate.shared.remove(observer)
|
|
49
89
|
nowPlayingObserver = nil
|
|
50
90
|
}
|
|
91
|
+
pendingAlbumArtistTrack = nil
|
|
51
92
|
audioBrowser = nil
|
|
52
93
|
}
|
|
53
94
|
|
|
@@ -64,9 +105,30 @@ final class CarPlayNowPlayingManager {
|
|
|
64
105
|
updateNowPlayingButtonStates()
|
|
65
106
|
}
|
|
66
107
|
|
|
67
|
-
/// Sets up custom Now Playing buttons based on configuration
|
|
108
|
+
/// Sets up custom Now Playing buttons based on configuration and current
|
|
109
|
+
/// player state, skipping the rebuild when nothing the row renders changed.
|
|
68
110
|
func setupNowPlayingButtons() {
|
|
69
|
-
|
|
111
|
+
// While a gate is active, custom buttons (favorite etc.) are hidden;
|
|
112
|
+
// the system transport controls stay — a gate never blocks playback.
|
|
113
|
+
let configured = (audioBrowser?.isGateActive ?? false) ? [] : (audioBrowser?.carPlayNowPlayingButtons ?? [])
|
|
114
|
+
// The template caps custom buttons at 5 (CPNowPlayingTemplate.h) and says
|
|
115
|
+
// nothing about overflow — unlike lists (trim) or the tab bar (throw). The
|
|
116
|
+
// config comes straight from JS, where duplicates and excess are
|
|
117
|
+
// representable, so dedupe (order preserved) and clamp here.
|
|
118
|
+
var deduped: [CarPlayNowPlayingButton] = []
|
|
119
|
+
for button in configured where !deduped.contains(button) {
|
|
120
|
+
deduped.append(button)
|
|
121
|
+
}
|
|
122
|
+
let buttons = Array(deduped.prefix(5))
|
|
123
|
+
let player = audioBrowser?.getPlayer()
|
|
124
|
+
let row = BuiltButtonRow(
|
|
125
|
+
types: buttons,
|
|
126
|
+
favorited: buttons.contains(.favorite) ? isActiveTrackFavorited : nil,
|
|
127
|
+
shuffleSelected: buttons.contains(.shuffle) ? (player?.shuffleEnabled ?? false) : nil,
|
|
128
|
+
repeatSelected: buttons.contains(.repeat) ? (player?.getRepeatMode() ?? .off) != .off : nil,
|
|
129
|
+
)
|
|
130
|
+
guard row != builtRow else { return }
|
|
131
|
+
builtRow = row
|
|
70
132
|
logger.info("Setting up Now Playing buttons: \(buttons.map(\.stringValue))")
|
|
71
133
|
|
|
72
134
|
guard !buttons.isEmpty else {
|
|
@@ -82,17 +144,21 @@ final class CarPlayNowPlayingManager {
|
|
|
82
144
|
let shuffleButton = CPNowPlayingShuffleButton { [weak self] _ in
|
|
83
145
|
self?.handleShuffleButtonTapped()
|
|
84
146
|
}
|
|
147
|
+
// Pre-stamp the serialized selected state — see BuiltButtonRow.
|
|
148
|
+
shuffleButton.isSelected = row.shuffleSelected ?? false
|
|
85
149
|
nowPlayingButtons.append(shuffleButton)
|
|
86
150
|
|
|
87
151
|
case .repeat:
|
|
88
152
|
let repeatButton = CPNowPlayingRepeatButton { [weak self] _ in
|
|
89
153
|
self?.handleRepeatButtonTapped()
|
|
90
154
|
}
|
|
155
|
+
// Pre-stamp the serialized selected state — see BuiltButtonRow.
|
|
156
|
+
repeatButton.isSelected = row.repeatSelected ?? false
|
|
91
157
|
nowPlayingButtons.append(repeatButton)
|
|
92
158
|
|
|
93
159
|
case .favorite:
|
|
94
160
|
let favoriteButton = CPNowPlayingImageButton(
|
|
95
|
-
image: favoriteButtonImage(isFavorited:
|
|
161
|
+
image: favoriteButtonImage(isFavorited: row.favorited ?? false),
|
|
96
162
|
) { [weak self] _ in
|
|
97
163
|
self?.handleFavoriteButtonTapped()
|
|
98
164
|
}
|
|
@@ -112,44 +178,100 @@ final class CarPlayNowPlayingManager {
|
|
|
112
178
|
|
|
113
179
|
// MARK: - Show Now Playing
|
|
114
180
|
|
|
115
|
-
|
|
181
|
+
/// `popToFront` controls what happens when Now Playing is already on the
|
|
182
|
+
/// stack but buried under templates pushed on top of it (Up Next, the album
|
|
183
|
+
/// line's browse destination): a user-initiated surface (tap, voice play)
|
|
184
|
+
/// pops back to it, while the deferred post-resolve calls in
|
|
185
|
+
/// `handleItemSelection` pass `false` — they run seconds after the tap, and
|
|
186
|
+
/// popping then would yank away a screen the user navigated to meanwhile.
|
|
187
|
+
func showNowPlaying(popToFront: Bool = true) {
|
|
116
188
|
updateNowPlayingButtonStates()
|
|
117
189
|
let nowPlayingTemplate = CPNowPlayingTemplate.shared
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
190
|
+
if interfaceController.templates.contains(where: { $0 === nowPlayingTemplate }) {
|
|
191
|
+
if popToFront {
|
|
192
|
+
interfaceController.safePop(to: nowPlayingTemplate, animated: true)
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
interfaceController.safePush(nowPlayingTemplate, animated: true)
|
|
121
196
|
}
|
|
122
|
-
interfaceController.pushTemplate(nowPlayingTemplate, animated: true, completion: nil)
|
|
123
197
|
}
|
|
124
198
|
|
|
125
199
|
// MARK: - Button State Updates
|
|
126
200
|
|
|
127
|
-
///
|
|
201
|
+
/// Refreshes the row for a favorite/shuffle/repeat state change — the
|
|
202
|
+
/// snapshot diff in setupNowPlayingButtons makes this a no-op when nothing
|
|
203
|
+
/// the row renders actually changed.
|
|
128
204
|
func updateFavoriteButtonState() {
|
|
129
|
-
|
|
130
|
-
let favorited = isActiveTrackFavorited
|
|
131
|
-
let buttons = CPNowPlayingTemplate.shared.nowPlayingButtons
|
|
132
|
-
|
|
133
|
-
for (index, button) in buttons.enumerated() {
|
|
134
|
-
if button is CPNowPlayingImageButton {
|
|
135
|
-
let newFavoriteButton = CPNowPlayingImageButton(
|
|
136
|
-
image: favoriteButtonImage(isFavorited: favorited)
|
|
137
|
-
) { [weak self] _ in
|
|
138
|
-
self?.handleFavoriteButtonTapped()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
var updatedButtons = buttons
|
|
142
|
-
updatedButtons[index] = newFavoriteButton
|
|
143
|
-
CPNowPlayingTemplate.shared.updateNowPlayingButtons(updatedButtons)
|
|
144
|
-
break
|
|
145
|
-
}
|
|
146
|
-
}
|
|
205
|
+
setupNowPlayingButtons()
|
|
147
206
|
}
|
|
148
207
|
|
|
149
208
|
/// Updates Now Playing button states based on config and current queue
|
|
150
209
|
func updateNowPlayingButtonStates() {
|
|
151
210
|
updateNowPlayingUpNextButton()
|
|
152
|
-
|
|
211
|
+
setupNowPlayingButtons()
|
|
212
|
+
updateAlbumArtistButtonState()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/// Re-resolves the album line's destination for the active track and
|
|
216
|
+
/// enables the (tappable) album/artist button only when one exists:
|
|
217
|
+
/// `track.albumUrl`, or the app's `resolveAlbumUrl` result.
|
|
218
|
+
/// Marks `track` as the just-tapped (still loading) track and derives the
|
|
219
|
+
/// album line's destination from it. Must run before the Now Playing
|
|
220
|
+
/// template is pushed — CarPlay reads `isAlbumArtistButtonEnabled` at display
|
|
221
|
+
/// time, so enabling after the push (when the load lands) renders no chevron.
|
|
222
|
+
func prepareAlbumArtistButton(for track: Track) {
|
|
223
|
+
pendingAlbumArtistTrack = track
|
|
224
|
+
updateAlbumArtistButtonState()
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// Clears the tap-time pending track (the player's `currentTrack` is now
|
|
228
|
+
/// authoritative) and refreshes all button states.
|
|
229
|
+
func handleActiveTrackChanged() {
|
|
230
|
+
pendingAlbumArtistTrack = nil
|
|
231
|
+
updateNowPlayingButtonStates()
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
func updateAlbumArtistButtonState() {
|
|
235
|
+
albumArtistGeneration &+= 1
|
|
236
|
+
let generation = albumArtistGeneration
|
|
237
|
+
|
|
238
|
+
// The just-tapped track wins while its load is in flight: currentTrack
|
|
239
|
+
// still points at the previous track (or nil) at push time.
|
|
240
|
+
guard let track = pendingAlbumArtistTrack ?? audioBrowser?.getPlayer()?.currentTrack else {
|
|
241
|
+
logger.debug("AlbumArtist: no current track → disabled")
|
|
242
|
+
setAlbumArtistDestination(nil)
|
|
243
|
+
return
|
|
244
|
+
}
|
|
245
|
+
logger.info("AlbumArtist: track=\(track.title) albumUrl=\(track.albumUrl ?? "nil") resolver=\(self.config.resolveAlbumUrl != nil)")
|
|
246
|
+
if let albumUrl = track.albumUrl {
|
|
247
|
+
setAlbumArtistDestination(albumUrl)
|
|
248
|
+
return
|
|
249
|
+
}
|
|
250
|
+
guard let resolver = config.resolveAlbumUrl else {
|
|
251
|
+
setAlbumArtistDestination(nil)
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
Task { @MainActor [weak self] in
|
|
255
|
+
let path: String?
|
|
256
|
+
do {
|
|
257
|
+
path = try await resolver(track).await()
|
|
258
|
+
} catch {
|
|
259
|
+
self?.logger.error("resolveAlbumUrl failed: \(error.localizedDescription)")
|
|
260
|
+
path = nil
|
|
261
|
+
}
|
|
262
|
+
guard let self, self.albumArtistGeneration == generation else { return }
|
|
263
|
+
self.setAlbumArtistDestination(path)
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private func setAlbumArtistDestination(_ path: String?) {
|
|
268
|
+
albumArtistDestination = path
|
|
269
|
+
let template = CPNowPlayingTemplate.shared
|
|
270
|
+
let enabled = path != nil
|
|
271
|
+
if template.isAlbumArtistButtonEnabled != enabled {
|
|
272
|
+
logger.info("AlbumArtist: button \(enabled ? "enabled" : "disabled") (destination: \(path ?? "nil"))")
|
|
273
|
+
template.isAlbumArtistButtonEnabled = enabled
|
|
274
|
+
}
|
|
153
275
|
}
|
|
154
276
|
|
|
155
277
|
// MARK: - Queue Changes
|
|
@@ -231,9 +353,19 @@ final class CarPlayNowPlayingManager {
|
|
|
231
353
|
|
|
232
354
|
// MARK: - Private - Up Next
|
|
233
355
|
|
|
356
|
+
fileprivate func handleAlbumArtistButtonTapped() {
|
|
357
|
+
guard let destination = albumArtistDestination else { return }
|
|
358
|
+
let track = pendingAlbumArtistTrack ?? audioBrowser?.getPlayer()?.currentTrack
|
|
359
|
+
// The album line is what was tapped, so its text is the natural title for
|
|
360
|
+
// the pushed destination (artist may be unset, or the live song).
|
|
361
|
+
let title = track?.album ?? track?.artist ?? track?.title ?? ""
|
|
362
|
+
logger.info("Album/Artist button tapped, navigating to \(destination)")
|
|
363
|
+
navigateToUrl?(destination, title)
|
|
364
|
+
}
|
|
365
|
+
|
|
234
366
|
private func updateNowPlayingUpNextButton() {
|
|
235
367
|
let template = CPNowPlayingTemplate.shared
|
|
236
|
-
template.isUpNextButtonEnabled =
|
|
368
|
+
template.isUpNextButtonEnabled = (audioBrowser?.carPlayUpNextButton ?? true) && (audioBrowser?.getPlayer()?.tracks.count ?? 0) > 1
|
|
237
369
|
}
|
|
238
370
|
|
|
239
371
|
fileprivate func handleUpNextButtonTapped() {
|
|
@@ -251,18 +383,28 @@ final class CarPlayNowPlayingManager {
|
|
|
251
383
|
|
|
252
384
|
logger.info("Showing Up Next queue with \(tracks.count) tracks")
|
|
253
385
|
|
|
386
|
+
// Reuse the now-playing template's button title (system-localized "Up Next"
|
|
387
|
+
// by default, and whatever the app set otherwise) instead of hardcoding an
|
|
388
|
+
// un-localized string.
|
|
389
|
+
let upNextTitle = CPNowPlayingTemplate.shared.upNextTitle
|
|
254
390
|
let template = CPListTemplate(
|
|
255
|
-
title: "Up Next",
|
|
256
|
-
sections: [createUpNextSection(tracks: tracks, player: player)]
|
|
391
|
+
title: upNextTitle.isEmpty ? "Up Next" : upNextTitle,
|
|
392
|
+
sections: [createUpNextSection(tracks: tracks, player: player)],
|
|
257
393
|
)
|
|
258
394
|
|
|
259
395
|
upNextTemplate = template
|
|
260
396
|
|
|
261
|
-
interfaceController.
|
|
397
|
+
interfaceController.safePush(template, animated: true)
|
|
262
398
|
}
|
|
263
399
|
|
|
264
400
|
private func createUpNextSection(tracks: [Track], player: TrackPlayer) -> CPListSection {
|
|
265
|
-
|
|
401
|
+
// Clamp to CarPlay's list limit (createSections does the same for browse
|
|
402
|
+
// lists). Taking the prefix keeps item positions aligned with queue indices.
|
|
403
|
+
let maxItems = CPListTemplate.maximumItemCount
|
|
404
|
+
if tracks.count > maxItems {
|
|
405
|
+
logger.info("Up Next queue has \(tracks.count) tracks, clamping to CarPlay's limit of \(maxItems)")
|
|
406
|
+
}
|
|
407
|
+
let items = tracks.prefix(maxItems).enumerated().map { index, track -> CPListItem in
|
|
266
408
|
listItemFactory(track) { [weak self] _, completion in
|
|
267
409
|
self?.logger.info("Skipping to track at index \(index): \(track.title)")
|
|
268
410
|
do {
|
|
@@ -297,6 +439,8 @@ private final class NowPlayingObserver: NSObject, CPNowPlayingTemplateObserver,
|
|
|
297
439
|
}
|
|
298
440
|
|
|
299
441
|
func nowPlayingTemplateAlbumArtistButtonTapped(_: CPNowPlayingTemplate) {
|
|
300
|
-
|
|
442
|
+
Task { @MainActor in
|
|
443
|
+
manager?.handleAlbumArtistButtonTapped()
|
|
444
|
+
}
|
|
301
445
|
}
|
|
302
446
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
|
|
4
|
+
// MARK: - ImageRowItem → Track Conversion
|
|
5
|
+
|
|
6
|
+
extension ImageRowItem {
|
|
7
|
+
/// Creates a minimal Track from an ImageRowItem for reuse with item selection and artwork loading.
|
|
8
|
+
/// A `src`-bearing item becomes a playable track (thumbnail tap plays it); otherwise the
|
|
9
|
+
/// track only navigates via `url`.
|
|
10
|
+
func toTrack() -> Track {
|
|
11
|
+
Track(
|
|
12
|
+
id: id, url: url, src: src, artwork: artwork.map { .first($0) },
|
|
13
|
+
artworkSource: artworkSource, request: request,
|
|
14
|
+
artworkCarPlayTinted: nil, title: title, subtitle: nil, artist: artist,
|
|
15
|
+
albumUrl: albumUrl, album: album, description: nil, genre: nil, duration: nil, style: nil,
|
|
16
|
+
childrenStyle: nil, favorited: nil, groupTitle: nil, live: live, imageRow: nil,
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -3,20 +3,25 @@
|
|
|
3
3
|
|
|
4
4
|
NS_ASSUME_NONNULL_BEGIN
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
@interface RNABAudioBrowser : NSObject
|
|
7
|
+
|
|
8
|
+
/// Return this from your AppDelegate's `application:handlerForIntent:` (iOS 14+
|
|
9
|
+
/// in-app handling). Vends the library's handler for supported intents —
|
|
10
|
+
/// `INPlayMediaIntent` (search / resume / play), `INUpdateMediaAffinityIntent`
|
|
11
|
+
/// (like / dislike the current track) and `INAddMediaIntent` (add the current
|
|
12
|
+
/// track to favorites) — or nil for unsupported intents. Register the ones you
|
|
13
|
+
/// want in `INIntentsSupported`.
|
|
8
14
|
///
|
|
9
|
-
/// Usage (add to your bridging header: #import <AudioBrowser/RNABAudioBrowser.h>):
|
|
10
15
|
/// @code
|
|
11
|
-
/// func application(_ application: UIApplication,
|
|
12
|
-
/// RNABAudioBrowser.
|
|
16
|
+
/// func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? {
|
|
17
|
+
/// RNABAudioBrowser.handler(for: intent)
|
|
13
18
|
/// }
|
|
14
19
|
/// @endcode
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
///
|
|
18
|
-
///
|
|
19
|
-
+ (
|
|
20
|
+
///
|
|
21
|
+
/// A handler must be returned — without one iOS falls back to
|
|
22
|
+
/// `UISIntentForwardingAction` and crashes in
|
|
23
|
+
/// `-[INHandleIntentForwardingActionResponse isSuccess]`.
|
|
24
|
+
+ (nullable id)handlerForIntent:(INIntent *)intent;
|
|
20
25
|
|
|
21
26
|
@end
|
|
22
27
|
|
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
@implementation RNABAudioBrowser
|
|
4
4
|
|
|
5
|
-
+ (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
fn(cls, sel, intent, completionHandler);
|
|
16
|
-
#pragma clang diagnostic pop
|
|
17
|
-
} else {
|
|
18
|
-
completionHandler([[INPlayMediaIntentResponse alloc] initWithCode:INPlayMediaIntentResponseCodeFailureRequiringAppLaunch userActivity:nil]);
|
|
5
|
+
+ (nullable id)handlerForIntent:(INIntent *)intent {
|
|
6
|
+
// The handlers are internal Swift classes exposed to the ObjC runtime via
|
|
7
|
+
// @objc(...); each conforms to the matching INIntentHandling protocol.
|
|
8
|
+
NSString *handlerClassName = nil;
|
|
9
|
+
if ([intent isKindOfClass:[INPlayMediaIntent class]]) {
|
|
10
|
+
handlerClassName = @"RNABMediaIntentHandler";
|
|
11
|
+
} else if ([intent isKindOfClass:[INUpdateMediaAffinityIntent class]]) {
|
|
12
|
+
handlerClassName = @"RNABMediaAffinityHandler";
|
|
13
|
+
} else if ([intent isKindOfClass:[INAddMediaIntent class]]) {
|
|
14
|
+
handlerClassName = @"RNABMediaAddHandler";
|
|
19
15
|
}
|
|
16
|
+
if (!handlerClassName) {
|
|
17
|
+
return nil;
|
|
18
|
+
}
|
|
19
|
+
Class cls = NSClassFromString(handlerClassName);
|
|
20
|
+
return cls ? [[cls alloc] init] : nil;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
@end
|