feat: use codegenNativeComponent to import native views (#1847)

Changed `requireNativeComponent` to `codegenNativeComponent` so that upcoming changes (Static View Configs, Bridgeless Mode and idk what more) in `react-native` are available in the library. Also, types and native components are now taken directly from `fabric` folder to make sure the values passed to the native components are the ones defined in props. It should work on all supported versions since `codegenNativeComponent` function exists from RN v. 0.61.0. Suggested by @RSNara and @cipolleschi

Reason for [`5394bbb` (#1847)](5394bbbced): 
- on `Paper`, `Animated` uses `setNativeProps` method when we set `useNativeDriver`  to `false`, and does not rerender the component. Therefore, new transform lands only in `SvgView` and is parsed in `RCTViewManager.m` .
- on `Fabric`, the same code makes the components rerender. Due to this, information about new transform is passed to the `SvgView` child: `G` , making it apply translations from the transform in its `updateProps` method.
- other than `Animated` use-case, on both archs, if we just passed `transform` prop to `Svg` component, it would end up in double transformations now as well. All of those changes are due to https://github.com/software-mansion/react-native-svg/pull/1895, which added proper parsing of RN style `transform` prop (array of transformations objects) therefore making `G` properly handle `transform` prop passed from `Svg`.

Reason for [`19bcb24` (#1847)](19bcb2464b): Same as https://github.com/software-mansion/react-native-screens/pull/1624
This commit is contained in:
Wojciech Lewicki
2022-11-03 15:47:29 +01:00
committed by GitHub
parent 079d069c16
commit 1126079425
82 changed files with 4270 additions and 3218 deletions

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/imagemanager/ImageManager.h>
#include <react/utils/ContextContainer.h>
#include "RNSVGImageShadowNode.h"
namespace facebook {
namespace react {
/*
* Descriptor for <RNSVGImage> component.
*/
class RNSVGImageComponentDescriptor final
: public ConcreteComponentDescriptor<RNSVGImageShadowNode> {
public:
RNSVGImageComponentDescriptor(ComponentDescriptorParameters const &parameters)
: ConcreteComponentDescriptor(parameters),
imageManager_(std::make_shared<ImageManager>(contextContainer_)){};
void adopt(ShadowNode::Unshared const &shadowNode) const override {
ConcreteComponentDescriptor::adopt(shadowNode);
auto imageShadowNode =
std::static_pointer_cast<RNSVGImageShadowNode>(shadowNode);
// `RNSVGImageShadowNode` uses `ImageManager` to initiate image loading and
// communicate the loading state and results to mounting layer.
imageShadowNode->setImageManager(imageManager_);
}
private:
const SharedImageManager imageManager_;
};
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <cstdlib>
#include <limits>
#include <react/renderer/core/LayoutContext.h>
#include "RNSVGImageShadowNode.h"
namespace facebook {
namespace react {
const char RNSVGImageComponentName[] = "RNSVGImage";
void RNSVGImageShadowNode::setImageManager(
const SharedImageManager &imageManager) {
ensureUnsealed();
imageManager_ = imageManager;
}
ImageSource RNSVGImageShadowNode::getImageSource() const {
auto source = getConcreteProps().src;
auto layoutMetrics = getLayoutMetrics();
auto size = layoutMetrics.getContentFrame().size;
auto scale = layoutMetrics.pointScaleFactor;
source.size = size;
source.scale = scale;
return source;
}
void RNSVGImageShadowNode::updateStateIfNeeded() {
ensureUnsealed();
auto imageSource = getImageSource();
auto const &currentState = getStateData();
bool hasSameImageSource = currentState.getImageSource() == imageSource;
if (hasSameImageSource) {
return;
}
auto state = RNSVGImageState{
imageSource,
imageManager_->requestImage(imageSource, getSurfaceId()),
};
setStateData(std::move(state));
}
#pragma mark - LayoutableShadowNode
void RNSVGImageShadowNode::layout(LayoutContext layoutContext) {
updateStateIfNeeded();
ConcreteViewShadowNode::layout(layoutContext);
}
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <jsi/jsi.h>
#include <react/renderer/components/rnsvg/EventEmitters.h>
#include <react/renderer/components/rnsvg/Props.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/imagemanager/ImageManager.h>
#include <react/renderer/imagemanager/primitives.h>
#include "RNSVGImageState.h"
namespace facebook {
namespace react {
JSI_EXPORT extern const char RNSVGImageComponentName[];
/*
* `ShadowNode` for <RNSVGImage> component.
*/
class JSI_EXPORT RNSVGImageShadowNode final : public ConcreteViewShadowNode<
RNSVGImageComponentName,
RNSVGImageProps,
ViewEventEmitter,
RNSVGImageState> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
static ShadowNodeTraits BaseTraits() {
auto traits = ConcreteViewShadowNode::BaseTraits();
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
return traits;
}
/*
* Associates a shared `ImageManager` with the node.
*/
void setImageManager(const SharedImageManager &imageManager);
static RNSVGImageState initialStateData(
ShadowNodeFragment const &fragment,
ShadowNodeFamilyFragment const &familyFragment,
ComponentDescriptor const &componentDescriptor) {
auto imageSource = ImageSource{ImageSource::Type::Invalid};
return {imageSource, {imageSource, nullptr}};
}
#pragma mark - LayoutableShadowNode
void layout(LayoutContext layoutContext) override;
private:
ImageSource getImageSource() const;
SharedImageManager imageManager_;
void updateStateIfNeeded();
};
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "RNSVGImageState.h"
namespace facebook {
namespace react {
ImageSource RNSVGImageState::getImageSource() const {
return imageSource_;
}
ImageRequest const &RNSVGImageState::getImageRequest() const {
return *imageRequest_;
}
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <jsi/jsi.h>
#include <react/renderer/imagemanager/ImageRequest.h>
#include <react/renderer/imagemanager/primitives.h>
#ifdef ANDROID
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif
namespace facebook {
namespace react {
/*
* State for <Image> component.
*/
class JSI_EXPORT RNSVGImageState final {
public:
RNSVGImageState(ImageSource const &imageSource, ImageRequest imageRequest)
: imageSource_(imageSource),
imageRequest_(
std::make_shared<ImageRequest>(std::move(imageRequest))){};
/*
* Returns stored ImageSource object.
*/
ImageSource getImageSource() const;
/*
* Exposes for reading stored `ImageRequest` object.
* `ImageRequest` object cannot be copied or moved from `ImageLocalData`.
*/
ImageRequest const &getImageRequest() const;
#ifdef ANDROID
RNSVGImageState(RNSVGImageState const &previousState, folly::dynamic data){};
/*
* Empty implementation for Android because it doesn't use this class.
*/
folly::dynamic getDynamic() const {
return {};
};
MapBuffer getMapBuffer() const {
return MapBufferBuilder::EMPTY();
};
#endif
private:
ImageSource imageSource_;
std::shared_ptr<ImageRequest> imageRequest_;
};
} // namespace react
} // namespace facebook