react-native-audio-browser 0.2.0-next.1 → 0.2.0-next.11
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/README.md +22 -18
- package/android/build.gradle +13 -10
- package/android/gradle.properties +2 -2
- package/android/src/main/AndroidManifest.xml +3 -1
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +76 -21
- package/android/src/main/java/com/audiobrowser/AudioBrowserLifecycleModule.kt +38 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowserPackage.kt +18 -2
- package/android/src/main/java/com/audiobrowser/ServiceBinding.kt +48 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +1 -2
- package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +1 -2
- package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +6 -7
- package/android/src/main/java/com/audiobrowser/http/HttpClient.kt +20 -3
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +11 -11
- package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +111 -58
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +9 -5
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +218 -252
- package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +0 -1
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +2 -4
- package/android/src/main/java/com/audiobrowser/player/Player.kt +30 -8
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +2 -1
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +2 -1
- package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +67 -11
- package/android/src/main/java/com/audiobrowser/tls/AiaChasingExtendedTrustManager.kt +168 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +58 -14
- package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +35 -7
- package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +278 -59
- package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +7 -9
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +8 -7
- package/android/src/test/java/com/audiobrowser/ServiceBindingTest.kt +87 -0
- package/android/src/test/java/com/audiobrowser/TestFixtures.kt +52 -1
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +6 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +167 -8
- package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +2 -1
- package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +2 -4
- package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +100 -56
- package/android/src/test/java/com/audiobrowser/player/MediaSessionSlotMappingTest.kt +45 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +3 -4
- package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +3 -3
- package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +197 -7
- package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +325 -4
- package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherCallSiteTest.kt +322 -0
- package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +83 -0
- package/ios/Browser/BrowserManager.swift +2 -27
- package/ios/Browser/SearchDrillIn.swift +1 -1
- package/ios/CarPlay/RNABMediaAddHandler.swift +6 -6
- package/ios/CarPlay/RNABMediaAffinityHandler.swift +2 -2
- package/ios/CarPlay/RNABMediaIntentHandler.swift +16 -16
- package/ios/HybridAudioBrowser.swift +87 -56
- package/ios/Model/NitroTypeStubs.swift +18 -2
- package/ios/Model/RemoteCommand.swift +18 -0
- package/ios/Model/TrackPlayerError.swift +2 -2
- package/ios/Option/SessionCategories.swift +3 -2
- package/ios/Player/MediaIntentCriteria.swift +4 -4
- package/ios/Player/MediaLoader.swift +3 -1
- package/ios/Player/PlaybackCoordinator.swift +4 -1
- package/ios/Player/PlaybackErrorHandler.swift +4 -4
- package/ios/Player/QueueManager.swift +10 -3
- package/ios/Player/RetryManager.swift +79 -18
- package/ios/Player/ShuffleOrder.swift +10 -0
- package/ios/Player/SleepTimerManager.swift +43 -15
- package/ios/RemoteCommand/RemoteCommandCallbacks.swift +47 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +9 -6
- package/ios/Tests/LRUCacheTests.swift +111 -0
- package/ios/Tests/LoadSeekCoordinatorTests.swift +3 -1
- package/ios/Tests/MediaIntentCriteriaTests.swift +2 -2
- package/ios/Tests/MediaLoaderTests.swift +10 -13
- package/ios/Tests/PlaybackCoordinatorTests.swift +10 -7
- package/ios/Tests/PlaybackErrorHandlerTests.swift +3 -1
- package/ios/Tests/PlayerTimeObserverTests.swift +37 -0
- package/ios/Tests/QueueManagerTests.swift +50 -4
- package/ios/Tests/RemoteCommandControllerTests.swift +156 -0
- package/ios/Tests/RemoteCommandTests.swift +67 -0
- package/ios/Tests/RetryManagerTests.swift +89 -0
- package/ios/Tests/SectionScopeTests.swift +2 -2
- package/ios/Tests/SleepTimerManagerTests.swift +22 -19
- package/ios/Tests/Support/ManualSleepTimerScheduler.swift +47 -0
- package/ios/Tests/Support/TestTypes.swift +1 -1
- package/ios/Tests/TabBarEntriesTests.swift +7 -7
- package/ios/TrackPlayer.swift +6 -1
- package/ios/TrackPlayerCallbacks.swift +5 -38
- package/ios/Util/LRUCache.swift +4 -1
- package/lib/commonjs/AudioBrowser.js +0 -11
- package/lib/commonjs/AudioBrowser.js.map +1 -1
- package/lib/commonjs/CLAUDE.md +52 -0
- package/lib/commonjs/features/browser.js +1 -1
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/carConnection.js +1 -1
- package/lib/commonjs/features/equalizer.js +1 -1
- package/lib/commonjs/features/errors.js +3 -3
- package/lib/commonjs/features/favorites.js +1 -1
- package/lib/commonjs/features/gate.js +16 -1
- package/lib/commonjs/features/gate.js.map +1 -1
- package/lib/commonjs/features/metadata.js +20 -3
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/network.js +1 -1
- package/lib/commonjs/features/nowPlaying.js +1 -1
- package/lib/commonjs/features/output.js +1 -1
- package/lib/commonjs/features/playback/playWhenReady.js +1 -1
- package/lib/commonjs/features/playback/playing.js +1 -1
- package/lib/commonjs/features/playback/progress.js +1 -1
- package/lib/commonjs/features/playback/state.js +1 -1
- package/lib/commonjs/features/playback/trackPlaybackTime.js +0 -6
- package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -1
- package/lib/commonjs/features/playback/volume.js +1 -1
- package/lib/commonjs/features/player/options.js +48 -34
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/player/setup.js +15 -8
- package/lib/commonjs/features/player/setup.js.map +1 -1
- package/lib/commonjs/features/player/validateOptions.js +21 -0
- package/lib/commonjs/features/player/validateOptions.js.map +1 -0
- package/lib/commonjs/features/queue/activeTrack.js +1 -1
- package/lib/commonjs/features/queue/queue.js +2 -2
- package/lib/commonjs/features/queue/repeatMode.js +1 -1
- package/lib/commonjs/features/queue/shuffle.js +1 -1
- package/lib/commonjs/features/remoteControls.js +13 -92
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/features/sleepTimer.js +13 -1
- package/lib/commonjs/features/sleepTimer.js.map +1 -1
- package/lib/commonjs/test-utils/reactNativeStub.js +65 -0
- package/lib/commonjs/test-utils/reactNativeStub.js.map +1 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js +8 -5
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/commonjs/web/NativeAudioBrowser.js +1 -1
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +1 -1
- package/lib/module/AudioBrowser.js +1 -1
- package/lib/module/AudioBrowser.js.map +1 -1
- package/lib/module/CLAUDE.md +52 -0
- package/lib/module/features/browser.js +1 -1
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/carConnection.js +1 -1
- package/lib/module/features/equalizer.js +1 -1
- package/lib/module/features/errors.js +3 -3
- package/lib/module/features/favorites.js +1 -1
- package/lib/module/features/gate.js +16 -1
- package/lib/module/features/gate.js.map +1 -1
- package/lib/module/features/metadata.js +20 -3
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/network.js +1 -1
- package/lib/module/features/nowPlaying.js +1 -1
- package/lib/module/features/output.js +1 -1
- package/lib/module/features/playback/playWhenReady.js +1 -1
- package/lib/module/features/playback/playing.js +1 -1
- package/lib/module/features/playback/progress.js +1 -1
- package/lib/module/features/playback/state.js +1 -1
- package/lib/module/features/playback/trackPlaybackTime.js +0 -5
- package/lib/module/features/playback/trackPlaybackTime.js.map +1 -1
- package/lib/module/features/playback/volume.js +1 -1
- package/lib/module/features/player/options.js +47 -32
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/player/setup.js +14 -7
- package/lib/module/features/player/setup.js.map +1 -1
- package/lib/module/features/player/validateOptions.js +17 -0
- package/lib/module/features/player/validateOptions.js.map +1 -0
- package/lib/module/features/queue/activeTrack.js +1 -1
- package/lib/module/features/queue/queue.js +2 -2
- package/lib/module/features/queue/repeatMode.js +1 -1
- package/lib/module/features/queue/shuffle.js +1 -1
- package/lib/module/features/remoteControls.js +13 -92
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/features/sleepTimer.js +13 -1
- package/lib/module/features/sleepTimer.js.map +1 -1
- package/lib/module/test-utils/reactNativeStub.js +58 -0
- package/lib/module/test-utils/reactNativeStub.js.map +1 -0
- package/lib/module/utils/LazyNativeEmitter.js +8 -5
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/module/web/NativeAudioBrowser.js +1 -1
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +1 -1
- package/lib/typescript/src/AudioBrowser.d.ts +0 -1
- package/lib/typescript/src/AudioBrowser.d.ts.map +1 -1
- package/lib/typescript/src/features/carConnection.d.ts +1 -1
- package/lib/typescript/src/features/equalizer.d.ts +1 -1
- package/lib/typescript/src/features/errors.d.ts +3 -3
- package/lib/typescript/src/features/favorites.d.ts +1 -1
- package/lib/typescript/src/features/gate.d.ts +18 -2
- package/lib/typescript/src/features/gate.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +20 -3
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/network.d.ts +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +1 -1
- package/lib/typescript/src/features/output.d.ts +1 -1
- package/lib/typescript/src/features/playback/playWhenReady.d.ts +1 -1
- package/lib/typescript/src/features/playback/playing.d.ts +1 -1
- package/lib/typescript/src/features/playback/progress.d.ts +1 -1
- package/lib/typescript/src/features/playback/state.d.ts +1 -1
- package/lib/typescript/src/features/playback/volume.d.ts +1 -1
- package/lib/typescript/src/features/player/options.d.ts +87 -37
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/player/setup.d.ts +14 -4
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
- package/lib/typescript/src/features/player/validateOptions.d.ts +9 -0
- package/lib/typescript/src/features/player/validateOptions.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/activeTrack.d.ts +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts +2 -2
- package/lib/typescript/src/features/queue/repeatMode.d.ts +1 -1
- package/lib/typescript/src/features/queue/shuffle.d.ts +1 -1
- package/lib/typescript/src/features/remoteControls.d.ts +23 -22
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
- package/lib/typescript/src/test-utils/reactNativeStub.d.ts +36 -0
- package/lib/typescript/src/test-utils/reactNativeStub.d.ts.map +1 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +8 -4
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +1 -1
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +10 -10
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +5 -5
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +11 -11
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +5 -5
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +5 -5
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +10 -10
- package/nitrogen/generated/android/c++/JOptions.hpp +5 -5
- package/nitrogen/generated/android/c++/{JNotificationButton.hpp → JRemoteButton.hpp} +19 -19
- package/nitrogen/generated/android/c++/JRemoteButtonLayout.hpp +86 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.hpp +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NotificationButton.kt → RemoteButton.kt} +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButtonLayout.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Variant_NullType_NotificationButtonLayout.kt → Variant_NullType_RemoteButtonLayout.kt} +9 -9
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +36 -51
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +6 -6
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +8 -8
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +12 -12
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2 -2
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +12 -12
- package/nitrogen/generated/ios/swift/{NotificationButton.swift → RemoteButton.swift} +6 -6
- package/nitrogen/generated/ios/swift/RemoteButtonLayout.swift +57 -0
- package/nitrogen/generated/ios/swift/{Variant_NullType_NotificationButtonLayout.swift → Variant_NullType_RemoteButtonLayout.swift} +3 -3
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +8 -8
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +8 -8
- package/nitrogen/generated/shared/c++/{NotificationButton.hpp → RemoteButton.hpp} +19 -19
- package/nitrogen/generated/shared/c++/RemoteButtonLayout.hpp +94 -0
- package/package.json +12 -4
- package/src/AudioBrowser.ts +1 -1
- package/src/CLAUDE.md +52 -0
- package/src/features/battery.test.ts +79 -0
- package/src/features/browser.ts +1 -1
- package/src/features/carConnection.ts +1 -1
- package/src/features/equalizer.ts +1 -1
- package/src/features/errors.ts +3 -3
- package/src/features/favorites.ts +1 -1
- package/src/features/gate.ts +16 -1
- package/src/features/hook-wiring.test.ts +254 -0
- package/src/features/metadata.ts +20 -3
- package/src/features/network.ts +1 -1
- package/src/features/nowPlaying.ts +1 -1
- package/src/features/output.ts +1 -1
- package/src/features/playback/playWhenReady.ts +1 -1
- package/src/features/playback/playing.ts +1 -1
- package/src/features/playback/progress.test.ts +169 -0
- package/src/features/playback/progress.ts +1 -1
- package/src/features/playback/state.ts +1 -1
- package/src/features/playback/trackPlaybackTime.test.ts +16 -6
- package/src/features/playback/trackPlaybackTime.ts +0 -5
- package/src/features/playback/volume.ts +1 -1
- package/src/features/player/options.ts +99 -57
- package/src/features/player/setup.test.ts +12 -4
- package/src/features/player/setup.ts +19 -9
- package/src/features/player/validateOptions.ts +19 -0
- package/src/features/queue/activeTrack.ts +1 -1
- package/src/features/queue/queue.ts +2 -2
- package/src/features/queue/repeatMode.ts +1 -1
- package/src/features/queue/shuffle.ts +1 -1
- package/src/features/remoteControls.ts +13 -92
- package/src/features/sleepTimer.test.ts +172 -0
- package/src/features/sleepTimer.ts +9 -1
- package/src/nitro-stub-drift.test.ts +237 -0
- package/src/public-surface.test.ts +107 -0
- package/src/specs/audio-browser.nitro.ts +1 -1
- package/src/test-utils/reactNativeStub.ts +60 -0
- package/src/utils/LazyNativeEmitter.ts +9 -6
- package/src/utils/useDebug.test.ts +182 -0
- package/src/utils/useNativeUpdatedValue.test.ts +103 -0
- package/src/web/NativeAudioBrowser.ts +1 -1
- package/src/web/browser/BrowserManager.ts +1 -1
- package/ios/Model/MediaURL.swift +0 -67
- package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +0 -94
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +0 -26
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +0 -75
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +0 -50
- package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +0 -92
- package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +0 -102
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
///
|
|
2
|
-
///
|
|
2
|
+
/// RemoteButton.hpp
|
|
3
3
|
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
4
|
/// https://github.com/mrousavy/nitro
|
|
5
5
|
/// Copyright © Marc Rousavy @ Margelo
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
namespace margelo::nitro::audiobrowser {
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* An enum which can be represented as a JavaScript union (
|
|
29
|
+
* An enum which can be represented as a JavaScript union (RemoteButton).
|
|
30
30
|
*/
|
|
31
|
-
enum class
|
|
31
|
+
enum class RemoteButton {
|
|
32
32
|
SKIP_TO_PREVIOUS SWIFT_NAME(skipToPrevious) = 0,
|
|
33
33
|
SKIP_TO_NEXT SWIFT_NAME(skipToNext) = 1,
|
|
34
34
|
JUMP_BACKWARD SWIFT_NAME(jumpBackward) = 2,
|
|
@@ -40,30 +40,30 @@ namespace margelo::nitro::audiobrowser {
|
|
|
40
40
|
|
|
41
41
|
namespace margelo::nitro {
|
|
42
42
|
|
|
43
|
-
// C++
|
|
43
|
+
// C++ RemoteButton <> JS RemoteButton (union)
|
|
44
44
|
template <>
|
|
45
|
-
struct JSIConverter<margelo::nitro::audiobrowser::
|
|
46
|
-
static inline margelo::nitro::audiobrowser::
|
|
45
|
+
struct JSIConverter<margelo::nitro::audiobrowser::RemoteButton> final {
|
|
46
|
+
static inline margelo::nitro::audiobrowser::RemoteButton fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
47
47
|
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
48
48
|
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
49
|
-
case hashString("skip-to-previous"): return margelo::nitro::audiobrowser::
|
|
50
|
-
case hashString("skip-to-next"): return margelo::nitro::audiobrowser::
|
|
51
|
-
case hashString("jump-backward"): return margelo::nitro::audiobrowser::
|
|
52
|
-
case hashString("jump-forward"): return margelo::nitro::audiobrowser::
|
|
53
|
-
case hashString("favorite"): return margelo::nitro::audiobrowser::
|
|
49
|
+
case hashString("skip-to-previous"): return margelo::nitro::audiobrowser::RemoteButton::SKIP_TO_PREVIOUS;
|
|
50
|
+
case hashString("skip-to-next"): return margelo::nitro::audiobrowser::RemoteButton::SKIP_TO_NEXT;
|
|
51
|
+
case hashString("jump-backward"): return margelo::nitro::audiobrowser::RemoteButton::JUMP_BACKWARD;
|
|
52
|
+
case hashString("jump-forward"): return margelo::nitro::audiobrowser::RemoteButton::JUMP_FORWARD;
|
|
53
|
+
case hashString("favorite"): return margelo::nitro::audiobrowser::RemoteButton::FAVORITE;
|
|
54
54
|
default: [[unlikely]]
|
|
55
|
-
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum
|
|
55
|
+
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum RemoteButton - invalid value!");
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::audiobrowser::
|
|
58
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::audiobrowser::RemoteButton arg) {
|
|
59
59
|
switch (arg) {
|
|
60
|
-
case margelo::nitro::audiobrowser::
|
|
61
|
-
case margelo::nitro::audiobrowser::
|
|
62
|
-
case margelo::nitro::audiobrowser::
|
|
63
|
-
case margelo::nitro::audiobrowser::
|
|
64
|
-
case margelo::nitro::audiobrowser::
|
|
60
|
+
case margelo::nitro::audiobrowser::RemoteButton::SKIP_TO_PREVIOUS: return JSIConverter<std::string>::toJSI(runtime, "skip-to-previous");
|
|
61
|
+
case margelo::nitro::audiobrowser::RemoteButton::SKIP_TO_NEXT: return JSIConverter<std::string>::toJSI(runtime, "skip-to-next");
|
|
62
|
+
case margelo::nitro::audiobrowser::RemoteButton::JUMP_BACKWARD: return JSIConverter<std::string>::toJSI(runtime, "jump-backward");
|
|
63
|
+
case margelo::nitro::audiobrowser::RemoteButton::JUMP_FORWARD: return JSIConverter<std::string>::toJSI(runtime, "jump-forward");
|
|
64
|
+
case margelo::nitro::audiobrowser::RemoteButton::FAVORITE: return JSIConverter<std::string>::toJSI(runtime, "favorite");
|
|
65
65
|
default: [[unlikely]]
|
|
66
|
-
throw std::invalid_argument("Cannot convert
|
|
66
|
+
throw std::invalid_argument("Cannot convert RemoteButton to JS - invalid value: "
|
|
67
67
|
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// RemoteButtonLayout.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
// Forward declaration of `RemoteButton` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::audiobrowser { enum class RemoteButton; }
|
|
33
|
+
|
|
34
|
+
#include "RemoteButton.hpp"
|
|
35
|
+
#include <optional>
|
|
36
|
+
#include <vector>
|
|
37
|
+
|
|
38
|
+
namespace margelo::nitro::audiobrowser {
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A struct which can be represented as a JavaScript object (RemoteButtonLayout).
|
|
42
|
+
*/
|
|
43
|
+
struct RemoteButtonLayout final {
|
|
44
|
+
public:
|
|
45
|
+
std::optional<RemoteButton> back SWIFT_PRIVATE;
|
|
46
|
+
std::optional<RemoteButton> forward SWIFT_PRIVATE;
|
|
47
|
+
std::vector<RemoteButton> overflow SWIFT_PRIVATE;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
RemoteButtonLayout() = default;
|
|
51
|
+
explicit RemoteButtonLayout(std::optional<RemoteButton> back, std::optional<RemoteButton> forward, std::vector<RemoteButton> overflow): back(back), forward(forward), overflow(overflow) {}
|
|
52
|
+
|
|
53
|
+
public:
|
|
54
|
+
friend bool operator==(const RemoteButtonLayout& lhs, const RemoteButtonLayout& rhs) = default;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
} // namespace margelo::nitro::audiobrowser
|
|
58
|
+
|
|
59
|
+
namespace margelo::nitro {
|
|
60
|
+
|
|
61
|
+
// C++ RemoteButtonLayout <> JS RemoteButtonLayout (object)
|
|
62
|
+
template <>
|
|
63
|
+
struct JSIConverter<margelo::nitro::audiobrowser::RemoteButtonLayout> final {
|
|
64
|
+
static inline margelo::nitro::audiobrowser::RemoteButtonLayout fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
65
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
66
|
+
return margelo::nitro::audiobrowser::RemoteButtonLayout(
|
|
67
|
+
JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "back"))),
|
|
68
|
+
JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "forward"))),
|
|
69
|
+
JSIConverter<std::vector<margelo::nitro::audiobrowser::RemoteButton>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "overflow")))
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::audiobrowser::RemoteButtonLayout& arg) {
|
|
73
|
+
jsi::Object obj(runtime);
|
|
74
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "back"), JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::toJSI(runtime, arg.back));
|
|
75
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "forward"), JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::toJSI(runtime, arg.forward));
|
|
76
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "overflow"), JSIConverter<std::vector<margelo::nitro::audiobrowser::RemoteButton>>::toJSI(runtime, arg.overflow));
|
|
77
|
+
return obj;
|
|
78
|
+
}
|
|
79
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
80
|
+
if (!value.isObject()) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
jsi::Object obj = value.getObject(runtime);
|
|
84
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (!JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "back")))) return false;
|
|
88
|
+
if (!JSIConverter<std::optional<margelo::nitro::audiobrowser::RemoteButton>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "forward")))) return false;
|
|
89
|
+
if (!JSIConverter<std::vector<margelo::nitro::audiobrowser::RemoteButton>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "overflow")))) return false;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audio-browser",
|
|
3
|
-
"version": "0.2.0-next.
|
|
3
|
+
"version": "0.2.0-next.11",
|
|
4
4
|
"description": "react-native-audio-browser is a react native package built with Nitro",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -45,17 +45,20 @@
|
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
47
|
"android:format": "yarn workspace example-native android:format",
|
|
48
|
+
"android:format:check": "yarn workspace example-native android:format:check",
|
|
48
49
|
"android:ide": "yarn workspace example-native android:ide",
|
|
49
50
|
"android:logs": "react-native log-android",
|
|
50
51
|
"android:test": "yarn workspace example-native android:test",
|
|
51
52
|
"build": "yarn prepare",
|
|
52
53
|
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
53
54
|
"codegen": "node codegen/index.js --logLevel=\"debug\" && node post-script.cjs && node codegen/strip-struct-equality.cjs && yarn build",
|
|
54
|
-
"prepare": "bob build",
|
|
55
|
+
"prepare": "bob build && yarn hooks:install",
|
|
56
|
+
"hooks:install": "git config core.hooksPath .githooks || exit 0",
|
|
55
57
|
"example": "yarn workspace example-native",
|
|
56
|
-
"ci:format": "oxfmt --check
|
|
58
|
+
"ci:format": "oxfmt --check --ignore-path .gitignore --ignore-path .oxfmtignore .",
|
|
59
|
+
"ci:format:ios": "swiftformat --lint ios",
|
|
57
60
|
"ci:lint": "oxlint --type-aware src",
|
|
58
|
-
"format": "oxfmt --write",
|
|
61
|
+
"format": "oxfmt --write --ignore-path .gitignore --ignore-path .oxfmtignore .",
|
|
59
62
|
"ios:format": "swiftformat ios",
|
|
60
63
|
"ios:ide": "yarn workspace example-native ios:ide",
|
|
61
64
|
"ios:rebuild": "yarn workspace example-native ios:rebuild",
|
|
@@ -69,15 +72,20 @@
|
|
|
69
72
|
"@react-native-community/cli": "15.0.0-alpha.2",
|
|
70
73
|
"@semantic-release/changelog": "^6.0.3",
|
|
71
74
|
"@semantic-release/git": "^10.0.1",
|
|
75
|
+
"@testing-library/dom": "^10.4.1",
|
|
76
|
+
"@testing-library/react": "^16.3.2",
|
|
72
77
|
"@types/node": "^22",
|
|
73
78
|
"@types/react": "19.1.1",
|
|
79
|
+
"@types/react-dom": "19.1.7",
|
|
74
80
|
"conventional-changelog-conventionalcommits": "^9.3.0",
|
|
75
81
|
"del-cli": "^5.1.0",
|
|
82
|
+
"happy-dom": "^20.11.2",
|
|
76
83
|
"nitrogen": "0.35.0",
|
|
77
84
|
"oxfmt": "^0.27.0",
|
|
78
85
|
"oxlint": "^1.42.0",
|
|
79
86
|
"oxlint-tsgolint": "^0.11.2",
|
|
80
87
|
"react": "19.1.1",
|
|
88
|
+
"react-dom": "19.1.1",
|
|
81
89
|
"react-native": "0.83.0",
|
|
82
90
|
"react-native-builder-bob": "^0.37.0",
|
|
83
91
|
"react-native-monorepo-config": "^0.3.1",
|
package/src/AudioBrowser.ts
CHANGED
package/src/CLAUDE.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# TypeScript API
|
|
2
|
+
|
|
3
|
+
The rules here are about the shape of the package's public surface. Both are
|
|
4
|
+
enforced by tests, but the tests only tell you _after_ you've written it.
|
|
5
|
+
|
|
6
|
+
## Everything you export is public
|
|
7
|
+
|
|
8
|
+
`index.ts` → `AudioBrowser.ts` → `features/index.ts` is a chain of unfiltered
|
|
9
|
+
`export *`. There is no allowlist to add a symbol to: a new `export` in any
|
|
10
|
+
feature module joins the package's public surface the moment you write it.
|
|
11
|
+
|
|
12
|
+
`@internal` does **not** make a value private. `stripInternal` honours it when
|
|
13
|
+
building `lib/typescript` — what a consumer's TypeScript sees — but React Native
|
|
14
|
+
resolves `"react-native": "src/index"`, so Metro bundles the _source_, where
|
|
15
|
+
nothing was stripped. An `@internal` value is invisible to the type checker and
|
|
16
|
+
fully reachable at runtime via `require()`.
|
|
17
|
+
|
|
18
|
+
So an internal value needs a module the barrels don't re-export, imported
|
|
19
|
+
directly by its callers — `features/player/validateOptions.ts` is the pattern.
|
|
20
|
+
Types are exempt: they have no runtime representation, so `stripInternal` really
|
|
21
|
+
does remove them, and `@internal` is enough.
|
|
22
|
+
|
|
23
|
+
`native.ts` is the sharp case and stays out of the barrel permanently. It holds
|
|
24
|
+
the raw Nitro object, whose `on*` properties are single callback slots that the
|
|
25
|
+
emitters below already occupy — a consumer assigning one unsubscribes every hook
|
|
26
|
+
in the library. Feature modules import it relatively; nothing else touches it.
|
|
27
|
+
|
|
28
|
+
`public-surface.test.ts` walks the `export *` graph and fails on any reachable
|
|
29
|
+
value that is `@internal`, `__`-prefixed, or `nativeBrowser`.
|
|
30
|
+
|
|
31
|
+
## Events are emitters, not functions
|
|
32
|
+
|
|
33
|
+
Every `on*` export is an object you subscribe to with `addListener(cb)`, which
|
|
34
|
+
returns an unsubscribe function. Never export a bare `on*(cb)` subscribe
|
|
35
|
+
function — that split is what made the whole remote-controls guide a compile
|
|
36
|
+
error until it was unified.
|
|
37
|
+
|
|
38
|
+
Two emitter classes, picked by what the event _is_:
|
|
39
|
+
|
|
40
|
+
- `NativeUpdatedValue` — state with a current value (playback, options,
|
|
41
|
+
progress). Subscribes to native at module load so no update is missed, and
|
|
42
|
+
caches `lastValue` so hooks can read synchronously.
|
|
43
|
+
- `LazyNativeEmitter` — discrete events with no current value (remote controls,
|
|
44
|
+
gate hits). Assigns the native callback on the first `addListener`, so an
|
|
45
|
+
event nobody listens to costs nothing.
|
|
46
|
+
|
|
47
|
+
Both are created via `emitterize(cb => (nativeBrowser.onThing = cb))` and both
|
|
48
|
+
return the instance. Neither class is exported from the package.
|
|
49
|
+
|
|
50
|
+
`on*` observes; `handle*` overrides. `handleRemoteNext(cb)` is a plain setter
|
|
51
|
+
that replaces the default behaviour and takes `undefined` to clear it, while
|
|
52
|
+
`onRemoteNext` fires on every press regardless of who handled it.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** @vitest-environment happy-dom */
|
|
2
|
+
|
|
3
|
+
import { renderHook, act, cleanup } from '@testing-library/react'
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
5
|
+
import type { BatteryOptimizationStatus } from './battery'
|
|
6
|
+
|
|
7
|
+
const native = vi.hoisted(() => ({
|
|
8
|
+
getBatteryWarningPending: vi.fn(() => false),
|
|
9
|
+
getBatteryOptimizationStatus: vi.fn<() => BatteryOptimizationStatus>(
|
|
10
|
+
() => 'unknown' as BatteryOptimizationStatus
|
|
11
|
+
),
|
|
12
|
+
dismissBatteryWarning: vi.fn(),
|
|
13
|
+
openBatterySettings: vi.fn(),
|
|
14
|
+
onBatteryWarningPendingChanged: undefined as
|
|
15
|
+
| ((event: { pending: boolean }) => void)
|
|
16
|
+
| undefined,
|
|
17
|
+
onBatteryOptimizationStatusChanged: undefined as
|
|
18
|
+
| ((event: { status: BatteryOptimizationStatus }) => void)
|
|
19
|
+
| undefined
|
|
20
|
+
}))
|
|
21
|
+
|
|
22
|
+
vi.mock('../native', () => ({ nativeBrowser: native }))
|
|
23
|
+
|
|
24
|
+
const { useBatteryWarning } = await import('./battery')
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vi.clearAllMocks()
|
|
28
|
+
native.getBatteryWarningPending.mockReturnValue(false)
|
|
29
|
+
native.getBatteryOptimizationStatus.mockReturnValue(
|
|
30
|
+
'unknown' as BatteryOptimizationStatus
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
afterEach(cleanup)
|
|
34
|
+
|
|
35
|
+
describe('useBatteryWarning', () => {
|
|
36
|
+
it('combines the two underlying values into one object', () => {
|
|
37
|
+
const { result } = renderHook(() => useBatteryWarning())
|
|
38
|
+
expect(result.current).toMatchObject({ pending: false, status: 'unknown' })
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('tracks each source independently', () => {
|
|
42
|
+
const { result } = renderHook(() => useBatteryWarning())
|
|
43
|
+
|
|
44
|
+
act(() => native.onBatteryWarningPendingChanged?.({ pending: true }))
|
|
45
|
+
expect(result.current).toMatchObject({ pending: true, status: 'unknown' })
|
|
46
|
+
|
|
47
|
+
act(() =>
|
|
48
|
+
native.onBatteryOptimizationStatusChanged?.({
|
|
49
|
+
status: 'restricted' as BatteryOptimizationStatus
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
expect(result.current).toMatchObject({
|
|
53
|
+
pending: true,
|
|
54
|
+
status: 'restricted'
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('exposes actions that reach native', () => {
|
|
59
|
+
const { result } = renderHook(() => useBatteryWarning())
|
|
60
|
+
|
|
61
|
+
result.current.dismiss()
|
|
62
|
+
expect(native.dismissBatteryWarning).toHaveBeenCalledOnce()
|
|
63
|
+
|
|
64
|
+
result.current.openSettings()
|
|
65
|
+
expect(native.openBatterySettings).toHaveBeenCalledOnce()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('keeps the action identities stable across updates', () => {
|
|
69
|
+
const { result } = renderHook(() => useBatteryWarning())
|
|
70
|
+
const { dismiss, openSettings } = result.current
|
|
71
|
+
|
|
72
|
+
act(() => native.onBatteryWarningPendingChanged?.({ pending: true }))
|
|
73
|
+
|
|
74
|
+
// They are module-level functions, not closures — a consumer can safely put
|
|
75
|
+
// them in a dependency array.
|
|
76
|
+
expect(result.current.dismiss).toBe(dismiss)
|
|
77
|
+
expect(result.current.openSettings).toBe(openSettings)
|
|
78
|
+
})
|
|
79
|
+
})
|
package/src/features/browser.ts
CHANGED
|
@@ -19,7 +19,7 @@ export function isCarConnected(): boolean {
|
|
|
19
19
|
* Subscribes to car connection changes (CarPlay on iOS, Android Auto /
|
|
20
20
|
* Android Automotive on Android). Never fires on web.
|
|
21
21
|
* @param callback - Called with the new connection state
|
|
22
|
-
* @returns
|
|
22
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
23
23
|
*/
|
|
24
24
|
export const onCarConnectedChanged = NativeUpdatedValue.emitterize<boolean>(
|
|
25
25
|
(cb) => (nativeBrowser.onCarConnectedChanged = cb)
|
|
@@ -46,7 +46,7 @@ export function setEqualizerLevels(levels: number[]): void {
|
|
|
46
46
|
/**
|
|
47
47
|
* Subscribes to equalizer settings changes (Android only).
|
|
48
48
|
* @param callback - Called when equalizer settings change
|
|
49
|
-
* @returns
|
|
49
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
50
50
|
*/
|
|
51
51
|
export const onEqualizerChanged =
|
|
52
52
|
NativeUpdatedValue.emitterize<EqualizerSettings>(
|
package/src/features/errors.ts
CHANGED
|
@@ -134,7 +134,7 @@ export function getPlaybackError(): PlaybackError | undefined {
|
|
|
134
134
|
/**
|
|
135
135
|
* Subscribes to playback error events.
|
|
136
136
|
* @param callback - Called when a playback error occurs
|
|
137
|
-
* @returns
|
|
137
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
138
138
|
*/
|
|
139
139
|
export const onPlaybackError =
|
|
140
140
|
NativeUpdatedValue.emitterize<PlaybackErrorEvent>(
|
|
@@ -165,7 +165,7 @@ export function getNavigationError(): NavigationError | undefined {
|
|
|
165
165
|
/**
|
|
166
166
|
* Subscribes to navigation error events.
|
|
167
167
|
* @param callback - Called when a navigation error occurs
|
|
168
|
-
* @returns
|
|
168
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
169
169
|
*/
|
|
170
170
|
export const onNavigationError =
|
|
171
171
|
NativeUpdatedValue.emitterize<NavigationErrorEvent>(
|
|
@@ -198,7 +198,7 @@ export function getFormattedNavigationError():
|
|
|
198
198
|
/**
|
|
199
199
|
* Subscribes to formatted navigation error changes.
|
|
200
200
|
* @param callback - Called when the formatted navigation error changes
|
|
201
|
-
* @returns
|
|
201
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
202
202
|
*/
|
|
203
203
|
export const onFormattedNavigationError = NativeUpdatedValue.emitterize<
|
|
204
204
|
FormattedNavigationError | undefined
|
|
@@ -82,7 +82,7 @@ export interface FavoriteChangedEvent {
|
|
|
82
82
|
* The native side has already updated the track's favorite state and UI.
|
|
83
83
|
*
|
|
84
84
|
* @param callback - Called with the track and its new favorite state
|
|
85
|
-
* @returns
|
|
85
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
86
86
|
*
|
|
87
87
|
* @example
|
|
88
88
|
* ```ts
|
package/src/features/gate.ts
CHANGED
|
@@ -120,12 +120,20 @@ nativeBrowser.resolveGate = async (
|
|
|
120
120
|
* some surfaces (CarPlay) any gate change pops pushed navigation back to root,
|
|
121
121
|
* so a page the user had drilled into is reset to the tab root. Set the gate
|
|
122
122
|
* before the car connects and it'll be there the moment it does.
|
|
123
|
+
*
|
|
124
|
+
* @platform ios android
|
|
125
|
+
* A no-op on web, which has no CarPlay or Android Auto surfaces for the gate to
|
|
126
|
+
* cover. Nothing is lost: the gate never covered in-app browse UI on any
|
|
127
|
+
* platform — that stays yours to gate.
|
|
123
128
|
*/
|
|
124
129
|
export function setGate(gate: Gate, resolve?: GateResolver): void
|
|
125
130
|
/**
|
|
126
131
|
* Raises the gate with a resolver only (no default chrome).
|
|
127
132
|
* The resolver must return a {@link Gate} or `true` for gated requests;
|
|
128
133
|
* native uses the built-in fallback chrome when `true` and no default is set.
|
|
134
|
+
*
|
|
135
|
+
* @platform ios android
|
|
136
|
+
* A no-op on web — the resolver is never consulted there.
|
|
129
137
|
*/
|
|
130
138
|
export function setGate(resolve: GateResolver): void
|
|
131
139
|
export function setGate(a: Gate | GateResolver, b?: GateResolver): void {
|
|
@@ -140,6 +148,9 @@ export function setGate(a: Gate | GateResolver, b?: GateResolver): void {
|
|
|
140
148
|
|
|
141
149
|
/**
|
|
142
150
|
* Drops the gate — the real content comes back, and the current tab is kept.
|
|
151
|
+
*
|
|
152
|
+
* @platform ios android
|
|
153
|
+
* A no-op on web, where no gate was ever raised.
|
|
143
154
|
*/
|
|
144
155
|
export function clearGate(): void {
|
|
145
156
|
resolver = undefined
|
|
@@ -148,7 +159,11 @@ export function clearGate(): void {
|
|
|
148
159
|
|
|
149
160
|
/**
|
|
150
161
|
* Subscribes to gate events (fired when a request is gated).
|
|
151
|
-
*
|
|
162
|
+
*
|
|
163
|
+
* @platform ios android
|
|
164
|
+
* Never fires on web — there are no gated serves to report.
|
|
165
|
+
*
|
|
166
|
+
* @returns An emitter — subscribe with `addListener(callback)`, which returns a cleanup function
|
|
152
167
|
*/
|
|
153
168
|
export const onGate = LazyNativeEmitter.emitterize<GateEvent>(
|
|
154
169
|
(cb) => (nativeBrowser.onGate = cb)
|