react-native-queue-player 1.2.0 → 2.0.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/QueuePlayer.podspec +14 -9
- package/README.md +3 -3
- package/android/consumer-rules.pro +1 -1
- package/android/src/main/cpp/airplay2_control.c +4 -4
- package/android/src/main/cpp/airplay2_control.h +4 -4
- package/android/src/main/cpp/airplay2_jni.cpp +3 -19
- package/android/src/main/cpp/airplay2_pair.c +7 -7
- package/android/src/main/cpp/airplay2_pair.h +2 -2
- package/android/src/main/cpp/airplay2_rtsp.c +8 -8
- package/android/src/main/cpp/airplay2_session.c +2 -2
- package/android/src/main/cpp/airplay_jni.cpp +8 -69
- package/android/src/main/java/com/margelo/nitro/queueplayer/AirPlayEngine.kt +7 -16
- package/android/src/main/java/com/margelo/nitro/queueplayer/CacheMimeTypes.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/CastManager.kt +2 -14
- package/android/src/main/java/com/margelo/nitro/queueplayer/CellularTransportMonitor.kt +77 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/CrossfadeEngine.kt +187 -52
- package/android/src/main/java/com/margelo/nitro/queueplayer/Equalizer.kt +27 -7
- package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerEngine.kt +33 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngine.kt +31 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/FFTProcessorTee.kt +45 -30
- package/android/src/main/java/com/margelo/nitro/queueplayer/FifoCacheEvictor.kt +111 -15
- package/android/src/main/java/com/margelo/nitro/queueplayer/GaplessEngine.kt +60 -33
- package/android/src/main/java/com/margelo/nitro/queueplayer/HeadlessJsMediaService.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/IEqualizerEngine.kt +3 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCache.kt +111 -29
- package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +78 -30
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaItemBuilder.kt +6 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaResponseCheck.kt +156 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaValidatingDataSource.kt +165 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/MimeCapturingDataSource.kt +18 -9
- package/android/src/main/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractor.kt +48 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/PitchCorrection.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackEngine.kt +71 -76
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackErrorMapping.kt +13 -5
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackModeStateMachine.kt +2 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackService.kt +68 -46
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackServiceCallback.kt +6 -5
- package/android/src/main/java/com/margelo/nitro/queueplayer/QueueMutationArithmetic.kt +5 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/QueueSkipArithmetic.kt +11 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessor.kt +26 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainData.kt +22 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainExtractor.kt +38 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainGain.kt +17 -13
- package/android/src/main/java/com/margelo/nitro/queueplayer/SuppliedReplayGain.kt +66 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/TrackPlayer.kt +985 -276
- package/android/src/main/java/com/margelo/nitro/queueplayer/Visualizer.kt +4 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastBackend.kt +4 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastSession.kt +5 -4
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2JNI.kt +0 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2Session.kt +4 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayBackend.kt +16 -9
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSync.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayRenderersFactory.kt +6 -14
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirplayJNI.kt +1 -13
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MulticastLockHolder.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastBackend.kt +3 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServer.kt +11 -35
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaServerHandle.kt +0 -5
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaTokenRegistry.kt +0 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitor.kt +32 -33
- package/android/src/test/java/androidx/media3/session/{MediaSessionControllerRequestTestSeam.kt → MediaSessionControllerRequestTestSupport.kt} +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/AvrcpMetadataTest.kt +12 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineFocusLossTest.kt +115 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineLifecycleTest.kt +45 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EngineEndSignalOrderTest.kt +70 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerEngineTest.kt +17 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +0 -6
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +17 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/FFTProcessorTeeTest.kt +15 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/FifoCacheEvictorTest.kt +135 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineLifecycleTest.kt +1 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineReplayGainTest.kt +36 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheTest.kt +84 -18
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterCancelTest.kt +85 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterTest.kt +112 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/MediaItemBuilderTest.kt +5 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/MediaResponseCheckTest.kt +163 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/MediaValidatingDataSourceTest.kt +189 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractorTest.kt +45 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/PitchAwareAudioProcessorChainTest.kt +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackSearchTest.kt +47 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackTest.kt +53 -29
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceLifecycleTest.kt +8 -8
- package/android/src/test/java/com/margelo/nitro/queueplayer/QueueSkipArithmeticTest.kt +33 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessorTest.kt +128 -5
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainExtractorTest.kt +209 -14
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainGainTest.kt +150 -10
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainMergeTest.kt +258 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/RobolectricServiceBindHelper.kt +2 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/SessionCommandForwardingPlayerTest.kt +2 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowDynamicsProcessingRejectingEnable.kt +19 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizer.kt +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizerRejectingBandWrites.kt +27 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/SuppliedReplayGainTest.kt +61 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAirPlayMetadataWiringTest.kt +4 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAudioFocusTest.kt +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastCommandRoutingTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastStateTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +122 -38
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLifecycleTest.kt +291 -27
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLookaheadConfigTest.kt +277 -38
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerMutationTest.kt +5 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerProgressThrottleTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueChangeTest.kt +85 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueTest.kt +11 -7
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerReadersTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipCapabilityTest.kt +90 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipTest.kt +8 -26
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerTransportTest.kt +3 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/VisualizerKtTest.kt +0 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/FakeRemotePlayer.kt +2 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitorTest.kt +173 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/ShadowConnectivityManagerRecordingRequests.kt +27 -0
- package/app.plugin.js +17 -1
- package/ios/AVPlayerItemQueueItemId.swift +26 -12
- package/ios/AVQueueBuilder.swift +120 -85
- package/ios/ArtworkLoader.swift +0 -7
- package/ios/ArtworkResolver.swift +22 -4
- package/ios/AssetReplayGainReader.swift +118 -0
- package/ios/AudioSession.swift +67 -16
- package/ios/AudioTapProvider.swift +284 -149
- package/ios/CarPlayBridge.swift +0 -12
- package/ios/CarPlayCoordinator.swift +18 -2
- package/ios/CarPlaySceneDelegate.swift +2 -2
- package/ios/Cast/AirPlayRouteState.swift +9 -8
- package/ios/Cast/Core/CastEventBridge.swift +66 -26
- package/ios/Cast/Core/CastNowPlayingController.swift +38 -16
- package/ios/Cast/Core/CastSession.swift +2 -2
- package/ios/Cast/Core/CastTransportRouter.swift +21 -9
- package/ios/Cast/Core/LocalMediaServer.swift +41 -52
- package/ios/Cast/Core/LocalNetworkPermissionProbe.swift +32 -11
- package/ios/Cast/Core/MediaServerHandle.swift +0 -4
- package/ios/Cast/Core/MediaTokenRegistry.swift +0 -6
- package/ios/CastManager.swift +1 -1
- package/ios/CrossfadeEngine.swift +672 -226
- package/ios/EQTap.swift +20 -17
- package/ios/Equalizer.swift +1 -1
- package/ios/FLACStreamInfo.swift +65 -0
- package/ios/GaplessEngine.swift +57 -30
- package/ios/InputGuards.swift +35 -5
- package/ios/LookaheadCache.swift +229 -58
- package/ios/LookaheadCachePrefetcher.swift +48 -36
- package/ios/MediaResponseCheck.swift +122 -0
- package/ios/MediaServer/MediaHTTPConnection.swift +691 -0
- package/ios/NetworkRecoveryPolicy.swift +32 -0
- package/ios/NowPlayingFormatExtractor.swift +25 -18
- package/ios/NowPlayingInfo.swift +84 -48
- package/ios/OutputRouteMonitor.swift +16 -3
- package/ios/PendingBrowseRequests.swift +1 -1
- package/ios/PlaceholderArtwork.swift +9 -5
- package/ios/PlaybackEngine.swift +165 -76
- package/ios/PlaybackErrorMapping.swift +3 -3
- package/ios/PlaybackModeStateMachine.swift +2 -2
- package/ios/PlaybackNetworkMonitor.swift +73 -0
- package/ios/PlayerStateDerivation.swift +6 -6
- package/ios/QueueMutationArithmetic.swift +25 -0
- package/ios/QueueSkipArithmetic.swift +5 -3
- package/ios/QueueWindowArithmetic.swift +152 -0
- package/ios/ReadThroughServer.swift +283 -0
- package/ios/RemoteCommands.swift +44 -4
- package/ios/ReplayGainData.swift +22 -3
- package/ios/ReplayGainExtractor.swift +70 -27
- package/ios/Siri/VoiceDonation.swift +14 -9
- package/ios/StreamingBitrateProbe.swift +22 -68
- package/ios/SuppliedReplayGain.swift +83 -0
- package/ios/Tests/AVQueueBuilderTests.swift +158 -221
- package/ios/Tests/ActiveItemEngineStub.swift +44 -0
- package/ios/Tests/AssetReplayGainReaderTests.swift +228 -0
- package/ios/Tests/AudioTapProviderDispatchTargetTests.swift +158 -0
- package/ios/Tests/AudioTapProviderReplayGainTests.swift +122 -10
- package/ios/Tests/BitrateReresolveBudgetTests.swift +71 -0
- package/ios/Tests/CastMediaItemTranslationTests.swift +72 -0
- package/ios/Tests/CastNowPlayingControllerTests.swift +1 -1
- package/ios/Tests/CrossfadeAdvanceWithoutFadeTests.swift +120 -0
- package/ios/Tests/CrossfadeEngineIncomingMixTests.swift +122 -0
- package/ios/Tests/CrossfadeEngineTests.swift +164 -0
- package/ios/Tests/CrossfadeMixReapplyTests.swift +66 -0
- package/ios/Tests/CrossfadePlaybackIntentTests.swift +81 -0
- package/ios/Tests/EngineSwapTests.swift +91 -0
- package/ios/Tests/EqualizerAudioMixProviderTests.swift +46 -0
- package/ios/Tests/EqualizerHybridTests.swift +5 -2
- package/ios/Tests/FLACStreamInfoTests.swift +88 -0
- package/ios/Tests/GaplessEngineLifecycleTests.swift +4 -4
- package/ios/Tests/InputGuardsTests.swift +41 -0
- package/ios/Tests/InterruptionIntentTests.swift +77 -0
- package/ios/Tests/LookaheadCacheCellularAccessTests.swift +185 -0
- package/ios/Tests/LookaheadCachePrefetcherTests.swift +53 -30
- package/ios/Tests/LookaheadCacheRuntimeConfigTests.swift +160 -1
- package/ios/Tests/LookaheadCacheTests.swift +44 -18
- package/ios/Tests/MediaHTTPConnectionTests.swift +79 -0
- package/ios/Tests/MediaResponseCheckTests.swift +128 -0
- package/ios/Tests/MutationDeferralTests.swift +220 -0
- package/ios/Tests/NowPlayingInfoTests.swift +86 -99
- package/ios/Tests/NowPlayingSnapshotTests.swift +127 -0
- package/ios/Tests/OriginRestartStitcherTests.swift +60 -0
- package/ios/Tests/PlaybackNetworkMonitorTests.swift +95 -0
- package/ios/Tests/PlayerFixtures.swift +48 -0
- package/ios/Tests/PlayerStateDerivationTests.swift +10 -10
- package/ios/Tests/QueueMutationGenerationTests.swift +141 -0
- package/ios/Tests/QueueRebuildPrefixTests.swift +317 -0
- package/ios/Tests/QueueStateTests.swift +3 -1
- package/ios/Tests/QueueWindowArithmeticTests.swift +56 -0
- package/ios/Tests/QueueWindowSliceTests.swift +162 -0
- package/ios/Tests/ReadThroughRoutingLifecycleTests.swift +63 -0
- package/ios/Tests/ReadThroughServerTests.swift +345 -0
- package/ios/Tests/RemoteCommandsTests.swift +28 -0
- package/ios/Tests/ReplayGainExtractorTests.swift +216 -6
- package/ios/Tests/ReplayGainMergeTests.swift +230 -0
- package/ios/Tests/RetryRecoveryTests.swift +418 -0
- package/ios/Tests/SkipCapabilityTests.swift +233 -8
- package/ios/Tests/SkipIndexTests.swift +32 -2
- package/ios/Tests/SleepTimerPauseIntentTests.swift +43 -0
- package/ios/Tests/StallRecoveryTests.swift +97 -0
- package/ios/Tests/StreamingBitrateProbeTests.swift +17 -20
- package/ios/Tests/TopUpWindowGateTests.swift +441 -0
- package/ios/Tests/TrackPlayer+TestHops.swift +14 -0
- package/ios/Tests/TrackPlayerCallOrderTests.swift +93 -0
- package/ios/Tests/TrackPlayerConfigureTeardownTests.swift +86 -0
- package/ios/Tests/TrackPlayerEndVerdictTests.swift +206 -0
- package/ios/Tests/TrackPlayerSeekTests.swift +137 -0
- package/ios/Tests/TrackPlayerThreadingTests.swift +127 -0
- package/ios/Tests/TrackSourceClassifierTests.swift +33 -7
- package/ios/Tests/VoiceVocabularyOptInTests.swift +38 -0
- package/ios/TrackPlayer+Automotive.swift +101 -0
- package/ios/TrackPlayer+Cache.swift +232 -0
- package/ios/TrackPlayer+Config.swift +291 -0
- package/ios/TrackPlayer+EngineDelegate.swift +209 -0
- package/ios/TrackPlayer+EventsAPI.swift +111 -0
- package/ios/TrackPlayer+EventsDispatch.swift +1042 -0
- package/ios/TrackPlayer+EventsWiring.swift +173 -0
- package/ios/TrackPlayer+Lifecycle.swift +982 -0
- package/ios/TrackPlayer+NowPlayingFormat.swift +258 -0
- package/ios/TrackPlayer+Queue.swift +951 -0
- package/ios/TrackPlayer+Recovery.swift +213 -0
- package/ios/TrackPlayer+Skip.swift +465 -0
- package/ios/TrackPlayer+SleepTimer.swift +175 -0
- package/ios/TrackPlayer+State.swift +108 -0
- package/ios/TrackPlayer+Threading.swift +135 -0
- package/ios/TrackPlayer+Transport.swift +272 -0
- package/ios/TrackPlayer+Window.swift +227 -0
- package/ios/TrackPlayer.swift +331 -4619
- package/ios/Visualizer.swift +6 -5
- package/ios/tests-harness/Podfile +1 -1
- package/ios/tests-harness/TestHost.xcodeproj/project.pbxproj +19 -11
- package/ios/tests-harness/scripts/seed-xcodeproj.rb +2 -2
- package/lib/module/hooks/useActiveTrack.js +29 -22
- package/lib/module/hooks/useActiveTrack.js.map +1 -1
- package/lib/module/hooks/useCast.js +8 -26
- package/lib/module/hooks/useCast.js.map +1 -1
- package/lib/module/hooks/useEqualizer.js +19 -12
- package/lib/module/hooks/useEqualizer.js.map +1 -1
- package/lib/module/hooks/useLookaheadCache.js +3 -7
- package/lib/module/hooks/useLookaheadCache.js.map +1 -1
- package/lib/module/hooks/useQueue.js +66 -19
- package/lib/module/hooks/useQueue.js.map +1 -1
- package/lib/module/index.js +6 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/queueDelta.js +41 -0
- package/lib/module/queueDelta.js.map +1 -0
- package/lib/module/types.js +28 -5
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/TrackPlayer.nitro.d.ts +53 -28
- package/lib/typescript/TrackPlayer.nitro.d.ts.map +1 -1
- package/lib/typescript/hooks/useActiveTrack.d.ts +5 -7
- package/lib/typescript/hooks/useActiveTrack.d.ts.map +1 -1
- package/lib/typescript/hooks/useCast.d.ts +6 -1
- package/lib/typescript/hooks/useCast.d.ts.map +1 -1
- package/lib/typescript/hooks/useEqualizer.d.ts +2 -1
- package/lib/typescript/hooks/useEqualizer.d.ts.map +1 -1
- package/lib/typescript/hooks/useLookaheadCache.d.ts.map +1 -1
- package/lib/typescript/hooks/useQueue.d.ts +4 -4
- package/lib/typescript/hooks/useQueue.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/queueDelta.d.ts +10 -0
- package/lib/typescript/queueDelta.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +168 -12
- package/lib/typescript/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_QueueChangeDelta_double_QueueChangeReason.hpp +85 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +45 -19
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +3 -3
- package/nitrogen/generated/android/c++/JLookaheadCacheConfig.hpp +8 -4
- package/nitrogen/generated/android/c++/JPlayerConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JQueueChangeDelta.hpp +128 -0
- package/nitrogen/generated/android/c++/JTrackItem.hpp +19 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_BrowseItem______std__string.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______MediaSearchRequest.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______std__string.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_AudioRoute.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_BufferState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CacheStatus.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastDiscoveryState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastLocalNetworkPermissionEvent.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastRoute.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastSessionDiedEvent.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlaybackError.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerProgress.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerState_StateChangeReason.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/{Func_void_std__vector_TrackItem__double_QueueChangeReason.kt → Func_void_QueueChangeDelta_double_QueueChangeReason.kt} +14 -16
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_ServiceReadyReason.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SkipCapability.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SleepTimerState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerErrorReason.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerFrame.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_bool.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_double_double.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_TrackItem__double_TrackChangeReason_std__optional_double_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_std__variant_nitro__NullType__NowPlayingFormat__.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_CastReceiver_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_EqualizerBand_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridCastManagerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridEqualizerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridTrackPlayerSpec.kt +6 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridVisualizerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/LookaheadCacheConfig.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/PlayerConfig.kt +7 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/QueueChangeDelta.kt +86 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/TrackItem.kt +24 -4
- package/nitrogen/generated/android/queueplayerOnLoad.cpp +2 -2
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.cpp +16 -16
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.hpp +80 -65
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +6 -3
- package/nitrogen/generated/ios/swift/Func_void_CacheStatus.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_QueueChangeDelta_double_QueueChangeReason.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +3 -3
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +32 -24
- package/nitrogen/generated/ios/swift/LookaheadCacheConfig.swift +20 -2
- package/nitrogen/generated/ios/swift/PlayerConfig.swift +19 -1
- package/nitrogen/generated/ios/swift/QueueChangeDelta.swift +82 -0
- package/nitrogen/generated/ios/swift/TrackItem.swift +73 -1
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +6 -3
- package/nitrogen/generated/shared/c++/LookaheadCacheConfig.hpp +7 -3
- package/nitrogen/generated/shared/c++/PlayerConfig.hpp +5 -1
- package/nitrogen/generated/shared/c++/QueueChangeDelta.hpp +113 -0
- package/nitrogen/generated/shared/c++/TrackItem.hpp +18 -2
- package/package.json +8 -8
- package/src/TrackPlayer.nitro.ts +53 -27
- package/src/hooks/useActiveTrack.ts +29 -22
- package/src/hooks/useCast.ts +14 -15
- package/src/hooks/useEqualizer.ts +19 -12
- package/src/hooks/useLookaheadCache.ts +3 -7
- package/src/hooks/useQueue.ts +66 -17
- package/src/index.ts +13 -3
- package/src/queueDelta.ts +41 -0
- package/src/types.ts +169 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/PendingIntentBuffer.kt +0 -82
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServerLifecycle.kt +0 -15
- package/android/src/test/java/com/margelo/nitro/queueplayer/PendingIntentBufferTest.kt +0 -192
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackEngineInterfaceTest.kt +0 -135
- package/android/src/test/java/com/margelo/nitro/queueplayer/SmokeTest.kt +0 -27
- package/ios/Cast/Core/LocalAddressMonitor.swift +0 -110
- package/ios/Cast/Core/MediaHTTPConnection.swift +0 -349
- package/ios/MetadataReader.swift +0 -555
- package/ios/Tests/CrossfadeEngineStubTests.swift +0 -43
- package/ios/Tests/MetadataReaderTests.swift +0 -603
- package/ios/Tests/PlaybackEngineProtocolTests.swift +0 -92
- package/ios/Tests/VoiceDonationTests.swift +0 -26
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double_QueueChangeReason.hpp +0 -101
- package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__double_QueueChangeReason.swift +0 -46
- /package/ios/{Cast/Core → MediaServer}/MimeTypes.swift +0 -0
package/ios/Visualizer.swift
CHANGED
|
@@ -14,6 +14,7 @@ import NitroModules
|
|
|
14
14
|
/// hops to main and builds a Nitro ArrayBuffer.
|
|
15
15
|
final class Visualizer: HybridVisualizerSpec {
|
|
16
16
|
|
|
17
|
+
private static let currentLock = NSLock()
|
|
17
18
|
/// The most recently constructed Visualizer instance. Held for
|
|
18
19
|
/// JS-reload teardown parity with Android — a fresh construction
|
|
19
20
|
/// tears the prior instance's subscriptions + consumer
|
|
@@ -23,7 +24,6 @@ final class Visualizer: HybridVisualizerSpec {
|
|
|
23
24
|
/// Acquire `currentLock` when reading or writing [current] —
|
|
24
25
|
/// `init()` runs on the JS bridge while a prior instance may be
|
|
25
26
|
/// mid-dispatch on the render thread.
|
|
26
|
-
private static let currentLock = NSLock()
|
|
27
27
|
private static var _current: Visualizer?
|
|
28
28
|
static var current: Visualizer? {
|
|
29
29
|
get {
|
|
@@ -52,8 +52,9 @@ final class Visualizer: HybridVisualizerSpec {
|
|
|
52
52
|
let disposed: DisposedFlag
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/// Thread-safe
|
|
56
|
-
///
|
|
55
|
+
/// Thread-safe "disposed" flag shared by a subscription and the emit blocks
|
|
56
|
+
/// it has already enqueued onto the main queue. `mark()` sets it; nothing
|
|
57
|
+
/// clears it.
|
|
57
58
|
private final class DisposedFlag {
|
|
58
59
|
private let lock = NSLock()
|
|
59
60
|
private var value = false
|
|
@@ -65,12 +66,12 @@ final class Visualizer: HybridVisualizerSpec {
|
|
|
65
66
|
private var subscriptions: [Subscription] = []
|
|
66
67
|
private var nextId: Int = 1
|
|
67
68
|
|
|
69
|
+
private let assetLock = NSLock()
|
|
68
70
|
/// Snapshot of the active asset — set from the audio-tap provider's
|
|
69
71
|
/// `audioMix(for:)` path so `subscribe` can report `hls-source` for
|
|
70
72
|
/// HLS streams without poking the TrackPlayer Hybrid. Held under its
|
|
71
73
|
/// own lock so the render-thread-hot `subsLock` covers only the
|
|
72
74
|
/// subscription array; main-thread asset writes never block render.
|
|
73
|
-
private let assetLock = NSLock()
|
|
74
75
|
private var activeAsset: AVAsset?
|
|
75
76
|
|
|
76
77
|
private let provider: AudioTapProvider
|
|
@@ -176,7 +177,7 @@ final class Visualizer: HybridVisualizerSpec {
|
|
|
176
177
|
// throttle (default 16ms) caps the emit rate, which puts a
|
|
177
178
|
// natural ceiling on main-queue accumulation.
|
|
178
179
|
DispatchQueue.main.async {
|
|
179
|
-
// Drop frames queued before dispose — the disposer sets this
|
|
180
|
+
// Drop frames queued before dispose — the disposer sets this flag
|
|
180
181
|
// before removing the subscription, so anything already on the main
|
|
181
182
|
// queue short-circuits here rather than firing onFrame post-dispose.
|
|
182
183
|
if disposed.isSet { return }
|
|
@@ -208,23 +208,29 @@
|
|
|
208
208
|
);
|
|
209
209
|
inputPaths = (
|
|
210
210
|
"${PODS_ROOT}/Target Support Files/Pods-TestHost/Pods-TestHost-resources.sh",
|
|
211
|
+
"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Core_Privacy.bundle",
|
|
212
|
+
"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Full_Privacy.bundle",
|
|
211
213
|
"${PODS_CONFIGURATION_BUILD_DIR}/QueuePlayer/QueuePlayer.bundle",
|
|
212
214
|
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
|
|
213
215
|
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
|
|
214
|
-
"${
|
|
215
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
216
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
217
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
218
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
219
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
220
|
-
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.
|
|
216
|
+
"${PODS_CONFIGURATION_BUILD_DIR}/React-timing/React-timing_privacy.bundle",
|
|
217
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastCoreResources.bundle",
|
|
218
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastUIResources.bundle",
|
|
219
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastOptionalUIResources.bundle",
|
|
220
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/MaterialDialogs.bundle",
|
|
221
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansBold.bundle",
|
|
222
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansMedium.bundle",
|
|
223
|
+
"${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansRegular.bundle",
|
|
221
224
|
"${PODS_CONFIGURATION_BUILD_DIR}/google-cast-sdk/GoogleCast.bundle",
|
|
222
225
|
);
|
|
223
226
|
name = "[CP] Copy Pods Resources";
|
|
224
227
|
outputPaths = (
|
|
228
|
+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Core_Privacy.bundle",
|
|
229
|
+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Full_Privacy.bundle",
|
|
225
230
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QueuePlayer.bundle",
|
|
226
231
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
|
|
227
232
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
|
|
233
|
+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-timing_privacy.bundle",
|
|
228
234
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastCoreResources.bundle",
|
|
229
235
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastUIResources.bundle",
|
|
230
236
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastOptionalUIResources.bundle",
|
|
@@ -264,7 +270,7 @@
|
|
|
264
270
|
CURRENT_PROJECT_VERSION = 1;
|
|
265
271
|
GENERATE_INFOPLIST_FILE = NO;
|
|
266
272
|
INFOPLIST_FILE = TestHost/Info.plist;
|
|
267
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
273
|
+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
|
268
274
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
269
275
|
MARKETING_VERSION = 1.0;
|
|
270
276
|
PRODUCT_BUNDLE_IDENTIFIER = org.ghenry22.RNQueuePlayer.TestHost;
|
|
@@ -327,7 +333,7 @@
|
|
|
327
333
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
328
334
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
329
335
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
330
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
336
|
+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
|
331
337
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
|
332
338
|
MTL_FAST_MATH = YES;
|
|
333
339
|
ONLY_ACTIVE_ARCH = YES;
|
|
@@ -339,6 +345,7 @@
|
|
|
339
345
|
"$(inherited)",
|
|
340
346
|
"-DRCT_REMOVE_LEGACY_ARCH=1",
|
|
341
347
|
);
|
|
348
|
+
PODFILE_DIR = "$(SRCROOT)";
|
|
342
349
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
343
350
|
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
|
|
344
351
|
SDKROOT = iphoneos;
|
|
@@ -398,7 +405,7 @@
|
|
|
398
405
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
399
406
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
400
407
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
401
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
408
|
+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
|
402
409
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
|
403
410
|
MTL_FAST_MATH = YES;
|
|
404
411
|
ONLY_ACTIVE_ARCH = YES;
|
|
@@ -410,6 +417,7 @@
|
|
|
410
417
|
"$(inherited)",
|
|
411
418
|
"-DRCT_REMOVE_LEGACY_ARCH=1",
|
|
412
419
|
);
|
|
420
|
+
PODFILE_DIR = "$(SRCROOT)";
|
|
413
421
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
414
422
|
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
|
|
415
423
|
SDKROOT = iphoneos;
|
|
@@ -433,7 +441,7 @@
|
|
|
433
441
|
CURRENT_PROJECT_VERSION = 1;
|
|
434
442
|
GENERATE_INFOPLIST_FILE = NO;
|
|
435
443
|
INFOPLIST_FILE = TestHost/Info.plist;
|
|
436
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
444
|
+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
|
437
445
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
438
446
|
MARKETING_VERSION = 1.0;
|
|
439
447
|
PRODUCT_BUNDLE_IDENTIFIER = org.ghenry22.RNQueuePlayer.TestHost;
|
|
@@ -41,7 +41,7 @@ end
|
|
|
41
41
|
|
|
42
42
|
project = Xcodeproj::Project.new(PROJECT_PATH)
|
|
43
43
|
|
|
44
|
-
target = project.new_target(:application, 'TestHost', :ios, '
|
|
44
|
+
target = project.new_target(:application, 'TestHost', :ios, '16.0', nil, :swift)
|
|
45
45
|
|
|
46
46
|
host_group = project.new_group('TestHost', 'TestHost')
|
|
47
47
|
app_ref = host_group.new_reference('App.swift')
|
|
@@ -64,7 +64,7 @@ project.build_configurations.each do |config|
|
|
|
64
64
|
'GCC_C_LANGUAGE_STANDARD' => 'gnu17',
|
|
65
65
|
'GCC_DYNAMIC_NO_PIC' => 'NO',
|
|
66
66
|
'GCC_NO_COMMON_BLOCKS' => 'YES',
|
|
67
|
-
'IPHONEOS_DEPLOYMENT_TARGET' => '
|
|
67
|
+
'IPHONEOS_DEPLOYMENT_TARGET' => '16.0',
|
|
68
68
|
'MTL_FAST_MATH' => 'YES',
|
|
69
69
|
'ONLY_ACTIVE_ARCH' => 'YES',
|
|
70
70
|
'SDKROOT' => 'iphoneos',
|
|
@@ -11,39 +11,46 @@ const INITIAL = {
|
|
|
11
11
|
/**
|
|
12
12
|
* Subscribes to native `onTrackChange` updates.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `(track, index, reason)` triple. Consumers needing an atomic
|
|
20
|
-
* snapshot should wait for the first listener fire.
|
|
14
|
+
* Renders empty for the first frame, then fills in: the seed reads
|
|
15
|
+
* `getQueue()`, which resolves asynchronously, and pairs it with a separately
|
|
16
|
+
* read index — so it can briefly observe a new list against an old index. Any
|
|
17
|
+
* `onTrackChange` that arrives first wins and the seed is dropped, since the
|
|
18
|
+
* event delivers a consistent `(track, index, reason)` triple.
|
|
21
19
|
*/
|
|
22
20
|
export function useActiveTrack() {
|
|
23
|
-
const [snapshot, setSnapshot] = useState(
|
|
24
|
-
try {
|
|
25
|
-
const player = getTrackPlayer();
|
|
26
|
-
const queue = player.getQueue();
|
|
27
|
-
const index = player.getCurrentTrackIndex();
|
|
28
|
-
return {
|
|
29
|
-
track: index >= 0 && index < queue.length ? queue[index] : undefined,
|
|
30
|
-
index,
|
|
31
|
-
reason: 'queue-replaced'
|
|
32
|
-
};
|
|
33
|
-
} catch {
|
|
34
|
-
return INITIAL;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
21
|
+
const [snapshot, setSnapshot] = useState(INITIAL);
|
|
37
22
|
useEffect(() => {
|
|
38
23
|
const player = getTrackPlayer();
|
|
24
|
+
let seeded = false;
|
|
25
|
+
// A seed still in flight when this effect is cleaned up (a StrictMode
|
|
26
|
+
// remount, an unmount) must not land on a later mount's state.
|
|
27
|
+
let disposed = false;
|
|
28
|
+
void (async () => {
|
|
29
|
+
try {
|
|
30
|
+
const queue = await player.getQueue();
|
|
31
|
+
const index = player.getCurrentTrackIndex();
|
|
32
|
+
if (disposed || seeded) return;
|
|
33
|
+
setSnapshot({
|
|
34
|
+
track: index >= 0 && index < queue.length ? queue[index] : undefined,
|
|
35
|
+
index,
|
|
36
|
+
reason: 'queue-replaced'
|
|
37
|
+
});
|
|
38
|
+
} catch {
|
|
39
|
+
// Player not configured yet; the first event seeds instead.
|
|
40
|
+
}
|
|
41
|
+
})();
|
|
39
42
|
const dispose = player.onTrackChange((track, index, reason) => {
|
|
43
|
+
seeded = true;
|
|
40
44
|
setSnapshot({
|
|
41
45
|
track,
|
|
42
46
|
index,
|
|
43
47
|
reason
|
|
44
48
|
});
|
|
45
49
|
});
|
|
46
|
-
return
|
|
50
|
+
return () => {
|
|
51
|
+
disposed = true;
|
|
52
|
+
dispose();
|
|
53
|
+
};
|
|
47
54
|
}, []);
|
|
48
55
|
return snapshot;
|
|
49
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","track","undefined","index","reason","useActiveTrack","snapshot","setSnapshot","player","queue","getQueue","getCurrentTrackIndex","length","dispose","onTrackChange"],"sourceRoot":"../../../src","sources":["hooks/useActiveTrack.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,cAAc,QAAQ,eAAY;AAW3C,MAAMC,OAA4B,GAAG;EACnCC,KAAK,EAAEC,SAAS;EAChBC,KAAK,EAAE,CAAC,CAAC;EACTC,MAAM,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA
|
|
1
|
+
{"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","track","undefined","index","reason","useActiveTrack","snapshot","setSnapshot","player","seeded","disposed","queue","getQueue","getCurrentTrackIndex","length","dispose","onTrackChange"],"sourceRoot":"../../../src","sources":["hooks/useActiveTrack.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,cAAc,QAAQ,eAAY;AAW3C,MAAMC,OAA4B,GAAG;EACnCC,KAAK,EAAEC,SAAS;EAChBC,KAAK,EAAE,CAAC,CAAC;EACTC,MAAM,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAAA,EAAwB;EACpD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGT,QAAQ,CAAsBE,OAAO,CAAC;EAEtEH,SAAS,CAAC,MAAM;IACd,MAAMW,MAAM,GAAGT,cAAc,CAAC,CAAC;IAC/B,IAAIU,MAAM,GAAG,KAAK;IAClB;IACA;IACA,IAAIC,QAAQ,GAAG,KAAK;IACpB,KAAK,CAAC,YAAY;MAChB,IAAI;QACF,MAAMC,KAAK,GAAG,MAAMH,MAAM,CAACI,QAAQ,CAAC,CAAC;QACrC,MAAMT,KAAK,GAAGK,MAAM,CAACK,oBAAoB,CAAC,CAAC;QAC3C,IAAIH,QAAQ,IAAID,MAAM,EAAE;QACxBF,WAAW,CAAC;UACVN,KAAK,EAAEE,KAAK,IAAI,CAAC,IAAIA,KAAK,GAAGQ,KAAK,CAACG,MAAM,GAAGH,KAAK,CAACR,KAAK,CAAC,GAAGD,SAAS;UACpEC,KAAK;UACLC,MAAM,EAAE;QACV,CAAC,CAAC;MACJ,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ,CAAC,EAAE,CAAC;IACJ,MAAMW,OAAO,GAAGP,MAAM,CAACQ,aAAa,CAAC,CAACf,KAAK,EAAEE,KAAK,EAAEC,MAAM,KAAK;MAC7DK,MAAM,GAAG,IAAI;MACbF,WAAW,CAAC;QAAEN,KAAK;QAAEE,KAAK;QAAEC;MAAO,CAAC,CAAC;IACvC,CAAC,CAAC;IACF,OAAO,MAAM;MACXM,QAAQ,GAAG,IAAI;MACfK,OAAO,CAAC,CAAC;IACX,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOT,QAAQ;AACjB","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
-
import { addDiscoveryStateListener, addLocalNetworkPermissionListener, addReceiversListener, addRouteListener, addSessionDiedListener, getCurrentRoute, getReceivers, getSupportedProtocols, isCastAvailable, isDiscovering, localRoute } from "../cast/index.js";
|
|
4
|
+
import { addDiscoveryStateListener, addLocalNetworkPermissionListener, addReceiversListener, addRouteListener, addSessionDiedListener, getCurrentRoute, getLocalNetworkPermissionState, getReceivers, getSupportedProtocols, isCastAvailable, isDiscovering, localRoute } from "../cast/index.js";
|
|
5
5
|
const INITIAL = {
|
|
6
6
|
supportedProtocols: [],
|
|
7
7
|
isAvailable: false,
|
|
@@ -33,7 +33,7 @@ export function useCast() {
|
|
|
33
33
|
route: getCurrentRoute(),
|
|
34
34
|
isDiscovering: isDiscovering(),
|
|
35
35
|
lastSessionDied: null,
|
|
36
|
-
permission:
|
|
36
|
+
permission: getLocalNetworkPermissionState()
|
|
37
37
|
};
|
|
38
38
|
} catch {
|
|
39
39
|
return INITIAL;
|
|
@@ -42,39 +42,25 @@ export function useCast() {
|
|
|
42
42
|
useEffect(() => {
|
|
43
43
|
if (!isCastAvailable()) return;
|
|
44
44
|
|
|
45
|
-
// Each `addXxxListener`
|
|
46
|
-
// subscribe
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
let firstDiscovery = true;
|
|
52
|
-
let firstPermission = true;
|
|
45
|
+
// Each `addXxxListener` replays the current value synchronously on
|
|
46
|
+
// subscribe, and every delivery is applied: a replay that equals the
|
|
47
|
+
// `useState` seed costs one batched render, while a replay that differs
|
|
48
|
+
// is a change that landed between the render and this effect — dropping
|
|
49
|
+
// it would leave the snapshot on the stale seed (on Android the
|
|
50
|
+
// permission replay is the only delivery there ever is).
|
|
53
51
|
const routeSub = addRouteListener(route => {
|
|
54
|
-
if (firstRoute) {
|
|
55
|
-
firstRoute = false;
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
52
|
setSnapshot(prev => ({
|
|
59
53
|
...prev,
|
|
60
54
|
route
|
|
61
55
|
}));
|
|
62
56
|
});
|
|
63
57
|
const receiversSub = addReceiversListener(receivers => {
|
|
64
|
-
if (firstReceivers) {
|
|
65
|
-
firstReceivers = false;
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
58
|
setSnapshot(prev => ({
|
|
69
59
|
...prev,
|
|
70
60
|
receivers
|
|
71
61
|
}));
|
|
72
62
|
});
|
|
73
63
|
const discoverySub = addDiscoveryStateListener(state => {
|
|
74
|
-
if (firstDiscovery) {
|
|
75
|
-
firstDiscovery = false;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
64
|
setSnapshot(prev => ({
|
|
79
65
|
...prev,
|
|
80
66
|
isDiscovering: state.isDiscovering
|
|
@@ -85,10 +71,6 @@ export function useCast() {
|
|
|
85
71
|
lastSessionDied: event
|
|
86
72
|
})));
|
|
87
73
|
const permissionSub = addLocalNetworkPermissionListener(event => {
|
|
88
|
-
if (firstPermission) {
|
|
89
|
-
firstPermission = false;
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
74
|
setSnapshot(prev => ({
|
|
93
75
|
...prev,
|
|
94
76
|
permission: event.state
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useState","addDiscoveryStateListener","addLocalNetworkPermissionListener","addReceiversListener","addRouteListener","addSessionDiedListener","getCurrentRoute","getReceivers","getSupportedProtocols","isCastAvailable","isDiscovering","localRoute","INITIAL","supportedProtocols","isAvailable","receivers","route","lastSessionDied","permission","useCast","snapshot","setSnapshot","protocols","length","
|
|
1
|
+
{"version":3,"names":["useEffect","useState","addDiscoveryStateListener","addLocalNetworkPermissionListener","addReceiversListener","addRouteListener","addSessionDiedListener","getCurrentRoute","getLocalNetworkPermissionState","getReceivers","getSupportedProtocols","isCastAvailable","isDiscovering","localRoute","INITIAL","supportedProtocols","isAvailable","receivers","route","lastSessionDied","permission","useCast","snapshot","setSnapshot","protocols","length","routeSub","prev","receiversSub","discoverySub","state","deathSub","event","permissionSub","remove"],"sourceRoot":"../../../src","sources":["hooks/useCast.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SACEC,yBAAyB,EACzBC,iCAAiC,EACjCC,oBAAoB,EACpBC,gBAAgB,EAChBC,sBAAsB,EACtBC,eAAe,EACfC,8BAA8B,EAC9BC,YAAY,EACZC,qBAAqB,EACrBC,eAAe,EACfC,aAAa,EACbC,UAAU,QAML,kBAAS;AA2BhB,MAAMC,OAAqB,GAAG;EAC5BC,kBAAkB,EAAE,EAAE;EACtBC,WAAW,EAAE,KAAK;EAClBC,SAAS,EAAE,EAAE;EACbC,KAAK,EAAEL,UAAU,CAAC,CAAC;EACnBD,aAAa,EAAE,KAAK;EACpBO,eAAe,EAAE,IAAI;EACrBC,UAAU,EAAE;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAOA,CAAA,EAAiB;EACtC,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGtB,QAAQ,CAAe,MAAM;IAC3D,IAAI;MACF,MAAMuB,SAAS,GAAGd,qBAAqB,CAAC,CAAC;MACzC,OAAO;QACLK,kBAAkB,EAAES,SAAS;QAC7BR,WAAW,EAAEQ,SAAS,CAACC,MAAM,GAAG,CAAC;QACjCR,SAAS,EAAER,YAAY,CAAC,CAAC;QACzBS,KAAK,EAAEX,eAAe,CAAC,CAAC;QACxBK,aAAa,EAAEA,aAAa,CAAC,CAAC;QAC9BO,eAAe,EAAE,IAAI;QACrBC,UAAU,EAAEZ,8BAA8B,CAAC;MAC7C,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAOM,OAAO;IAChB;EACF,CAAC,CAAC;EAEFd,SAAS,CAAC,MAAM;IACd,IAAI,CAACW,eAAe,CAAC,CAAC,EAAE;;IAExB;IACA;IACA;IACA;IACA;IACA;IACA,MAAMe,QAAQ,GAAGrB,gBAAgB,CAAEa,KAAK,IAAK;MAC3CK,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAET;MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,MAAMU,YAAY,GAAGxB,oBAAoB,CAAEa,SAAS,IAAK;MACvDM,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEV;MAAU,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;IACF,MAAMY,YAAY,GAAG3B,yBAAyB,CAAE4B,KAAK,IAAK;MACxDP,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEf,aAAa,EAAEkB,KAAK,CAAClB;MAAc,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC;IACF,MAAMmB,QAAQ,GAAGzB,sBAAsB,CAAE0B,KAAK,IAC5CT,WAAW,CAAEI,IAAI,KAAM;MAAE,GAAGA,IAAI;MAAER,eAAe,EAAEa;IAAM,CAAC,CAAC,CAC7D,CAAC;IACD,MAAMC,aAAa,GAAG9B,iCAAiC,CAAE6B,KAAK,IAAK;MACjET,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEP,UAAU,EAAEY,KAAK,CAACF;MAAM,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,OAAO,MAAM;MACXJ,QAAQ,CAACQ,MAAM,CAAC,CAAC;MACjBN,YAAY,CAACM,MAAM,CAAC,CAAC;MACrBL,YAAY,CAACK,MAAM,CAAC,CAAC;MACrBH,QAAQ,CAACG,MAAM,CAAC,CAAC;MACjBD,aAAa,CAACC,MAAM,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOZ,QAAQ;AACjB","ignoreList":[]}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { useCallback, useEffect, useState } from 'react';
|
|
4
4
|
import { getEqualizer } from "../clients.js";
|
|
5
5
|
/**
|
|
6
|
-
* Subscribes to Equalizer band-change
|
|
6
|
+
* Subscribes to Equalizer band-change and enabled-change events and
|
|
7
|
+
* exposes imperative setters.
|
|
7
8
|
* Initial state is pulled synchronously on mount so consumers don't flash
|
|
8
9
|
* empty bands.
|
|
9
10
|
*/
|
|
@@ -31,20 +32,27 @@ export function useEqualizer() {
|
|
|
31
32
|
});
|
|
32
33
|
useEffect(() => {
|
|
33
34
|
const eq = getEqualizer();
|
|
34
|
-
const
|
|
35
|
+
const disposeBands = eq.onBandChange(updated => {
|
|
35
36
|
setBands(updated);
|
|
36
37
|
});
|
|
37
|
-
|
|
38
|
+
const disposeEnabled = eq.onEnabledChange(next => {
|
|
39
|
+
setEnabledState(next);
|
|
40
|
+
});
|
|
41
|
+
return () => {
|
|
42
|
+
disposeBands();
|
|
43
|
+
disposeEnabled();
|
|
44
|
+
};
|
|
38
45
|
}, []);
|
|
39
46
|
const setEnabled = useCallback(async next => {
|
|
40
47
|
const eq = getEqualizer();
|
|
41
48
|
await eq.setEnabled(next);
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// `
|
|
46
|
-
// the
|
|
47
|
-
//
|
|
49
|
+
// `isEnabled()` is the authority on what the native side committed,
|
|
50
|
+
// so read it back rather than echoing the request. `onEnabledChange`
|
|
51
|
+
// has already delivered the same value — both platforms emit it
|
|
52
|
+
// synchronously inside `setEnabled`'s promise body — which makes this
|
|
53
|
+
// a redundant write on the happy path and the only correction if a
|
|
54
|
+
// future native build stops emitting. Fall back to the requested
|
|
55
|
+
// value when the read-back throws, matching the seed's try/catch.
|
|
48
56
|
try {
|
|
49
57
|
setEnabledState(eq.isEnabled());
|
|
50
58
|
} catch {
|
|
@@ -61,9 +69,8 @@ export function useEqualizer() {
|
|
|
61
69
|
await getEqualizer().applyPreset(name);
|
|
62
70
|
}, []);
|
|
63
71
|
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// manual sync re-fetch.
|
|
72
|
+
// The spec carries no presets-changed event, so save and delete
|
|
73
|
+
// re-read `getPresets()` themselves to refresh the local list.
|
|
67
74
|
const saveCustomPreset = useCallback(async name => {
|
|
68
75
|
await getEqualizer().saveCustomPreset(name);
|
|
69
76
|
setPresets(getEqualizer().getPresets());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useState","getEqualizer","useEqualizer","enabled","setEnabledState","isEnabled","bands","setBands","getBands","presets","setPresets","getPresets","eq","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useState","getEqualizer","useEqualizer","enabled","setEnabledState","isEnabled","bands","setBands","getBands","presets","setPresets","getPresets","eq","disposeBands","onBandChange","updated","disposeEnabled","onEnabledChange","next","setEnabled","setBandGain","index","gainDb","setAllBandGains","gains","applyPreset","name","saveCustomPreset","deleteCustomPreset","reset"],"sourceRoot":"../../../src","sources":["hooks/useEqualizer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -20,13 +20,9 @@ const INITIAL = {
|
|
|
20
20
|
* and drop the lookahead count).
|
|
21
21
|
*/
|
|
22
22
|
export function useLookaheadCache() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} catch {
|
|
27
|
-
return INITIAL;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
23
|
+
// Seeded by the listener's own first fire, which delivers current status on
|
|
24
|
+
// registration — no getter call, so this survives the getter being async.
|
|
25
|
+
const [status, setStatus] = useState(INITIAL);
|
|
30
26
|
useEffect(() => {
|
|
31
27
|
const player = getTrackPlayer();
|
|
32
28
|
const dispose = player.onCacheStatusChange(next => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useState","getTrackPlayer","INITIAL","enabled","currentSizeMb","maxSizeMb","tracksFullyCached","currentlyCaching","useLookaheadCache","status","setStatus","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useState","getTrackPlayer","INITIAL","enabled","currentSizeMb","maxSizeMb","tracksFullyCached","currentlyCaching","useLookaheadCache","status","setStatus","player","dispose","onCacheStatusChange","next","setConfig","config","setLookaheadCache","clear","clearLookaheadCache"],"sourceRoot":"../../../src","sources":["hooks/useLookaheadCache.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AACxD,SAASC,cAAc,QAAQ,eAAY;AAS3C;AACA;AACA;AACA;AACA,MAAMC,OAAoB,GAAG;EAC3BC,OAAO,EAAE,KAAK;EACdC,aAAa,EAAE,CAAC;EAChBC,SAAS,EAAE,GAAG;EACdC,iBAAiB,EAAE,CAAC;EACpBC,gBAAgB,EAAE;AACpB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAA4B;EAC3D;EACA;EACA,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGV,QAAQ,CAAcE,OAAO,CAAC;EAE1DH,SAAS,CAAC,MAAM;IACd,MAAMY,MAAM,GAAGV,cAAc,CAAC,CAAC;IAC/B,MAAMW,OAAO,GAAGD,MAAM,CAACE,mBAAmB,CAAEC,IAAI,IAAK;MACnDJ,SAAS,CAACI,IAAI,CAAC;IACjB,CAAC,CAAC;IACF,OAAOF,OAAO;EAChB,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMG,SAAS,GAAGjB,WAAW,CAAC,MAAOkB,MAA4B,IAAK;IACpE,MAAMf,cAAc,CAAC,CAAC,CAACgB,iBAAiB,CAACD,MAAM,CAAC;EAClD,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,KAAK,GAAGpB,WAAW,CAAC,YAAY;IACpC,MAAMG,cAAc,CAAC,CAAC,CAACkB,mBAAmB,CAAC,CAAC;EAC9C,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEV,MAAM;IAAEM,SAAS;IAAEG;EAAM,CAAC;AACrC","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { getTrackPlayer } from "../clients.js";
|
|
5
|
+
import { applyQueueDelta } from "../queueDelta.js";
|
|
5
6
|
const INITIAL = {
|
|
6
7
|
queue: [],
|
|
7
8
|
currentIndex: -1
|
|
@@ -13,30 +14,75 @@ const INITIAL = {
|
|
|
13
14
|
* `onTrackChange` so `currentIndex` stays live on auto-advance / skip,
|
|
14
15
|
* which move the active position without changing the queue contents.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Renders empty for the first frame, then fills in: the seed reads
|
|
18
|
+
* `getQueue()`, which resolves asynchronously. A mutation landing in that gap
|
|
19
|
+
* is not lost: a delta that arrives before the seed lands cannot be applied —
|
|
20
|
+
* there is nothing correct to apply it to — so the queue is re-read instead.
|
|
20
21
|
*/
|
|
21
22
|
export function useQueue() {
|
|
22
|
-
const [snapshot, setSnapshot] = useState(
|
|
23
|
-
try {
|
|
24
|
-
const player = getTrackPlayer();
|
|
25
|
-
return {
|
|
26
|
-
queue: player.getQueue(),
|
|
27
|
-
currentIndex: player.getCurrentTrackIndex()
|
|
28
|
-
};
|
|
29
|
-
} catch {
|
|
30
|
-
return INITIAL;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
23
|
+
const [snapshot, setSnapshot] = useState(INITIAL);
|
|
33
24
|
useEffect(() => {
|
|
34
25
|
const player = getTrackPlayer();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
let disposed = false;
|
|
27
|
+
// `haveBase` is what makes a delta applicable: without a queue to apply it
|
|
28
|
+
// to, applying one silently produces a wrong mirror — and for `shuffle`, an
|
|
29
|
+
// array of holes. `seenEvent` separately stops a slow seed overwriting
|
|
30
|
+
// newer state.
|
|
31
|
+
let haveBase = false;
|
|
32
|
+
let seenEvent = false;
|
|
33
|
+
let revision = 0;
|
|
34
|
+
// Guards against two overlapping re-reads resolving out of order.
|
|
35
|
+
let readTicket = 0;
|
|
36
|
+
const reread = () => {
|
|
37
|
+
const ticket = ++readTicket;
|
|
38
|
+
// Until this read lands there is no base a delta can be applied to:
|
|
39
|
+
// an event arriving meanwhile re-reads too, and the ticket keeps the
|
|
40
|
+
// last read's answer.
|
|
41
|
+
haveBase = false;
|
|
42
|
+
void player.getQueue().then(queue => {
|
|
43
|
+
if (disposed || ticket !== readTicket) return;
|
|
44
|
+
haveBase = true;
|
|
45
|
+
// Re-read the index too: the queue just came from a fresh read, and
|
|
46
|
+
// the index captured when the event fired may already be stale.
|
|
47
|
+
setSnapshot({
|
|
48
|
+
queue,
|
|
49
|
+
currentIndex: player.getCurrentTrackIndex()
|
|
50
|
+
});
|
|
51
|
+
}).catch(() => {
|
|
52
|
+
// Player not configured yet; a later event re-reads.
|
|
39
53
|
});
|
|
54
|
+
};
|
|
55
|
+
void (async () => {
|
|
56
|
+
try {
|
|
57
|
+
const ticket = ++readTicket;
|
|
58
|
+
const queue = await player.getQueue();
|
|
59
|
+
const currentIndex = player.getCurrentTrackIndex();
|
|
60
|
+
if (disposed || seenEvent || ticket !== readTicket) return;
|
|
61
|
+
haveBase = true;
|
|
62
|
+
setSnapshot({
|
|
63
|
+
queue,
|
|
64
|
+
currentIndex
|
|
65
|
+
});
|
|
66
|
+
} catch {
|
|
67
|
+
// Player not configured yet; the first event re-reads instead.
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
|
|
71
|
+
// A delta only makes sense against the copy it was computed from, so a
|
|
72
|
+
// missed event — or one that beats the seed — is recovered by re-reading
|
|
73
|
+
// rather than patched over.
|
|
74
|
+
const offQueue = player.onQueueChange((delta, currentIndex, reason) => {
|
|
75
|
+
seenEvent = true;
|
|
76
|
+
const missed = revision !== 0 && delta.revision !== revision + 1;
|
|
77
|
+
revision = delta.revision;
|
|
78
|
+
if (!haveBase || missed) {
|
|
79
|
+
reread();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
setSnapshot(prev => ({
|
|
83
|
+
queue: applyQueueDelta(prev.queue, delta, reason),
|
|
84
|
+
currentIndex
|
|
85
|
+
}));
|
|
40
86
|
});
|
|
41
87
|
// Keep `currentIndex` live when the active track changes without a
|
|
42
88
|
// queue-content change (auto-advance, skip). Preserves the queue from
|
|
@@ -48,6 +94,7 @@ export function useQueue() {
|
|
|
48
94
|
}));
|
|
49
95
|
});
|
|
50
96
|
return () => {
|
|
97
|
+
disposed = true;
|
|
51
98
|
offQueue();
|
|
52
99
|
offTrack();
|
|
53
100
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","queue","currentIndex","useQueue","snapshot","setSnapshot","player","getQueue","getCurrentTrackIndex","offQueue","onQueueChange","offTrack","onTrackChange","_track","index"
|
|
1
|
+
{"version":3,"names":["useEffect","useState","getTrackPlayer","applyQueueDelta","INITIAL","queue","currentIndex","useQueue","snapshot","setSnapshot","player","disposed","haveBase","seenEvent","revision","readTicket","reread","ticket","getQueue","then","getCurrentTrackIndex","catch","offQueue","onQueueChange","delta","reason","missed","prev","offTrack","onTrackChange","_track","index"],"sourceRoot":"../../../src","sources":["hooks/useQueue.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -27,11 +27,14 @@ export { SectionIcon } from "./types.js";
|
|
|
27
27
|
// `getEqualizer()` API for consumers building EQ UIs.
|
|
28
28
|
export { EQ_BAND_COUNT, EQ_BAND_FREQUENCIES_HZ, EQ_FLAT_PRESET_NAME, EQ_GAIN_MAX_DB, EQ_GAIN_MIN_DB, clampGain, gainsFromBands, gainsFromMap, isBuiltinPreset, nearestBandIndex } from "./equalizer.js";
|
|
29
29
|
|
|
30
|
+
// Pure helper for applying an onQueueChange delta to a queue copy.
|
|
31
|
+
export { applyQueueDelta } from "./queueDelta.js";
|
|
32
|
+
|
|
30
33
|
// React hooks — thin observers over the HybridObject event surface.
|
|
31
34
|
export * from "./hooks/index.js";
|
|
32
35
|
|
|
33
|
-
// Cast —
|
|
34
|
-
// `
|
|
35
|
-
// `getCastManager()`
|
|
36
|
+
// Cast — `Cast.*`: thin functions over the `CastManager` HybridObject
|
|
37
|
+
// (optional-argument shapes, `CastSubscription` handles, `CastErrorCodes`,
|
|
38
|
+
// `localRoute()`); `getCastManager()` returns the HybridObject itself.
|
|
36
39
|
export * as Cast from "./cast/index.js";
|
|
37
40
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getCastManager","getEqualizer","getTrackPlayer","getVisualizer","registerPlaybackService","unregisterPlaybackService","crossfadeDurationBounds","SectionIcon","EQ_BAND_COUNT","EQ_BAND_FREQUENCIES_HZ","EQ_FLAT_PRESET_NAME","EQ_GAIN_MAX_DB","EQ_GAIN_MIN_DB","clampGain","gainsFromBands","gainsFromMap","isBuiltinPreset","nearestBandIndex","Cast"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;;AAMA;;
|
|
1
|
+
{"version":3,"names":["getCastManager","getEqualizer","getTrackPlayer","getVisualizer","registerPlaybackService","unregisterPlaybackService","crossfadeDurationBounds","SectionIcon","EQ_BAND_COUNT","EQ_BAND_FREQUENCIES_HZ","EQ_FLAT_PRESET_NAME","EQ_GAIN_MAX_DB","EQ_GAIN_MIN_DB","clampGain","gainsFromBands","gainsFromMap","isBuiltinPreset","nearestBandIndex","applyQueueDelta","Cast"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;;AAMA;;AA+EA;AACA;AACA;AACA,SAASA,cAAc,EAAEC,YAAY,EAAEC,cAAc,EAAEC,aAAa,QAAQ,cAAW;;AAEvF;AACA;AACA;AACA,SACEC,uBAAuB,EACvBC,yBAAyB,QACpB,sBAAmB;AAM1B;AACA;AACA,SAASC,uBAAuB,QAAQ,YAAS;;AAEjD;AACA;AACA;AACA,SAASC,WAAW,QAAQ,YAAS;;AAErC;AACA;AACA;AACA,SACEC,aAAa,EACbC,sBAAsB,EACtBC,mBAAmB,EACnBC,cAAc,EACdC,cAAc,EACdC,SAAS,EACTC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,gBAAgB,QACX,gBAAa;;AAEpB;AACA,SAASC,eAAe,QAAQ,iBAAc;;AAE9C;AACA,cAAc,kBAAS;;AAEvB;AACA;AACA;AACA,OAAO,KAAKC,IAAI,MAAM,iBAAQ","ignoreList":[]}
|