From 207e25422246a96e994aa6bc51a4cab06dad60b8 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Wed, 15 Jan 2025 18:50:15 +0100 Subject: [PATCH] fix: Wrap in state --- .../src/views/ViewComponentShadowNode.ts | 22 ++++++++++++++++--- .../views/kotlin/KotlinHybridViewManager.ts | 2 +- .../nitro/image/views/TestViewManager.kt | 2 +- .../shared/c++/views/TestViewComponent.cpp | 8 +++++++ .../shared/c++/views/TestViewComponent.hpp | 14 +++++++++--- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/packages/nitrogen/src/views/ViewComponentShadowNode.ts b/packages/nitrogen/src/views/ViewComponentShadowNode.ts index fa486558..0e538a5a 100644 --- a/packages/nitrogen/src/views/ViewComponentShadowNode.ts +++ b/packages/nitrogen/src/views/ViewComponentShadowNode.ts @@ -73,6 +73,7 @@ ${createFileMetadataString(`${component}.hpp`)} #include "NitroDefines.hpp" #include "NitroHash.hpp" +#include #include #include #include @@ -92,7 +93,7 @@ namespace ${namespace} { /** * Props for the "${spec.name}" View. */ - class ${propsClassName}: public react::ViewProps { + class ${propsClassName} final: public react::ViewProps { public: explicit ${propsClassName}() = default; ${propsClassName}(const react::PropsParserContext& context, @@ -109,9 +110,16 @@ namespace ${namespace} { /** * State for the "${spec.name}" View. */ - class ${stateClassName} { + class ${stateClassName} final { public: explicit ${stateClassName}() = default; + + public: + void setProps(const ${propsClassName}& props) { _props = props; } + const std::optional<${propsClassName}>& getProps() const { return _props; } + + private: + std::optional<${propsClassName}> _props; }; /** @@ -125,7 +133,7 @@ namespace ${namespace} { /** * The Component Descriptor for the "${spec.name}" View. */ - class ${descriptorClassName}: public react::ConcreteComponentDescriptor<${shadowNodeClassName}> { + class ${descriptorClassName} final: public react::ConcreteComponentDescriptor<${shadowNodeClassName}> { public: ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters); @@ -189,8 +197,16 @@ namespace ${namespace} { void ${descriptorClassName}::adopt(react::ShadowNode& shadowNode) const { // This is called immediately after \`ShadowNode\` is created, cloned or in progress. +#ifdef ANDROID + // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++. auto& concreteShadowNode = static_cast<${shadowNodeClassName}&>(shadowNode); const ${propsClassName}& props = concreteShadowNode.getConcreteProps(); + ${stateClassName} state; + state.setProps(props); + concreteShadowNode.setStateData(std::move(state)); +#else + // On iOS, prop updating happens through the updateProps: Obj-C selector. +#endif } } // namespace ${namespace} diff --git a/packages/nitrogen/src/views/kotlin/KotlinHybridViewManager.ts b/packages/nitrogen/src/views/kotlin/KotlinHybridViewManager.ts index f279f714..1bf77a77 100644 --- a/packages/nitrogen/src/views/kotlin/KotlinHybridViewManager.ts +++ b/packages/nitrogen/src/views/kotlin/KotlinHybridViewManager.ts @@ -26,7 +26,7 @@ import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext -class ${manager} extends SimpleViewManager { +class ${manager}: SimpleViewManager() { override fun getName(): String { return "${spec.name}" } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/views/TestViewManager.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/views/TestViewManager.kt index 270353b5..9f2d03b8 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/views/TestViewManager.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/views/TestViewManager.kt @@ -14,7 +14,7 @@ import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext -class TestViewManager extends SimpleViewManager { +class TestViewManager: SimpleViewManager() { override fun getName(): String { return "TestView" } diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.cpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.cpp index d0cc41cb..cdc9a674 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.cpp @@ -45,8 +45,16 @@ namespace margelo::nitro::image::views { void HybridTestViewComponentDescriptor::adopt(react::ShadowNode& shadowNode) const { // This is called immediately after `ShadowNode` is created, cloned or in progress. +#ifdef ANDROID + // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++. auto& concreteShadowNode = static_cast(shadowNode); const HybridTestViewProps& props = concreteShadowNode.getConcreteProps(); + HybridTestViewState state; + state.setProps(props); + concreteShadowNode.setStateData(std::move(state)); +#else + // On iOS, prop updating happens through the updateProps: Obj-C selector. +#endif } } // namespace margelo::nitro::image::views diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.hpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.hpp index 24544a1e..a2ae8a35 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/views/TestViewComponent.hpp @@ -11,6 +11,7 @@ #include "NitroDefines.hpp" #include "NitroHash.hpp" +#include #include #include #include @@ -30,7 +31,7 @@ namespace margelo::nitro::image::views { /** * Props for the "TestView" View. */ - class HybridTestViewProps: public react::ViewProps { + class HybridTestViewProps final: public react::ViewProps { public: explicit HybridTestViewProps() = default; HybridTestViewProps(const react::PropsParserContext& context, @@ -48,9 +49,16 @@ namespace margelo::nitro::image::views { /** * State for the "TestView" View. */ - class HybridTestViewState { + class HybridTestViewState final { public: explicit HybridTestViewState() = default; + + public: + void setProps(const HybridTestViewProps& props) { _props = props; } + const std::optional& getProps() const { return _props; } + + private: + std::optional _props; }; /** @@ -64,7 +72,7 @@ namespace margelo::nitro::image::views { /** * The Component Descriptor for the "TestView" View. */ - class HybridTestViewComponentDescriptor: public react::ConcreteComponentDescriptor { + class HybridTestViewComponentDescriptor final: public react::ConcreteComponentDescriptor { public: HybridTestViewComponentDescriptor(const react::ComponentDescriptorParameters& parameters);