From fd40915bc96bc6d8b6d74ae6c009a776822582de Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 10 Apr 2026 19:17:22 +0200 Subject: [PATCH] Cleanup source handling --- .../main/java/dev/zoriya/omni/OmniPlayer.kt | 4 +- biome.json | 13 ++ .../generated/android/Omni+autolinking.cmake | 2 - nitrogen/generated/android/OmniOnLoad.cpp | 2 - .../c++/JHybridOmniPlayerFactorySpec.cpp | 34 +++- .../c++/JHybridOmniPlayerFactorySpec.hpp | 2 +- .../c++/JHybridOmniPlayerPropsSpec.cpp | 147 ------------------ .../c++/JHybridOmniPlayerPropsSpec.hpp | 72 --------- .../android/c++/JHybridOmniPlayerSpec.cpp | 36 ++++- .../android/c++/JHybridOmniPlayerSpec.hpp | 2 + nitrogen/generated/android/c++/JSource.hpp | 120 ++++++++++++++ .../nitro/omni/HybridOmniPlayerFactorySpec.kt | 2 +- .../nitro/omni/HybridOmniPlayerPropsSpec.kt | 80 ---------- .../nitro/omni/HybridOmniPlayerSpec.kt | 6 + .../kotlin/com/margelo/nitro/omni/Source.kt | 50 ++++++ .../c++/HybridOmniPlayerFactorySpec.hpp | 8 +- .../shared/c++/HybridOmniPlayerPropsSpec.cpp | 30 ---- .../shared/c++/HybridOmniPlayerPropsSpec.hpp | 83 ---------- .../shared/c++/HybridOmniPlayerSpec.cpp | 2 + .../shared/c++/HybridOmniPlayerSpec.hpp | 5 + nitrogen/generated/shared/c++/Source.hpp | 111 +++++++++++++ src/provider.tsx | 27 ++-- src/specs/omni-player.nitro.ts | 8 +- src/types/player.ts | 4 + src/types/{provider.ts => source.ts} | 2 +- src/utils/lazy-ref.ts | 13 ++ 26 files changed, 415 insertions(+), 450 deletions(-) delete mode 100644 nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp delete mode 100644 nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.hpp create mode 100644 nitrogen/generated/android/c++/JSource.hpp delete mode 100644 nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerPropsSpec.kt create mode 100644 nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt delete mode 100644 nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp delete mode 100644 nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.hpp create mode 100644 nitrogen/generated/shared/c++/Source.hpp rename src/types/{provider.ts => source.ts} (95%) create mode 100644 src/utils/lazy-ref.ts diff --git a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt index 5dfe049..0616c90 100644 --- a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt +++ b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt @@ -2,7 +2,7 @@ package dev.zoriya.omni import android.net.Uri import com.margelo.nitro.NitroModules -import com.margelo.nitro.omni.HybridOmniPlayerPropsSpec +import com.margelo.nitro.omni.Source import com.margelo.nitro.omni.HybridOmniPlayerSpec import com.margelo.nitro.omni.PlayerStatus import com.margelo.nitro.omni.Rendition @@ -17,7 +17,7 @@ class OmniPlayer() : HybridOmniPlayerSpec() { val vlc = LibVLC(NitroModules.applicationContext ?: throw Error("No Context available!")) val player = MediaPlayer(vlc) - var source: HybridOmniPlayerPropsSpec by deferredObservable { _, _, new -> + override var source: Source by deferredObservable { _, _, new -> val src = new.src.firstOrNull()?.uri ?: return@deferredObservable player.media = Media(vlc, Uri.parse(src)) new.startTime?.let { start -> diff --git a/biome.json b/biome.json index a61bbaa..4ecc066 100644 --- a/biome.json +++ b/biome.json @@ -18,6 +18,19 @@ "recommended": true, "style": { "noNonNullAssertion": "off" + }, + "correctness": { + "useExhaustiveDependencies": { + "level": "warn", + "options": { + "hooks": [ + { + "name": "useLazyRef", + "stableResult": true + } + ] + } + } } } }, diff --git a/nitrogen/generated/android/Omni+autolinking.cmake b/nitrogen/generated/android/Omni+autolinking.cmake index 9270301..ab143fa 100644 --- a/nitrogen/generated/android/Omni+autolinking.cmake +++ b/nitrogen/generated/android/Omni+autolinking.cmake @@ -33,13 +33,11 @@ target_sources( # Autolinking Setup ../nitrogen/generated/android/OmniOnLoad.cpp # Shared Nitrogen C++ sources - ../nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp ../nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp ../nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.cpp ../nitrogen/generated/shared/c++/HybridOmniViewSpec.cpp ../nitrogen/generated/shared/c++/views/HybridOmniViewComponent.cpp # Android-specific Nitrogen C++ sources - ../nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp ../nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp ../nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp ../nitrogen/generated/android/c++/JHybridOmniViewSpec.cpp diff --git a/nitrogen/generated/android/OmniOnLoad.cpp b/nitrogen/generated/android/OmniOnLoad.cpp index 422b421..c3be823 100644 --- a/nitrogen/generated/android/OmniOnLoad.cpp +++ b/nitrogen/generated/android/OmniOnLoad.cpp @@ -15,7 +15,6 @@ #include #include -#include "JHybridOmniPlayerPropsSpec.hpp" #include "JHybridOmniPlayerSpec.hpp" #include "JHybridOmniPlayerFactorySpec.hpp" #include "JHybridOmniViewSpec.hpp" @@ -52,7 +51,6 @@ void registerAllNatives() { using namespace margelo::nitro::omni; // Register native JNI methods - margelo::nitro::omni::JHybridOmniPlayerPropsSpec::CxxPart::registerNatives(); margelo::nitro::omni::JHybridOmniPlayerSpec::CxxPart::registerNatives(); margelo::nitro::omni::JHybridOmniPlayerFactorySpec::CxxPart::registerNatives(); margelo::nitro::omni::JHybridOmniViewSpec::CxxPart::registerNatives(); diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp index 85227e1..8e95bf1 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp @@ -9,14 +9,34 @@ // Forward declaration of `HybridOmniPlayerSpec` to properly resolve imports. namespace margelo::nitro::omni { class HybridOmniPlayerSpec; } -// Forward declaration of `HybridOmniPlayerPropsSpec` to properly resolve imports. -namespace margelo::nitro::omni { class HybridOmniPlayerPropsSpec; } +// Forward declaration of `Source` to properly resolve imports. +namespace margelo::nitro::omni { struct Source; } +// Forward declaration of `VideoSrc` to properly resolve imports. +namespace margelo::nitro::omni { struct VideoSrc; } +// Forward declaration of `Subtitle` to properly resolve imports. +namespace margelo::nitro::omni { struct Subtitle; } +// Forward declaration of `Metadata` to properly resolve imports. +namespace margelo::nitro::omni { struct Metadata; } +// Forward declaration of `MixAudioMode` to properly resolve imports. +namespace margelo::nitro::omni { enum class MixAudioMode; } #include #include "HybridOmniPlayerSpec.hpp" #include "JHybridOmniPlayerSpec.hpp" -#include "HybridOmniPlayerPropsSpec.hpp" -#include "JHybridOmniPlayerPropsSpec.hpp" +#include "Source.hpp" +#include "JSource.hpp" +#include "VideoSrc.hpp" +#include +#include "JVideoSrc.hpp" +#include +#include +#include +#include "Subtitle.hpp" +#include "JSubtitle.hpp" +#include "Metadata.hpp" +#include "JMetadata.hpp" +#include "MixAudioMode.hpp" +#include "JMixAudioMode.hpp" namespace margelo::nitro::omni { @@ -51,9 +71,9 @@ namespace margelo::nitro::omni { // Methods - std::shared_ptr JHybridOmniPlayerFactorySpec::createPlayer(const std::shared_ptr& props) { - static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* props */)>("createPlayer"); - auto __result = method(_javaPart, std::dynamic_pointer_cast(props)->getJavaPart()); + std::shared_ptr JHybridOmniPlayerFactorySpec::createPlayer(const Source& props) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* props */)>("createPlayer"); + auto __result = method(_javaPart, JSource::fromCpp(props)); return __result->getJHybridOmniPlayerSpec(); } diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp b/nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.hpp index c1761d1..35a0092 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 std::shared_ptr& props) override; + std::shared_ptr createPlayer(const Source& props) override; private: jni::global_ref _javaPart; diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp b/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp deleted file mode 100644 index 31dfd80..0000000 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/// -/// JHybridOmniPlayerPropsSpec.cpp -/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. -/// https://github.com/mrousavy/nitro -/// Copyright © Marc Rousavy @ Margelo -/// - -#include "JHybridOmniPlayerPropsSpec.hpp" - -// Forward declaration of `VideoSrc` to properly resolve imports. -namespace margelo::nitro::omni { struct VideoSrc; } -// Forward declaration of `Subtitle` to properly resolve imports. -namespace margelo::nitro::omni { struct Subtitle; } -// Forward declaration of `Metadata` to properly resolve imports. -namespace margelo::nitro::omni { struct Metadata; } -// Forward declaration of `MixAudioMode` to properly resolve imports. -namespace margelo::nitro::omni { enum class MixAudioMode; } - -#include "VideoSrc.hpp" -#include -#include "JVideoSrc.hpp" -#include -#include -#include -#include "Subtitle.hpp" -#include "JSubtitle.hpp" -#include "Metadata.hpp" -#include "JMetadata.hpp" -#include "MixAudioMode.hpp" -#include "JMixAudioMode.hpp" - -namespace margelo::nitro::omni { - - std::shared_ptr JHybridOmniPlayerPropsSpec::JavaPart::getJHybridOmniPlayerPropsSpec() { - auto hybridObject = JHybridObject::JavaPart::getJHybridObject(); - auto castHybridObject = std::dynamic_pointer_cast(hybridObject); - if (castHybridObject == nullptr) [[unlikely]] { - throw std::runtime_error("Failed to downcast JHybridObject to JHybridOmniPlayerPropsSpec!"); - } - return castHybridObject; - } - - jni::local_ref JHybridOmniPlayerPropsSpec::CxxPart::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); - } - - std::shared_ptr JHybridOmniPlayerPropsSpec::CxxPart::createHybridObject(const jni::local_ref& javaPart) { - auto castJavaPart = jni::dynamic_ref_cast(javaPart); - if (castJavaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridOmniPlayerPropsSpec::JavaPart!"); - } - return std::make_shared(castJavaPart); - } - - void JHybridOmniPlayerPropsSpec::CxxPart::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", JHybridOmniPlayerPropsSpec::CxxPart::initHybrid), - }); - } - - // Properties - std::vector JHybridOmniPlayerPropsSpec::getSrc() { - static const auto method = _javaPart->javaClassStatic()->getMethod>()>("getSrc"); - auto __result = method(_javaPart); - return [&]() { - size_t __size = __result->size(); - std::vector __vector; - __vector.reserve(__size); - for (size_t __i = 0; __i < __size; __i++) { - auto __element = __result->getElement(__i); - __vector.push_back(__element->toCpp()); - } - return __vector; - }(); - } - void JHybridOmniPlayerPropsSpec::setSrc(const std::vector& src) { - static const auto method = _javaPart->javaClassStatic()->getMethod> /* src */)>("setSrc"); - method(_javaPart, [&]() { - size_t __size = src.size(); - jni::local_ref> __array = jni::JArrayClass::newArray(__size); - for (size_t __i = 0; __i < __size; __i++) { - const auto& __element = src[__i]; - auto __elementJni = JVideoSrc::fromCpp(__element); - __array->setElement(__i, *__elementJni); - } - return __array; - }()); - } - std::optional JHybridOmniPlayerPropsSpec::getStartTime() { - static const auto method = _javaPart->javaClassStatic()->getMethod()>("getStartTime"); - auto __result = method(_javaPart); - return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt; - } - void JHybridOmniPlayerPropsSpec::setStartTime(std::optional startTime) { - static const auto method = _javaPart->javaClassStatic()->getMethod /* startTime */)>("setStartTime"); - method(_javaPart, startTime.has_value() ? jni::JDouble::valueOf(startTime.value()) : nullptr); - } - std::vector JHybridOmniPlayerPropsSpec::getSubtitles() { - static const auto method = _javaPart->javaClassStatic()->getMethod>()>("getSubtitles"); - auto __result = method(_javaPart); - return [&]() { - size_t __size = __result->size(); - std::vector __vector; - __vector.reserve(__size); - for (size_t __i = 0; __i < __size; __i++) { - auto __element = __result->getElement(__i); - __vector.push_back(__element->toCpp()); - } - return __vector; - }(); - } - void JHybridOmniPlayerPropsSpec::setSubtitles(const std::vector& subtitles) { - static const auto method = _javaPart->javaClassStatic()->getMethod> /* subtitles */)>("setSubtitles"); - method(_javaPart, [&]() { - size_t __size = subtitles.size(); - jni::local_ref> __array = jni::JArrayClass::newArray(__size); - for (size_t __i = 0; __i < __size; __i++) { - const auto& __element = subtitles[__i]; - auto __elementJni = JSubtitle::fromCpp(__element); - __array->setElement(__i, *__elementJni); - } - return __array; - }()); - } - std::optional JHybridOmniPlayerPropsSpec::getMetadata() { - static const auto method = _javaPart->javaClassStatic()->getMethod()>("getMetadata"); - auto __result = method(_javaPart); - return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt; - } - void JHybridOmniPlayerPropsSpec::setMetadata(const std::optional& metadata) { - static const auto method = _javaPart->javaClassStatic()->getMethod /* metadata */)>("setMetadata"); - method(_javaPart, metadata.has_value() ? JMetadata::fromCpp(metadata.value()) : nullptr); - } - std::optional JHybridOmniPlayerPropsSpec::getMixAudio() { - static const auto method = _javaPart->javaClassStatic()->getMethod()>("getMixAudio"); - auto __result = method(_javaPart); - return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt; - } - void JHybridOmniPlayerPropsSpec::setMixAudio(std::optional mixAudio) { - static const auto method = _javaPart->javaClassStatic()->getMethod /* mixAudio */)>("setMixAudio"); - method(_javaPart, mixAudio.has_value() ? JMixAudioMode::fromCpp(mixAudio.value()) : nullptr); - } - - // Methods - - -} // namespace margelo::nitro::omni diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.hpp b/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.hpp deleted file mode 100644 index 37fffa3..0000000 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/// -/// HybridOmniPlayerPropsSpec.hpp -/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. -/// https://github.com/mrousavy/nitro -/// Copyright © Marc Rousavy @ Margelo -/// - -#pragma once - -#include -#include -#include "HybridOmniPlayerPropsSpec.hpp" - - - - -namespace margelo::nitro::omni { - - using namespace facebook; - - class JHybridOmniPlayerPropsSpec: public virtual HybridOmniPlayerPropsSpec, public virtual JHybridObject { - public: - struct JavaPart: public jni::JavaClass { - static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/HybridOmniPlayerPropsSpec;"; - std::shared_ptr getJHybridOmniPlayerPropsSpec(); - }; - struct CxxPart: public jni::HybridClass { - static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/HybridOmniPlayerPropsSpec$CxxPart;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); - static void registerNatives(); - using HybridBase::HybridBase; - protected: - std::shared_ptr createHybridObject(const jni::local_ref& javaPart) override; - }; - - public: - explicit JHybridOmniPlayerPropsSpec(const jni::local_ref& javaPart): - HybridObject(HybridOmniPlayerPropsSpec::TAG), - JHybridObject(javaPart), - _javaPart(jni::make_global(javaPart)) {} - ~JHybridOmniPlayerPropsSpec() override { - // Hermes GC can destroy JS objects on a non-JNI Thread. - jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); - } - - public: - inline const jni::global_ref& getJavaPart() const noexcept { - return _javaPart; - } - - public: - // Properties - std::vector getSrc() override; - void setSrc(const std::vector& src) override; - std::optional getStartTime() override; - void setStartTime(std::optional startTime) override; - std::vector getSubtitles() override; - void setSubtitles(const std::vector& subtitles) override; - std::optional getMetadata() override; - void setMetadata(const std::optional& metadata) override; - std::optional getMixAudio() override; - void setMixAudio(std::optional mixAudio) override; - - public: - // Methods - - - private: - jni::global_ref _javaPart; - }; - -} // namespace margelo::nitro::omni diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp index b3531c8..327fbc0 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp @@ -7,6 +7,16 @@ #include "JHybridOmniPlayerSpec.hpp" +// Forward declaration of `Source` to properly resolve imports. +namespace margelo::nitro::omni { struct Source; } +// Forward declaration of `VideoSrc` to properly resolve imports. +namespace margelo::nitro::omni { struct VideoSrc; } +// Forward declaration of `Subtitle` to properly resolve imports. +namespace margelo::nitro::omni { struct Subtitle; } +// Forward declaration of `Metadata` to properly resolve imports. +namespace margelo::nitro::omni { struct Metadata; } +// Forward declaration of `MixAudioMode` to properly resolve imports. +namespace margelo::nitro::omni { enum class MixAudioMode; } // Forward declaration of `PlayerStatus` to properly resolve imports. namespace margelo::nitro::omni { enum class PlayerStatus; } // Forward declaration of `Track` to properly resolve imports. @@ -14,13 +24,24 @@ namespace margelo::nitro::omni { struct Track; } // Forward declaration of `Rendition` to properly resolve imports. namespace margelo::nitro::omni { struct Rendition; } +#include "Source.hpp" +#include "JSource.hpp" +#include "VideoSrc.hpp" +#include +#include "JVideoSrc.hpp" +#include +#include +#include +#include "Subtitle.hpp" +#include "JSubtitle.hpp" +#include "Metadata.hpp" +#include "JMetadata.hpp" +#include "MixAudioMode.hpp" +#include "JMixAudioMode.hpp" #include "PlayerStatus.hpp" #include "JPlayerStatus.hpp" #include "Track.hpp" -#include #include "JTrack.hpp" -#include -#include #include "Rendition.hpp" #include "JRendition.hpp" @@ -54,6 +75,15 @@ namespace margelo::nitro::omni { } // Properties + Source JHybridOmniPlayerSpec::getSource() { + static const auto method = _javaPart->javaClassStatic()->getMethod()>("getSource"); + auto __result = method(_javaPart); + return __result->toCpp(); + } + void JHybridOmniPlayerSpec::setSource(const Source& source) { + static const auto method = _javaPart->javaClassStatic()->getMethod /* source */)>("setSource"); + method(_javaPart, JSource::fromCpp(source)); + } bool JHybridOmniPlayerSpec::getHasPrev() { static const auto method = _javaPart->javaClassStatic()->getMethod("getHasPrev"); auto __result = method(_javaPart); diff --git a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp index b011212..a90a57b 100644 --- a/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp +++ b/nitrogen/generated/android/c++/JHybridOmniPlayerSpec.hpp @@ -50,6 +50,8 @@ namespace margelo::nitro::omni { public: // Properties + Source getSource() override; + void setSource(const Source& source) override; bool getHasPrev() override; bool getHasNext() override; PlayerStatus getStatus() override; diff --git a/nitrogen/generated/android/c++/JSource.hpp b/nitrogen/generated/android/c++/JSource.hpp new file mode 100644 index 0000000..4412f30 --- /dev/null +++ b/nitrogen/generated/android/c++/JSource.hpp @@ -0,0 +1,120 @@ +/// +/// JSource.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "Source.hpp" + +#include "JMetadata.hpp" +#include "JMixAudioMode.hpp" +#include "JSubtitle.hpp" +#include "JVideoSrc.hpp" +#include "Metadata.hpp" +#include "MixAudioMode.hpp" +#include "Subtitle.hpp" +#include "VideoSrc.hpp" +#include +#include +#include +#include + +namespace margelo::nitro::omni { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "Source" and the the Kotlin data class "Source". + */ + struct JSource final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/Source;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct Source by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + Source toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldSrc = clazz->getField>("src"); + jni::local_ref> src = this->getFieldValue(fieldSrc); + static const auto fieldStartTime = clazz->getField("startTime"); + jni::local_ref startTime = this->getFieldValue(fieldStartTime); + static const auto fieldSubtitles = clazz->getField>("subtitles"); + jni::local_ref> subtitles = this->getFieldValue(fieldSubtitles); + static const auto fieldMetadata = clazz->getField("metadata"); + jni::local_ref metadata = this->getFieldValue(fieldMetadata); + static const auto fieldMixAudio = clazz->getField("mixAudio"); + jni::local_ref mixAudio = this->getFieldValue(fieldMixAudio); + return Source( + [&]() { + size_t __size = src->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = src->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(), + startTime != nullptr ? std::make_optional(startTime->value()) : std::nullopt, + [&]() { + size_t __size = subtitles->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = subtitles->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(), + metadata != nullptr ? std::make_optional(metadata->toCpp()) : std::nullopt, + mixAudio != nullptr ? std::make_optional(mixAudio->toCpp()) : std::nullopt + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[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); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + [&]() { + size_t __size = value.src.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = value.src[__i]; + auto __elementJni = JVideoSrc::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(), + value.startTime.has_value() ? jni::JDouble::valueOf(value.startTime.value()) : nullptr, + [&]() { + size_t __size = value.subtitles.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = value.subtitles[__i]; + auto __elementJni = JSubtitle::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(), + value.metadata.has_value() ? JMetadata::fromCpp(value.metadata.value()) : nullptr, + value.mixAudio.has_value() ? JMixAudioMode::fromCpp(value.mixAudio.value()) : nullptr + ); + } + }; + +} // namespace margelo::nitro::omni 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 8f62d6c..6dd00ca 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: HybridOmniPlayerPropsSpec): 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/HybridOmniPlayerPropsSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerPropsSpec.kt deleted file mode 100644 index 043635e..0000000 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerPropsSpec.kt +++ /dev/null @@ -1,80 +0,0 @@ -/// -/// HybridOmniPlayerPropsSpec.kt -/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. -/// https://github.com/mrousavy/nitro -/// Copyright © Marc Rousavy @ Margelo -/// - -package com.margelo.nitro.omni - -import androidx.annotation.Keep -import com.facebook.jni.HybridData -import com.facebook.proguard.annotations.DoNotStrip -import com.margelo.nitro.core.HybridObject - -/** - * A Kotlin class representing the OmniPlayerProps HybridObject. - * Implement this abstract class to create Kotlin-based instances of OmniPlayerProps. - */ -@DoNotStrip -@Keep -@Suppress( - "KotlinJniMissingFunction", "unused", - "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", - "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" -) -abstract class HybridOmniPlayerPropsSpec: HybridObject() { - // Properties - @get:DoNotStrip - @get:Keep - @set:DoNotStrip - @set:Keep - abstract var src: Array - - @get:DoNotStrip - @get:Keep - @set:DoNotStrip - @set:Keep - abstract var startTime: Double? - - @get:DoNotStrip - @get:Keep - @set:DoNotStrip - @set:Keep - abstract var subtitles: Array - - @get:DoNotStrip - @get:Keep - @set:DoNotStrip - @set:Keep - abstract var metadata: Metadata? - - @get:DoNotStrip - @get:Keep - @set:DoNotStrip - @set:Keep - abstract var mixAudio: MixAudioMode? - - // Methods - - - // Default implementation of `HybridObject.toString()` - override fun toString(): String { - return "[HybridObject OmniPlayerProps]" - } - - // C++ backing class - @DoNotStrip - @Keep - protected open class CxxPart(javaPart: HybridOmniPlayerPropsSpec): HybridObject.CxxPart(javaPart) { - // C++ JHybridOmniPlayerPropsSpec::CxxPart::initHybrid(...) - external override fun initHybrid(): HybridData - } - override fun createCxxPart(): CxxPart { - return CxxPart(this) - } - - companion object { - protected const val TAG = "HybridOmniPlayerPropsSpec" - } -} 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 6f266bf..428a7c8 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/HybridOmniPlayerSpec.kt @@ -25,6 +25,12 @@ import com.margelo.nitro.core.HybridObject ) abstract class HybridOmniPlayerSpec: HybridObject() { // Properties + @get:DoNotStrip + @get:Keep + @set:DoNotStrip + @set:Keep + abstract var source: Source + @get:DoNotStrip @get:Keep abstract val hasPrev: Boolean diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt new file mode 100644 index 0000000..c8525c7 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/omni/Source.kt @@ -0,0 +1,50 @@ +/// +/// Source.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.omni + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the JavaScript object/struct "Source". + */ +@DoNotStrip +@Keep +data class Source( + @DoNotStrip + @Keep + val src: Array, + @DoNotStrip + @Keep + val startTime: Double?, + @DoNotStrip + @Keep + val subtitles: Array, + @DoNotStrip + @Keep + val metadata: Metadata?, + @DoNotStrip + @Keep + val mixAudio: MixAudioMode? +) { + /* primary constructor */ + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(src: Array, startTime: Double?, subtitles: Array, metadata: Metadata?, mixAudio: MixAudioMode?): Source { + return Source(src, startTime, subtitles, metadata, mixAudio) + } + } +} diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp b/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp index 3d13e63..e9a1fc4 100644 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp +++ b/nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.hpp @@ -15,12 +15,12 @@ // Forward declaration of `HybridOmniPlayerSpec` to properly resolve imports. namespace margelo::nitro::omni { class HybridOmniPlayerSpec; } -// Forward declaration of `HybridOmniPlayerPropsSpec` to properly resolve imports. -namespace margelo::nitro::omni { class HybridOmniPlayerPropsSpec; } +// Forward declaration of `Source` to properly resolve imports. +namespace margelo::nitro::omni { struct Source; } #include #include "HybridOmniPlayerSpec.hpp" -#include "HybridOmniPlayerPropsSpec.hpp" +#include "Source.hpp" namespace margelo::nitro::omni { @@ -53,7 +53,7 @@ namespace margelo::nitro::omni { public: // Methods - virtual std::shared_ptr createPlayer(const std::shared_ptr& props) = 0; + virtual std::shared_ptr createPlayer(const Source& props) = 0; protected: // Hybrid Setup diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp b/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp deleted file mode 100644 index 1b26368..0000000 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/// -/// HybridOmniPlayerPropsSpec.cpp -/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. -/// https://github.com/mrousavy/nitro -/// Copyright © Marc Rousavy @ Margelo -/// - -#include "HybridOmniPlayerPropsSpec.hpp" - -namespace margelo::nitro::omni { - - void HybridOmniPlayerPropsSpec::loadHybridMethods() { - // load base methods/properties - HybridObject::loadHybridMethods(); - // load custom methods/properties - registerHybrids(this, [](Prototype& prototype) { - prototype.registerHybridGetter("src", &HybridOmniPlayerPropsSpec::getSrc); - prototype.registerHybridSetter("src", &HybridOmniPlayerPropsSpec::setSrc); - prototype.registerHybridGetter("startTime", &HybridOmniPlayerPropsSpec::getStartTime); - prototype.registerHybridSetter("startTime", &HybridOmniPlayerPropsSpec::setStartTime); - prototype.registerHybridGetter("subtitles", &HybridOmniPlayerPropsSpec::getSubtitles); - prototype.registerHybridSetter("subtitles", &HybridOmniPlayerPropsSpec::setSubtitles); - prototype.registerHybridGetter("metadata", &HybridOmniPlayerPropsSpec::getMetadata); - prototype.registerHybridSetter("metadata", &HybridOmniPlayerPropsSpec::setMetadata); - prototype.registerHybridGetter("mixAudio", &HybridOmniPlayerPropsSpec::getMixAudio); - prototype.registerHybridSetter("mixAudio", &HybridOmniPlayerPropsSpec::setMixAudio); - }); - } - -} // namespace margelo::nitro::omni diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.hpp b/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.hpp deleted file mode 100644 index 42a8cb9..0000000 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/// -/// HybridOmniPlayerPropsSpec.hpp -/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. -/// https://github.com/mrousavy/nitro -/// Copyright © Marc Rousavy @ Margelo -/// - -#pragma once - -#if __has_include() -#include -#else -#error NitroModules cannot be found! Are you sure you installed NitroModules properly? -#endif - -// Forward declaration of `VideoSrc` to properly resolve imports. -namespace margelo::nitro::omni { struct VideoSrc; } -// Forward declaration of `Subtitle` to properly resolve imports. -namespace margelo::nitro::omni { struct Subtitle; } -// Forward declaration of `Metadata` to properly resolve imports. -namespace margelo::nitro::omni { struct Metadata; } -// Forward declaration of `MixAudioMode` to properly resolve imports. -namespace margelo::nitro::omni { enum class MixAudioMode; } - -#include "VideoSrc.hpp" -#include -#include -#include "Subtitle.hpp" -#include "Metadata.hpp" -#include "MixAudioMode.hpp" - -namespace margelo::nitro::omni { - - using namespace margelo::nitro; - - /** - * An abstract base class for `OmniPlayerProps` - * Inherit this class to create instances of `HybridOmniPlayerPropsSpec` in C++. - * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual. - * @example - * ```cpp - * class HybridOmniPlayerProps: public HybridOmniPlayerPropsSpec { - * public: - * HybridOmniPlayerProps(...): HybridObject(TAG) { ... } - * // ... - * }; - * ``` - */ - class HybridOmniPlayerPropsSpec: public virtual HybridObject { - public: - // Constructor - explicit HybridOmniPlayerPropsSpec(): HybridObject(TAG) { } - - // Destructor - ~HybridOmniPlayerPropsSpec() override = default; - - public: - // Properties - virtual std::vector getSrc() = 0; - virtual void setSrc(const std::vector& src) = 0; - virtual std::optional getStartTime() = 0; - virtual void setStartTime(std::optional startTime) = 0; - virtual std::vector getSubtitles() = 0; - virtual void setSubtitles(const std::vector& subtitles) = 0; - virtual std::optional getMetadata() = 0; - virtual void setMetadata(const std::optional& metadata) = 0; - virtual std::optional getMixAudio() = 0; - virtual void setMixAudio(std::optional mixAudio) = 0; - - public: - // Methods - - - protected: - // Hybrid Setup - void loadHybridMethods() override; - - protected: - // Tag for logging - static constexpr auto TAG = "OmniPlayerProps"; - }; - -} // namespace margelo::nitro::omni diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp index ad6cc41..719aed8 100644 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp +++ b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp @@ -14,6 +14,8 @@ namespace margelo::nitro::omni { HybridObject::loadHybridMethods(); // load custom methods/properties registerHybrids(this, [](Prototype& prototype) { + prototype.registerHybridGetter("source", &HybridOmniPlayerSpec::getSource); + prototype.registerHybridSetter("source", &HybridOmniPlayerSpec::setSource); prototype.registerHybridGetter("hasPrev", &HybridOmniPlayerSpec::getHasPrev); prototype.registerHybridGetter("hasNext", &HybridOmniPlayerSpec::getHasNext); prototype.registerHybridGetter("status", &HybridOmniPlayerSpec::getStatus); diff --git a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp index a635788..fcf20b6 100644 --- a/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp +++ b/nitrogen/generated/shared/c++/HybridOmniPlayerSpec.hpp @@ -13,6 +13,8 @@ #error NitroModules cannot be found! Are you sure you installed NitroModules properly? #endif +// Forward declaration of `Source` to properly resolve imports. +namespace margelo::nitro::omni { struct Source; } // Forward declaration of `PlayerStatus` to properly resolve imports. namespace margelo::nitro::omni { enum class PlayerStatus; } // Forward declaration of `Track` to properly resolve imports. @@ -20,6 +22,7 @@ namespace margelo::nitro::omni { struct Track; } // Forward declaration of `Rendition` to properly resolve imports. namespace margelo::nitro::omni { struct Rendition; } +#include "Source.hpp" #include "PlayerStatus.hpp" #include "Track.hpp" #include @@ -53,6 +56,8 @@ namespace margelo::nitro::omni { public: // Properties + virtual Source getSource() = 0; + virtual void setSource(const Source& source) = 0; virtual bool getHasPrev() = 0; virtual bool getHasNext() = 0; virtual PlayerStatus getStatus() = 0; diff --git a/nitrogen/generated/shared/c++/Source.hpp b/nitrogen/generated/shared/c++/Source.hpp new file mode 100644 index 0000000..d84af8b --- /dev/null +++ b/nitrogen/generated/shared/c++/Source.hpp @@ -0,0 +1,111 @@ +/// +/// Source.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `VideoSrc` to properly resolve imports. +namespace margelo::nitro::omni { struct VideoSrc; } +// Forward declaration of `Subtitle` to properly resolve imports. +namespace margelo::nitro::omni { struct Subtitle; } +// Forward declaration of `Metadata` to properly resolve imports. +namespace margelo::nitro::omni { struct Metadata; } +// Forward declaration of `MixAudioMode` to properly resolve imports. +namespace margelo::nitro::omni { enum class MixAudioMode; } + +#include "VideoSrc.hpp" +#include +#include +#include "Subtitle.hpp" +#include "Metadata.hpp" +#include "MixAudioMode.hpp" + +namespace margelo::nitro::omni { + + /** + * A struct which can be represented as a JavaScript object (Source). + */ + struct Source final { + public: + std::vector src SWIFT_PRIVATE; + std::optional startTime SWIFT_PRIVATE; + std::vector subtitles SWIFT_PRIVATE; + std::optional metadata SWIFT_PRIVATE; + std::optional mixAudio SWIFT_PRIVATE; + + public: + Source() = default; + explicit Source(std::vector src, std::optional startTime, std::vector subtitles, std::optional metadata, std::optional mixAudio): src(src), startTime(startTime), subtitles(subtitles), metadata(metadata), mixAudio(mixAudio) {} + + public: + friend bool operator==(const Source& lhs, const Source& rhs) = default; + }; + +} // namespace margelo::nitro::omni + +namespace margelo::nitro { + + // C++ Source <> JS Source (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::omni::Source fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::omni::Source( + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "src"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "startTime"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "subtitles"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mixAudio"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::omni::Source& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "src"), JSIConverter>::toJSI(runtime, arg.src)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "startTime"), JSIConverter>::toJSI(runtime, arg.startTime)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "subtitles"), JSIConverter>::toJSI(runtime, arg.subtitles)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "metadata"), JSIConverter>::toJSI(runtime, arg.metadata)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "mixAudio"), JSIConverter>::toJSI(runtime, arg.mixAudio)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "src")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "startTime")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "subtitles")))) 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; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/src/provider.tsx b/src/provider.tsx index 69f2442..2376308 100755 --- a/src/provider.tsx +++ b/src/provider.tsx @@ -1,10 +1,9 @@ -import { createContext, type ReactNode, useContext } from "react"; +import { createContext, type ReactNode, useContext, useEffect } from "react"; import { NitroModules } from "react-native-nitro-modules"; -import type { - OmniPlayerFactory, - OmniPlayerProps, -} from "./specs/omni-player.nitro"; +import type { OmniPlayerFactory } from "./specs/omni-player.nitro"; import type { OmniPlayer } from "./types/player"; +import type { Source } from "./types/source"; +import { useLazyRef } from "./utils/lazy-ref"; const ProviderFactory = NitroModules.createHybridObject( "OmniProviderFactory", @@ -14,10 +13,20 @@ const PlayerCtx = createContext(null!); export const OmniProvider = ({ children, - ...props -}: OmniPlayerProps & { children: ReactNode }) => { - const player = ProviderFactory.createPlayer(props); - return {children}; + source, +}: { + source: Source; + children: ReactNode; +}) => { + const player = useLazyRef(() => ProviderFactory.createPlayer(source)); + + useEffect(() => { + player.current.source = source; + }, [source]); + + return ( + {children} + ); }; export const usePlayer = () => { diff --git a/src/specs/omni-player.nitro.ts b/src/specs/omni-player.nitro.ts index 5c0aac0..09ec7b2 100644 --- a/src/specs/omni-player.nitro.ts +++ b/src/specs/omni-player.nitro.ts @@ -1,15 +1,11 @@ import type { HybridObject } from "react-native-nitro-modules"; import type { OmniPlayer as OmniPlayerT } from "../types/player"; -import type { OmniPlayerProps as OmniPlayerPropsT } from "../types/provider"; - -export interface OmniPlayerProps - extends HybridObject<{ android: "kotlin" }>, - OmniPlayerPropsT {} +import type { Source } from "../types/source"; export interface OmniPlayer extends HybridObject<{ android: "kotlin" }>, OmniPlayerT {} export interface OmniPlayerFactory extends HybridObject<{ android: "kotlin" }> { - createPlayer(props: OmniPlayerProps): OmniPlayer; + createPlayer(props: Source): OmniPlayer; } diff --git a/src/types/player.ts b/src/types/player.ts index d25d92e..27a173a 100644 --- a/src/types/player.ts +++ b/src/types/player.ts @@ -1,4 +1,8 @@ +import type { Source } from "./source"; + export interface OmniPlayer { + source: Source; + play(): void; pause(): void; seekBy(offset: number): void; diff --git a/src/types/provider.ts b/src/types/source.ts similarity index 95% rename from src/types/provider.ts rename to src/types/source.ts index 35703a2..426e9ee 100644 --- a/src/types/provider.ts +++ b/src/types/source.ts @@ -1,4 +1,4 @@ -export interface OmniPlayerProps { +export interface Source { src: VideoSrc[]; startTime?: number; subtitles: Subtitle[]; diff --git a/src/utils/lazy-ref.ts b/src/utils/lazy-ref.ts new file mode 100644 index 0000000..2eccacf --- /dev/null +++ b/src/utils/lazy-ref.ts @@ -0,0 +1,13 @@ +import { type RefObject, useRef } from "react"; + +const empty = Symbol("useLazyRef empty value"); + +export const useLazyRef = (init: () => T): RefObject => { + const resultRef = useRef(empty); + + if (resultRef.current === empty) { + resultRef.current = init(); + } + + return resultRef as RefObject; +};