Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/react-native/React/Fabric/RCTScheduler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ void schedulerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic>
// This delegate method is not currently used on iOS.
}

void schedulerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) override
{
// Does nothing.
// View transition snapshots are not currently implemented on iOS.
}

void schedulerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) override
{
// Does nothing.
// View transition snapshots are not currently implemented on iOS.
}

void schedulerDidClearPendingSnapshots() override
{
// Does nothing.
// View transition snapshots are not currently implemented on iOS.
}

private:
void *scheduler_;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,23 @@ void FabricUIManagerBinding::schedulerDidUpdateShadowTree(
// no-op
}

void FabricUIManagerBinding::schedulerDidCaptureViewSnapshot(
Tag tag,
SurfaceId surfaceId) {
// TODO: implement this
}

void FabricUIManagerBinding::schedulerDidSetViewSnapshot(
Tag sourceTag,
Tag targetTag,
SurfaceId surfaceId) {
// TODO: implement this
}

void FabricUIManagerBinding::schedulerDidClearPendingSnapshots() {
// TODO: implement this
}

void FabricUIManagerBinding::onAnimationStarted() {
auto mountingManager = getMountingManager("onAnimationStarted");
if (!mountingManager) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ class FabricUIManagerBinding : public jni::HybridClass<FabricUIManagerBinding>,

void schedulerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) override;

void schedulerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) override;

void schedulerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) override;

void schedulerDidClearPendingSnapshots() override;

void setPixelDensity(float pointScaleFactor);

void driveCxxAnimations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,20 @@ std::optional<jsi::Object> NativeViewTransition::getViewTransitionInstance(
return result;
}

jsi::Value NativeViewTransition::findPseudoElementShadowNodeByTag(
jsi::Runtime& rt,
double reactTag) {
auto& uiManager = UIManagerBinding::getBinding(rt)->getUIManager();
auto* viewTransitionDelegate = uiManager.getViewTransitionDelegate();
if (viewTransitionDelegate != nullptr) {
auto shadowNode = viewTransitionDelegate->findPseudoElementShadowNodeByTag(
static_cast<Tag>(reactTag));
if (shadowNode) {
return Bridging<std::shared_ptr<const ShadowNode>>::toJs(rt, shadowNode);
}
}

return jsi::Value::null();
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class NativeViewTransition : public NativeViewTransitionCxxSpec<NativeViewTransi

std::optional<jsi::Object>
getViewTransitionInstance(jsi::Runtime &rt, const std::string &name, const std::string &pseudo);

jsi::Value findPseudoElementShadowNodeByTag(jsi::Runtime &rt, double reactTag);
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ Scheduler::Scheduler(

// Initialize ViewTransitionModule
if (ReactNativeFeatureFlags::viewTransitionEnabled()) {
viewTransitionModule_ = std::make_unique<ViewTransitionModule>();
viewTransitionModule_->setUIManager(uiManager_.get());
uiManager_->setViewTransitionDelegate(viewTransitionModule_.get());
viewTransitionModule_ = std::make_shared<ViewTransitionModule>();
viewTransitionModule_->initialize(uiManager_.get(), viewTransitionModule_);
}

uiManager->registerMountHook(*eventPerformanceLogger_);
Expand Down Expand Up @@ -365,6 +364,27 @@ void Scheduler::uiManagerDidUpdateShadowTree(
}
}

void Scheduler::uiManagerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) {
if (delegate_ != nullptr) {
delegate_->schedulerDidCaptureViewSnapshot(tag, surfaceId);
}
}

void Scheduler::uiManagerDidSetViewSnapshot(
Tag sourceTag,
Tag targetTag,
SurfaceId surfaceId) {
if (delegate_ != nullptr) {
delegate_->schedulerDidSetViewSnapshot(sourceTag, targetTag, surfaceId);
}
}

void Scheduler::uiManagerDidClearPendingSnapshots() {
if (delegate_ != nullptr) {
delegate_->schedulerDidClearPendingSnapshots();
}
}

void Scheduler::uiManagerShouldAddEventListener(
std::shared_ptr<const EventListener> listener) {
addEventListener(listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class Scheduler final : public UIManagerDelegate {
bool blockNativeResponder) override;
void uiManagerShouldSynchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic &props) override;
void uiManagerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) override;
void uiManagerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) override;
void uiManagerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) override;
void uiManagerDidClearPendingSnapshots() override;
void uiManagerShouldAddEventListener(std::shared_ptr<const EventListener> listener) final;
void uiManagerShouldRemoveEventListener(const std::shared_ptr<const EventListener> &listener) final;
void uiManagerDidFinishReactCommit(const ShadowTree &shadowTree) override;
Expand Down Expand Up @@ -147,7 +150,7 @@ class Scheduler final : public UIManagerDelegate {

RuntimeScheduler *runtimeScheduler_{nullptr};

std::unique_ptr<ViewTransitionModule> viewTransitionModule_;
std::shared_ptr<ViewTransitionModule> viewTransitionModule_;

mutable std::shared_mutex onSurfaceStartCallbackMutex_;
OnSurfaceStartCallback onSurfaceStartCallback_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ class SchedulerDelegate {

virtual void schedulerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) = 0;

// View transition bitmap snapshot capture and application.
virtual void schedulerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) = 0;
virtual void schedulerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) = 0;
virtual void schedulerDidClearPendingSnapshots() = 0;

virtual ~SchedulerDelegate() noexcept = default;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,37 @@ jsi::Value UIManagerBinding::get(
});
}

if (methodName == "createViewTransitionInstance") {
auto paramCount = 2;
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[uiManager, methodName, paramCount](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
validateArgumentCount(runtime, methodName, paramCount, count);

auto transitionName = arguments[0].isString()
? stringFromValue(runtime, arguments[0])
: "";
auto pseudoElementTag = tagFromValue(arguments[1]);

if (!transitionName.empty()) {
auto* viewTransitionDelegate =
uiManager->getViewTransitionDelegate();
if (viewTransitionDelegate != nullptr) {
viewTransitionDelegate->createViewTransitionInstance(
transitionName, pseudoElementTag);
}
}

return jsi::Value::undefined();
});
}

if (methodName == "cancelViewTransitionName") {
auto paramCount = 2;
return jsi::Function::createFromHostFunction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ class UIManagerDelegate {
using OnSurfaceStartCallback = std::function<void(const ShadowTree &shadowTree)>;
virtual void uiManagerShouldSetOnSurfaceStartCallback(OnSurfaceStartCallback &&callback) = 0;

// View transition bitmap snapshot capture and application.
virtual void uiManagerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) = 0;
virtual void uiManagerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) = 0;
virtual void uiManagerDidClearPendingSnapshots() = 0;

virtual ~UIManagerDelegate() noexcept = default;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class UIManagerViewTransitionDelegate {
{
}

virtual void createViewTransitionInstance(const std::string & /*name*/, Tag /*pseudoElementTag*/) {}

virtual void cancelViewTransitionName(const ShadowNode &shadowNode, const std::string &name) {}

virtual void restoreViewTransitionName(const ShadowNode &shadowNode) {}
Expand Down Expand Up @@ -55,6 +57,16 @@ class UIManagerViewTransitionDelegate {
{
return std::nullopt;
}

// Similar to UIManager::findShadowNodeByTag, but searches all direct children
// of the root node (where pseudo-element nodes live) rather than just the
// first child. Pseudo-element nodes are appended as additional children of the
// root node, rather than inserted into the main React tree, to avoid
// disrupting the user-created component tree.
virtual std::shared_ptr<const ShadowNode> findPseudoElementShadowNodeByTag(Tag /*tag*/) const
{
return nullptr;
}
};

} // namespace facebook::react
Loading
Loading