@onekeyfe/react-native-skeleton 3.0.95 → 3.0.98

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.
Files changed (19) hide show
  1. package/android/src/main/java/com/margelo/nitro/skeleton/OneKeySkeletonRenderer.kt +173 -0
  2. package/android/src/main/java/com/margelo/nitro/skeleton/Skeleton.kt +63 -194
  3. package/ios/Skeleton.swift +58 -272
  4. package/ios/SkeletonRenderer.swift +146 -0
  5. package/lib/nitrogen/generated/android/c++/views/JHybridSkeletonStateUpdater.cpp +42 -23
  6. package/lib/nitrogen/generated/android/c++/views/JHybridSkeletonStateUpdater.hpp +6 -1
  7. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/skeleton/views/HybridSkeletonManager.kt +26 -10
  8. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/skeleton/views/HybridSkeletonStateUpdater.kt +2 -2
  9. package/lib/nitrogen/generated/ios/c++/views/HybridSkeletonComponent.mm +50 -27
  10. package/lib/nitrogen/generated/shared/c++/views/HybridSkeletonComponent.cpp +7 -65
  11. package/lib/nitrogen/generated/shared/c++/views/HybridSkeletonComponent.hpp +26 -50
  12. package/nitrogen/generated/android/c++/views/JHybridSkeletonStateUpdater.cpp +42 -23
  13. package/nitrogen/generated/android/c++/views/JHybridSkeletonStateUpdater.hpp +6 -1
  14. package/nitrogen/generated/android/kotlin/com/margelo/nitro/skeleton/views/HybridSkeletonManager.kt +26 -10
  15. package/nitrogen/generated/android/kotlin/com/margelo/nitro/skeleton/views/HybridSkeletonStateUpdater.kt +2 -2
  16. package/nitrogen/generated/ios/c++/views/HybridSkeletonComponent.mm +50 -27
  17. package/nitrogen/generated/shared/c++/views/HybridSkeletonComponent.cpp +7 -65
  18. package/nitrogen/generated/shared/c++/views/HybridSkeletonComponent.hpp +26 -50
  19. package/package.json +4 -4
@@ -37,6 +37,7 @@ using namespace margelo::nitro::skeleton::views;
37
37
 
38
38
  @implementation HybridSkeletonComponent {
39
39
  std::shared_ptr<HybridSkeletonSpecSwift> _hybridView;
40
+ BOOL _didDropView;
40
41
  }
41
42
 
42
43
  + (void) load {
@@ -50,6 +51,7 @@ using namespace margelo::nitro::skeleton::views;
50
51
 
51
52
  - (instancetype) init {
52
53
  if (self = [super init]) {
54
+ _props = HybridSkeletonShadowNode::defaultSharedProps();
53
55
  std::shared_ptr<HybridSkeletonSpec> hybridView = Skeleton::SkeletonAutolinking::createSkeleton();
54
56
  _hybridView = std::dynamic_pointer_cast<HybridSkeletonSpecSwift>(hybridView);
55
57
  [self updateView];
@@ -69,40 +71,61 @@ using namespace margelo::nitro::skeleton::views;
69
71
  [self setContentView:view];
70
72
  }
71
73
 
74
+ - (void) notifyOnDropView {
75
+ // A recycled component can later be invalidated. Notify only once per mount.
76
+ if (_didDropView) {
77
+ return;
78
+ }
79
+ Skeleton::HybridSkeletonSpec_cxx& swiftPart = _hybridView->getSwiftPart();
80
+ swiftPart.onDropView();
81
+ _didDropView = YES;
82
+ }
83
+
72
84
  - (void) updateProps:(const std::shared_ptr<const react::Props>&)props
73
85
  oldProps:(const std::shared_ptr<const react::Props>&)oldProps {
86
+ // A props update marks a newly mounted or still-active component.
87
+ _didDropView = NO;
88
+
74
89
  // 1. Downcast props
75
- const auto& newViewPropsConst = *std::static_pointer_cast<HybridSkeletonProps const>(props);
76
- auto& newViewProps = const_cast<HybridSkeletonProps&>(newViewPropsConst);
90
+ const auto& newViewProps = *std::static_pointer_cast<const HybridSkeletonProps>(props);
91
+ const auto* oldViewProps = static_cast<const HybridSkeletonProps*>(oldProps.get());
77
92
  Skeleton::HybridSkeletonSpec_cxx& swiftPart = _hybridView->getSwiftPart();
78
93
 
79
- // 2. Update each prop individually
80
- swiftPart.beforeUpdate();
81
-
82
- // shimmerSpeed: optional
83
- if (newViewProps.shimmerSpeed.isDirty) {
84
- swiftPart.setShimmerSpeed(newViewProps.shimmerSpeed.value);
85
- newViewProps.shimmerSpeed.isDirty = false;
86
- }
87
- // shimmerGradientColors: optional
88
- if (newViewProps.shimmerGradientColors.isDirty) {
89
- swiftPart.setShimmerGradientColors(newViewProps.shimmerGradientColors.value);
90
- newViewProps.shimmerGradientColors.isDirty = false;
91
- }
92
-
93
- swiftPart.afterUpdate();
94
+ // 2. Update only props that differ from the previous Props snapshot.
95
+ const bool hasTransactionPropChanges = oldViewProps == nullptr
96
+ ? newViewProps.hasAnyProvidedProps()
97
+ : !newViewProps.hasSameProps(*oldViewProps);
98
+ if (hasTransactionPropChanges) {
99
+ swiftPart.beforeUpdate();
100
+
101
+ // shimmerSpeed: optional
102
+ if (oldViewProps == nullptr
103
+ ? newViewProps.shimmerSpeed.isProvided()
104
+ : !newViewProps.shimmerSpeed.hasSameValue(oldViewProps->shimmerSpeed)) {
105
+ swiftPart.setShimmerSpeed(newViewProps.shimmerSpeed.get());
106
+ }
107
+ // shimmerGradientColors: optional
108
+ if (oldViewProps == nullptr
109
+ ? newViewProps.shimmerGradientColors.isProvided()
110
+ : !newViewProps.shimmerGradientColors.hasSameValue(oldViewProps->shimmerGradientColors)) {
111
+ swiftPart.setShimmerGradientColors(newViewProps.shimmerGradientColors.get());
112
+ }
94
113
 
95
- // 3. Update hybridRef if it changed
96
- if (newViewProps.hybridRef.isDirty) {
97
- // hybridRef changed - call it with new this
98
- const auto& maybeFunc = newViewProps.hybridRef.value;
99
- if (maybeFunc.has_value()) {
100
- maybeFunc.value()(_hybridView);
114
+ // Update hybridRef if it changed
115
+ if (oldViewProps == nullptr
116
+ ? newViewProps.hybridRef.isProvided()
117
+ : !newViewProps.hybridRef.hasSameValue(oldViewProps->hybridRef)) {
118
+ // hybridRef changed - call it with new this
119
+ const auto& maybeFunc = newViewProps.hybridRef.get();
120
+ if (maybeFunc.has_value()) {
121
+ maybeFunc.value()(_hybridView);
122
+ }
101
123
  }
102
- newViewProps.hybridRef.isDirty = false;
124
+
125
+ swiftPart.afterUpdate();
103
126
  }
104
127
 
105
- // 4. Continue in base class
128
+ // 3. Continue in base class
106
129
  [super updateProps:props oldProps:oldProps];
107
130
  }
108
131
 
@@ -111,6 +134,7 @@ using namespace margelo::nitro::skeleton::views;
111
134
  }
112
135
 
113
136
  - (void)prepareForRecycle {
137
+ [self notifyOnDropView];
114
138
  [super prepareForRecycle];
115
139
  Skeleton::HybridSkeletonSpec_cxx& swiftPart = _hybridView->getSwiftPart();
116
140
  swiftPart.maybePrepareForRecycle();
@@ -118,8 +142,7 @@ using namespace margelo::nitro::skeleton::views;
118
142
 
119
143
  #ifdef ENABLE_RCT_COMPONENT_VIEW_INVALIDATE
120
144
  - (void)invalidate {
121
- Skeleton::HybridSkeletonSpec_cxx& swiftPart = _hybridView->getSwiftPart();
122
- swiftPart.onDropView();
145
+ [self notifyOnDropView];
123
146
  [super invalidate];
124
147
  }
125
148
  #endif
@@ -7,55 +7,22 @@
7
7
 
8
8
  #include "HybridSkeletonComponent.hpp"
9
9
 
10
- #include <string>
11
- #include <exception>
12
- #include <utility>
13
- #include <NitroModules/NitroDefines.hpp>
14
- #include <NitroModules/JSIConverter.hpp>
15
- #include <NitroModules/PropNameIDCache.hpp>
16
- #include <react/renderer/core/RawValue.h>
17
- #include <react/renderer/core/ShadowNode.h>
18
- #include <react/renderer/core/ComponentDescriptor.h>
19
- #include <react/renderer/components/view/ViewProps.h>
10
+ #include <NitroModules/NitroHash.hpp>
11
+ #include <NitroModules/ReactProp.hpp>
20
12
 
21
13
  namespace margelo::nitro::skeleton::views {
22
14
 
15
+ using namespace facebook;
16
+
23
17
  extern const char HybridSkeletonComponentName[] = "Skeleton";
24
18
 
25
19
  HybridSkeletonProps::HybridSkeletonProps(const react::PropsParserContext& context,
26
20
  const HybridSkeletonProps& sourceProps,
27
21
  const react::RawProps& rawProps):
28
22
  react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
29
- shimmerSpeed([&]() -> CachedProp<std::optional<double>> {
30
- try {
31
- const react::RawValue* rawValue = rawProps.at("shimmerSpeed", nullptr, nullptr);
32
- if (rawValue == nullptr) return sourceProps.shimmerSpeed;
33
- const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
34
- return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.shimmerSpeed);
35
- } catch (const std::exception& exc) {
36
- throw std::runtime_error(std::string("Skeleton.shimmerSpeed: ") + exc.what());
37
- }
38
- }()),
39
- shimmerGradientColors([&]() -> CachedProp<std::optional<std::vector<std::string>>> {
40
- try {
41
- const react::RawValue* rawValue = rawProps.at("shimmerGradientColors", nullptr, nullptr);
42
- if (rawValue == nullptr) return sourceProps.shimmerGradientColors;
43
- const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
44
- return CachedProp<std::optional<std::vector<std::string>>>::fromRawValue(*runtime, value, sourceProps.shimmerGradientColors);
45
- } catch (const std::exception& exc) {
46
- throw std::runtime_error(std::string("Skeleton.shimmerGradientColors: ") + exc.what());
47
- }
48
- }()),
49
- hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridSkeletonSpec>& /* ref */)>>> {
50
- try {
51
- const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
52
- if (rawValue == nullptr) return sourceProps.hybridRef;
53
- const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
54
- return CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridSkeletonSpec>& /* ref */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f")), sourceProps.hybridRef);
55
- } catch (const std::exception& exc) {
56
- throw std::runtime_error(std::string("Skeleton.hybridRef: ") + exc.what());
57
- }
58
- }()) { }
23
+ shimmerSpeed(nitro::ReactProp<std::optional<double>>::fromRawValue("Skeleton", "shimmerSpeed", rawProps, sourceProps.shimmerSpeed)),
24
+ shimmerGradientColors(nitro::ReactProp<std::optional<std::vector<std::string>>>::fromRawValue("Skeleton", "shimmerGradientColors", rawProps, sourceProps.shimmerGradientColors)),
25
+ hybridRef(nitro::ReactProp<std::optional<std::function<void(const std::shared_ptr<HybridSkeletonSpec>& /* ref */)>>>::fromRawValue("Skeleton", "hybridRef", rawProps, sourceProps.hybridRef)) { }
59
26
 
60
27
  bool HybridSkeletonProps::filterObjectKeys(const std::string& propName) {
61
28
  switch (hashString(propName)) {
@@ -66,29 +33,4 @@ namespace margelo::nitro::skeleton::views {
66
33
  }
67
34
  }
68
35
 
69
- HybridSkeletonComponentDescriptor::HybridSkeletonComponentDescriptor(const react::ComponentDescriptorParameters& parameters)
70
- : ConcreteComponentDescriptor(parameters,
71
- react::RawPropsParser()) {}
72
-
73
- std::shared_ptr<const react::Props> HybridSkeletonComponentDescriptor::cloneProps(const react::PropsParserContext& context,
74
- const std::shared_ptr<const react::Props>& props,
75
- react::RawProps rawProps) const {
76
- // 1. Prepare raw props parser
77
- rawProps.parse(rawPropsParser_);
78
- // 2. Copy props with Nitro's cached copy constructor
79
- return HybridSkeletonShadowNode::Props(context, /* & */ rawProps, props);
80
- }
81
-
82
- #ifdef ANDROID
83
- void HybridSkeletonComponentDescriptor::adopt(react::ShadowNode& shadowNode) const {
84
- // This is called immediately after `ShadowNode` is created, cloned or in progress.
85
- // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
86
- auto& concreteShadowNode = static_cast<HybridSkeletonShadowNode&>(shadowNode);
87
- const std::shared_ptr<const HybridSkeletonProps>& constProps = concreteShadowNode.getConcreteSharedProps();
88
- const std::shared_ptr<HybridSkeletonProps>& props = std::const_pointer_cast<HybridSkeletonProps>(constProps);
89
- HybridSkeletonState state{props};
90
- concreteShadowNode.setStateData(std::move(state));
91
- }
92
- #endif
93
-
94
36
  } // namespace margelo::nitro::skeleton::views
@@ -7,14 +7,15 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include <optional>
11
- #include <NitroModules/NitroDefines.hpp>
12
- #include <NitroModules/NitroHash.hpp>
13
- #include <NitroModules/CachedProp.hpp>
14
- #include <react/renderer/core/ConcreteComponentDescriptor.h>
15
- #include <react/renderer/core/PropsParserContext.h>
10
+ #include <NitroModules/ReactProp.hpp>
11
+ #include <NitroModules/ViewComponentDescriptor.hpp>
12
+ #include <NitroModules/ViewPropsHolderState.hpp>
16
13
  #include <react/renderer/components/view/ConcreteViewShadowNode.h>
17
14
  #include <react/renderer/components/view/ViewProps.h>
15
+ #include <react/renderer/core/PropsParserContext.h>
16
+ #include <react/renderer/core/RawProps.h>
17
+
18
+ #include <string>
18
19
 
19
20
  #include <optional>
20
21
  #include <string>
@@ -43,9 +44,23 @@ namespace margelo::nitro::skeleton::views {
43
44
  const react::RawProps& rawProps);
44
45
 
45
46
  public:
46
- CachedProp<std::optional<double>> shimmerSpeed;
47
- CachedProp<std::optional<std::vector<std::string>>> shimmerGradientColors;
48
- CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridSkeletonSpec>& /* ref */)>>> hybridRef;
47
+ nitro::ReactProp<std::optional<double>> shimmerSpeed;
48
+ nitro::ReactProp<std::optional<std::vector<std::string>>> shimmerGradientColors;
49
+ nitro::ReactProp<std::optional<std::function<void(const std::shared_ptr<HybridSkeletonSpec>& /* ref */)>>> hybridRef;
50
+
51
+ [[nodiscard]]
52
+ bool hasSameProps(const HybridSkeletonProps& other) const noexcept {
53
+ return shimmerSpeed.hasSameValue(other.shimmerSpeed) &&
54
+ shimmerGradientColors.hasSameValue(other.shimmerGradientColors) &&
55
+ hybridRef.hasSameValue(other.hybridRef);
56
+ }
57
+
58
+ [[nodiscard]]
59
+ bool hasAnyProvidedProps() const noexcept {
60
+ return shimmerSpeed.isProvided() ||
61
+ shimmerGradientColors.isProvided() ||
62
+ hybridRef.isProvided();
63
+ }
49
64
 
50
65
  private:
51
66
  static bool filterObjectKeys(const std::string& propName);
@@ -54,32 +69,7 @@ namespace margelo::nitro::skeleton::views {
54
69
  /**
55
70
  * State for the "Skeleton" View.
56
71
  */
57
- class HybridSkeletonState final {
58
- public:
59
- HybridSkeletonState() = default;
60
- explicit HybridSkeletonState(const std::shared_ptr<HybridSkeletonProps>& props):
61
- _props(props) {}
62
-
63
- public:
64
- [[nodiscard]]
65
- const std::shared_ptr<HybridSkeletonProps>& getProps() const {
66
- return _props;
67
- }
68
-
69
- public:
70
- #ifdef ANDROID
71
- HybridSkeletonState(const HybridSkeletonState& /* previousState */, folly::dynamic /* data */) {}
72
- folly::dynamic getDynamic() const {
73
- throw std::runtime_error("HybridSkeletonState does not support folly!");
74
- }
75
- react::MapBuffer getMapBuffer() const {
76
- throw std::runtime_error("HybridSkeletonState does not support MapBuffer!");
77
- };
78
- #endif
79
-
80
- private:
81
- std::shared_ptr<HybridSkeletonProps> _props;
82
- };
72
+ using HybridSkeletonState = nitro::ViewPropsHolderState<HybridSkeletonProps>;
83
73
 
84
74
  /**
85
75
  * The Shadow Node for the "Skeleton" View.
@@ -92,21 +82,7 @@ namespace margelo::nitro::skeleton::views {
92
82
  /**
93
83
  * The Component Descriptor for the "Skeleton" View.
94
84
  */
95
- class HybridSkeletonComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridSkeletonShadowNode> {
96
- public:
97
- explicit HybridSkeletonComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
98
-
99
- public:
100
- /**
101
- * A faster path for cloning props - reuses the caching logic from `HybridSkeletonProps`.
102
- */
103
- std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
104
- const std::shared_ptr<const react::Props>& props,
105
- react::RawProps rawProps) const override;
106
- #ifdef ANDROID
107
- void adopt(react::ShadowNode& shadowNode) const override;
108
- #endif
109
- };
85
+ using HybridSkeletonComponentDescriptor = nitro::ViewComponentDescriptor<HybridSkeletonShadowNode>;
110
86
 
111
87
  /* The actual view for "Skeleton" needs to be implemented in platform-specific code. */
112
88
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-skeleton",
3
- "version": "3.0.95",
3
+ "version": "3.0.98",
4
4
  "description": "react-native-skeleton",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -78,12 +78,12 @@
78
78
  "eslint-plugin-prettier": "^5.5.4",
79
79
  "jest": "^29.7.0",
80
80
  "lefthook": "^2.0.3",
81
- "nitrogen": "0.36.5",
81
+ "nitrogen": "0.37.0",
82
82
  "prettier": "^2.8.8",
83
83
  "react": "19.2.3",
84
84
  "react-native": "patch:react-native@npm%3A0.86.2#~/.yarn/patches/react-native-npm-0.86.2-c9d546616f.patch",
85
85
  "react-native-builder-bob": "^0.40.13",
86
- "react-native-nitro-modules": "0.36.5",
86
+ "react-native-nitro-modules": "0.37.0",
87
87
  "release-it": "^19.0.4",
88
88
  "turbo": "^2.5.6",
89
89
  "typescript": "^5.9.2"
@@ -91,7 +91,7 @@
91
91
  "peerDependencies": {
92
92
  "react": "*",
93
93
  "react-native": "*",
94
- "react-native-nitro-modules": "0.36.5"
94
+ "react-native-nitro-modules": "0.37.0"
95
95
  },
96
96
  "packageManager": "yarn@4.11.0",
97
97
  "react-native-builder-bob": {