From 6eb02d32cb676c8a2ee1b259fd2eae8737feeea9 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 21 Jul 2026 19:43:30 +0200 Subject: [PATCH] fix(provider): make source optional --- .../main/java/dev/zoriya/omni/OmniPlayer.kt | 9 +++++++- .../java/dev/zoriya/omni/OmniPlayerFactory.kt | 2 +- .../c++/JHybridOmniPlayerFactorySpec.cpp | 6 ++--- .../c++/JHybridOmniPlayerFactorySpec.hpp | 2 +- .../android/c++/JHybridOmniPlayerSpec.cpp | 4 ++-- .../android/c++/JHybridOmniPlayerSpec.hpp | 2 +- nitrogen/generated/android/c++/JSource.hpp | 6 ++++- .../nitro/omni/HybridOmniPlayerFactorySpec.kt | 2 +- .../nitro/omni/HybridOmniPlayerSpec.kt | 2 +- .../kotlin/com/margelo/nitro/omni/Source.kt | 9 ++++++-- .../c++/HybridOmniPlayerFactorySpec.hpp | 3 ++- .../shared/c++/HybridOmniPlayerSpec.hpp | 2 +- nitrogen/generated/shared/c++/Source.hpp | 6 ++++- .../generated/shared/json/OmniViewConfig.json | 22 +++++++++---------- src/provider.tsx | 2 +- src/provider.web.tsx | 10 ++++----- src/specs/omni-player.nitro.ts | 4 ++-- 17 files changed, 57 insertions(+), 36 deletions(-) diff --git a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt index 1a16e5c..58d7c36 100644 --- a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt +++ b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt @@ -177,7 +177,14 @@ class OmniPlayer : HybridOmniPlayerSpec() { } } - override fun setSource(src: Source) { + override fun setSource(src: Source?) { + if (src == null) { + runOnMainThreadSync { + player.setMediaItem(MediaItem.EMPTY) + player.prepare() + } + return + } val handleAudioFocus = (src.mixAudio ?: MixAudioMode.AUTO) != MixAudioMode.MIXWITHOTHERS val audioAttributes = AudioAttributes.Builder() .setUsage(C.USAGE_MEDIA) diff --git a/android/src/main/java/dev/zoriya/omni/OmniPlayerFactory.kt b/android/src/main/java/dev/zoriya/omni/OmniPlayerFactory.kt index 932f0bd..a6b3917 100755 --- a/android/src/main/java/dev/zoriya/omni/OmniPlayerFactory.kt +++ b/android/src/main/java/dev/zoriya/omni/OmniPlayerFactory.kt @@ -7,7 +7,7 @@ import com.margelo.nitro.omni.HybridOmniPlayerSpec import com.margelo.nitro.omni.Source class OmniPlayerFactory(val context: ThemedReactContext) : HybridOmniPlayerFactorySpec() { - override fun createPlayer(props: Source): HybridOmniPlayerSpec { + override fun createPlayer(props: Source?): HybridOmniPlayerSpec { return OmniPlayer().apply { setSource(props) } diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp index 8e95bf1..63423c0 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp @@ -24,12 +24,12 @@ namespace margelo::nitro::omni { enum class MixAudioMode; } #include "HybridOmniPlayerSpec.hpp" #include "JHybridOmniPlayerSpec.hpp" #include "Source.hpp" +#include #include "JSource.hpp" #include "VideoSrc.hpp" #include #include "JVideoSrc.hpp" #include -#include #include #include "Subtitle.hpp" #include "JSubtitle.hpp" @@ -71,9 +71,9 @@ namespace margelo::nitro::omni { // Methods - std::shared_ptr JHybridOmniPlayerFactorySpec::createPlayer(const Source& props) { + std::shared_ptr JHybridOmniPlayerFactorySpec::createPlayer(const std::optional& props) { static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* props */)>("createPlayer"); - auto __result = method(_javaPart, JSource::fromCpp(props)); + auto __result = method(_javaPart, props.has_value() ? JSource::fromCpp(props.value()) : nullptr); return __result->getJHybridOmniPlayerSpec(); } diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp index 35a0092..50785a5 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp @@ -54,7 +54,7 @@ namespace margelo::nitro::omni { public: // Methods - std::shared_ptr createPlayer(const Source& props) override; + std::shared_ptr createPlayer(const std::optional& props) override; private: jni::global_ref _javaPart; diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp index e24ba15..2451617 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp @@ -232,9 +232,9 @@ namespace margelo::nitro::omni { } // Methods - void JHybridOmniPlayerSpec::setSource(const Source& src) { + void JHybridOmniPlayerSpec::setSource(const std::optional& src) { static const auto method = _javaPart->javaClassStatic()->getMethod /* src */)>("setSource"); - method(_javaPart, JSource::fromCpp(src)); + method(_javaPart, src.has_value() ? JSource::fromCpp(src.value()) : nullptr); } void JHybridOmniPlayerSpec::play() { static const auto method = _javaPart->javaClassStatic()->getMethod("play"); diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp index 0eef745..77e8567 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp @@ -76,7 +76,7 @@ namespace margelo::nitro::omni { public: // Methods - void setSource(const Source& src) override; + void setSource(const std::optional& src) override; void play() override; void pause() override; void seekBy(double offset) override; diff --git a/nitrogen/generated/android/c++/JSource.hpp b/nitrogen/generated/android/c++/JSource.hpp index 8ee15a5..b1bdf1f 100644 --- a/nitrogen/generated/android/c++/JSource.hpp +++ b/nitrogen/generated/android/c++/JSource.hpp @@ -54,6 +54,8 @@ namespace margelo::nitro::omni { jni::local_ref metadata = this->getFieldValue(fieldMetadata); static const auto fieldMixAudio = clazz->getField("mixAudio"); jni::local_ref mixAudio = this->getFieldValue(fieldMixAudio); + static const auto fieldCastId = clazz->getField("castId"); + jni::local_ref castId = this->getFieldValue(fieldCastId); static const auto fieldCastData = clazz->getField>("castData"); jni::local_ref> castData = this->getFieldValue(fieldCastData); return Source( @@ -90,6 +92,7 @@ namespace margelo::nitro::omni { }(fonts)) : std::nullopt, metadata != nullptr ? std::make_optional(metadata->toCpp()) : std::nullopt, mixAudio != nullptr ? std::make_optional(mixAudio->toCpp()) : std::nullopt, + castId != nullptr ? std::make_optional(castId->toStdString()) : std::nullopt, castData != nullptr ? std::make_optional([&]() { std::unordered_map __map; __map.reserve(castData->size()); @@ -107,7 +110,7 @@ namespace margelo::nitro::omni { */ [[maybe_unused]] static jni::local_ref fromCpp(const Source& value) { - using JSignature = JSource(jni::alias_ref>, jni::alias_ref, jni::alias_ref>, jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref>); + using JSignature = JSource(jni::alias_ref>, jni::alias_ref, jni::alias_ref>, jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref>); static const auto clazz = javaClassStatic(); static const auto create = clazz->getStaticMethod("fromCpp"); return create( @@ -145,6 +148,7 @@ namespace margelo::nitro::omni { }(value.fonts.value()) : nullptr, value.metadata.has_value() ? JMetadata::fromCpp(value.metadata.value()) : nullptr, value.mixAudio.has_value() ? JMixAudioMode::fromCpp(value.mixAudio.value()) : nullptr, + value.castId.has_value() ? jni::make_jstring(value.castId.value()) : nullptr, value.castData.has_value() ? [&]() -> jni::local_ref> { auto __map = jni::JHashMap::create(value.castData.value().size()); for (const auto& __entry : value.castData.value()) { diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerFactorySpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerFactorySpec.kt index 6dd00ca..96b18be 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerFactorySpec.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerFactorySpec.kt @@ -30,7 +30,7 @@ abstract class HybridOmniPlayerFactorySpec: HybridObject() { // Methods @DoNotStrip @Keep - abstract fun createPlayer(props: Source): HybridOmniPlayerSpec + abstract fun createPlayer(props: Source?): HybridOmniPlayerSpec // Default implementation of `HybridObject.toString()` override fun toString(): String { diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt index f8f48ba..394225c 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt @@ -110,7 +110,7 @@ abstract class HybridOmniPlayerSpec: HybridObject() { // Methods @DoNotStrip @Keep - abstract fun setSource(src: Source): Unit + abstract fun setSource(src: Source?): Unit @DoNotStrip @Keep diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt index 7b9d03a..5581d28 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt @@ -38,6 +38,9 @@ data class Source( val mixAudio: MixAudioMode?, @DoNotStrip @Keep + val castId: String?, + @DoNotStrip + @Keep val castData: Map? ) { /* primary constructor */ @@ -51,6 +54,7 @@ data class Source( && Objects.deepEquals(this.fonts, other.fonts) && Objects.deepEquals(this.metadata, other.metadata) && Objects.deepEquals(this.mixAudio, other.mixAudio) + && Objects.deepEquals(this.castId, other.castId) && Objects.deepEquals(this.castData, other.castData) } @@ -62,6 +66,7 @@ data class Source( fonts, metadata, mixAudio, + castId, castData ).contentDeepHashCode() } @@ -74,8 +79,8 @@ data class Source( @Keep @Suppress("unused") @JvmStatic - private fun fromCpp(src: Array, startTime: Double?, subtitles: Array, fonts: Array?, metadata: Metadata?, mixAudio: MixAudioMode?, castData: Map?): Source { - return Source(src, startTime, subtitles, fonts, metadata, mixAudio, castData) + private fun fromCpp(src: Array, startTime: Double?, subtitles: Array, fonts: Array?, metadata: Metadata?, mixAudio: MixAudioMode?, castId: String?, castData: Map?): Source { + return Source(src, startTime, subtitles, fonts, metadata, mixAudio, castId, castData) } } } diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp b/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp index e9a1fc4..3d9938d 100644 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp +++ b/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp @@ -21,6 +21,7 @@ namespace margelo::nitro::omni { struct Source; } #include #include "HybridOmniPlayerSpec.hpp" #include "Source.hpp" +#include namespace margelo::nitro::omni { @@ -53,7 +54,7 @@ namespace margelo::nitro::omni { public: // Methods - virtual std::shared_ptr createPlayer(const Source& props) = 0; + virtual std::shared_ptr createPlayer(const std::optional& props) = 0; protected: // Hybrid Setup diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp index 8a1bfc5..1d9eaff 100644 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp +++ b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp @@ -89,7 +89,7 @@ namespace margelo::nitro::omni { public: // Methods - virtual void setSource(const Source& src) = 0; + virtual void setSource(const std::optional& src) = 0; virtual void play() = 0; virtual void pause() = 0; virtual void seekBy(double offset) = 0; diff --git a/nitrogen/generated/shared/c++/Source.hpp b/nitrogen/generated/shared/c++/Source.hpp index a3c174e..00d43b1 100644 --- a/nitrogen/generated/shared/c++/Source.hpp +++ b/nitrogen/generated/shared/c++/Source.hpp @@ -59,11 +59,12 @@ namespace margelo::nitro::omni { std::optional> fonts SWIFT_PRIVATE; std::optional metadata SWIFT_PRIVATE; std::optional mixAudio SWIFT_PRIVATE; + std::optional castId SWIFT_PRIVATE; std::optional> castData SWIFT_PRIVATE; public: Source() = default; - explicit Source(std::vector src, std::optional startTime, std::vector subtitles, std::optional> fonts, std::optional metadata, std::optional mixAudio, std::optional> castData): src(src), startTime(startTime), subtitles(subtitles), fonts(fonts), metadata(metadata), mixAudio(mixAudio), castData(castData) {} + explicit Source(std::vector src, std::optional startTime, std::vector subtitles, std::optional> fonts, std::optional metadata, std::optional mixAudio, std::optional castId, std::optional> castData): src(src), startTime(startTime), subtitles(subtitles), fonts(fonts), metadata(metadata), mixAudio(mixAudio), castId(castId), castData(castData) {} public: friend bool operator==(const Source& lhs, const Source& rhs) = default; @@ -85,6 +86,7 @@ namespace margelo::nitro { JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "fonts"))), JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata"))), JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mixAudio"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "castId"))), JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "castData"))) ); } @@ -96,6 +98,7 @@ namespace margelo::nitro { obj.setProperty(runtime, PropNameIDCache::get(runtime, "fonts"), JSIConverter>>::toJSI(runtime, arg.fonts)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "metadata"), JSIConverter>::toJSI(runtime, arg.metadata)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "mixAudio"), JSIConverter>::toJSI(runtime, arg.mixAudio)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "castId"), JSIConverter>::toJSI(runtime, arg.castId)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "castData"), JSIConverter>>::toJSI(runtime, arg.castData)); return obj; } @@ -113,6 +116,7 @@ namespace margelo::nitro { if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "fonts")))) return false; if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata")))) return false; if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mixAudio")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "castId")))) return false; if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "castData")))) return false; return true; } diff --git a/nitrogen/generated/shared/json/OmniViewConfig.json b/nitrogen/generated/shared/json/OmniViewConfig.json index c2ad2f1..fac84a7 100644 --- a/nitrogen/generated/shared/json/OmniViewConfig.json +++ b/nitrogen/generated/shared/json/OmniViewConfig.json @@ -1,13 +1,13 @@ { - "uiViewClassName": "OmniView", - "supportsRawText": false, - "bubblingEventTypes": {}, - "directEventTypes": {}, - "validAttributes": { - "player": true, - "autoplay": true, - "autoPip": true, - "subtitleAssets": true, - "hybridRef": true - } + "uiViewClassName": "OmniView", + "supportsRawText": false, + "bubblingEventTypes": {}, + "directEventTypes": {}, + "validAttributes": { + "player": true, + "autoplay": true, + "autoPip": true, + "subtitleAssets": true, + "hybridRef": true + } } diff --git a/src/provider.tsx b/src/provider.tsx index 6756249..d0d7c5f 100755 --- a/src/provider.tsx +++ b/src/provider.tsx @@ -16,7 +16,7 @@ export const OmniProvider = ({ showNotification = false, cast: _, }: { - source: Source; + source?: Source; cast?: CastOptions; children: ReactNode; showNotification?: boolean; diff --git a/src/provider.web.tsx b/src/provider.web.tsx index 4632bbf..72aaa10 100644 --- a/src/provider.web.tsx +++ b/src/provider.web.tsx @@ -22,7 +22,7 @@ export const OmniProvider = ({ cast, showNotification = false, }: { - source: Source; + source?: Source; cast?: CastOptions; children: ReactNode; showNotification?: boolean; @@ -47,7 +47,7 @@ const PlayerInitializer = ({ showNotification, }: { children: ReactNode; - source: Source; + source?: Source; cast?: CastOptions; showNotification: boolean; }) => { @@ -56,11 +56,11 @@ const PlayerInitializer = ({ const seekedForSrc = useRef(undefined); useEffect(() => { - player.source = source; - const uri = source.src[0]?.uri; + player.source = source ?? null; + const uri = source?.src[0]?.uri; if (uri !== seekedForSrc.current) { seekedForSrc.current = uri; - if (source.startTime) store.seek(source.startTime); + if (source?.startTime) store.seek(source.startTime); } }, [source, store]); diff --git a/src/specs/omni-player.nitro.ts b/src/specs/omni-player.nitro.ts index 1546694..861583b 100644 --- a/src/specs/omni-player.nitro.ts +++ b/src/specs/omni-player.nitro.ts @@ -57,9 +57,9 @@ export interface OmniPlayer OmniPlayerT { readonly eventMap: OmniEventMap; - setSource(src: Source): void; + setSource(src?: Source): void; } export interface OmniPlayerFactory extends HybridObject<{ android: "kotlin" }> { - createPlayer(props: Source): OmniPlayer; + createPlayer(props?: Source): OmniPlayer; }