diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 16f4f81b0bd..6e198a0bfa2 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -539,6 +539,7 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu metrics.contentInset = RCTEdgeInsetsFromUIEdgeInsets(_scrollView.contentInset); metrics.containerSize = RCTSizeFromCGSize(_scrollView.bounds.size); metrics.zoomScale = _scrollView.zoomScale; + metrics.timestamp = CACurrentMediaTime(); if (_layoutMetrics.layoutDirection == LayoutDirection::RightToLeft) { metrics.contentOffset.x = metrics.contentSize.width - metrics.containerSize.width - metrics.contentOffset.x; diff --git a/packages/react-native/React/Views/ScrollView/RCTScrollEvent.m b/packages/react-native/React/Views/ScrollView/RCTScrollEvent.m index 944c64cdb40..36606078215 100644 --- a/packages/react-native/React/Views/ScrollView/RCTScrollEvent.m +++ b/packages/react-native/React/Views/ScrollView/RCTScrollEvent.m @@ -16,6 +16,7 @@ CGFloat _scrollViewZoomScale; NSDictionary *_userData; uint16_t _coalescingKey; + CFTimeInterval _timestamp; } @synthesize viewTag = _viewTag; @@ -43,6 +44,7 @@ _scrollViewZoomScale = scrollViewZoomScale; _userData = userData; _coalescingKey = coalescingKey; + _timestamp = CACurrentMediaTime(); } return self; } @@ -67,6 +69,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init) @"contentSize" : @{@"width" : @(_scrollViewContentSize.width), @"height" : @(_scrollViewContentSize.height)}, @"layoutMeasurement" : @{@"width" : @(_scrollViewFrame.size.width), @"height" : @(_scrollViewFrame.size.height)}, @"zoomScale" : @(_scrollViewZoomScale ?: 1), + @"timestamp" : @(_timestamp * 1000), }; if (_userData) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp index 95313a2e91f..08dadd11f95 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp @@ -43,6 +43,7 @@ jsi::Value ScrollEvent::asJSIValue(jsi::Runtime& runtime) const { } payload.setProperty(runtime, "zoomScale", zoomScale); + payload.setProperty(runtime, "timestamp", timestamp * 1000); return payload; } @@ -61,11 +62,12 @@ folly::dynamic ScrollEvent::asDynamic() const { auto containerSizeObj = folly::dynamic::object("width", containerSize.width)( "height", containerSize.height); - auto metrics = folly::dynamic::object( - "contentOffset", std::move(contentOffsetObj))( - "contentInset", std::move(contentInsetObj))( - "contentSize", std::move(contentSizeObj))( - "layoutMeasurement", std::move(containerSizeObj))("zoomScale", zoomScale); + auto metrics = + folly::dynamic::object("contentOffset", std::move(contentOffsetObj))( + "contentInset", std::move(contentInsetObj))( + "contentSize", std::move(contentSizeObj))( + "layoutMeasurement", std::move(containerSizeObj))( + "zoomScale", zoomScale)("timestamp", timestamp * 1000); return metrics; }; @@ -91,7 +93,7 @@ std::vector getDebugProps( {"layoutMeasurement", getDebugDescription(scrollEvent.layoutMeasurement, options)}, {"zoomScale", getDebugDescription(scrollEvent.zoomScale, options)}, - }; + {"timestamp", getDebugDescription(scrollEvent.timestamp, options)}}; } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h index 5a8ff342f3e..8eac9e879b5 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h @@ -21,6 +21,11 @@ struct ScrollEvent : public EventPayload { Size containerSize; Float zoomScale{}; + /* + * The time in seconds when the touch occurred or when it was last mutated. + */ + Float timestamp{}; + ScrollEvent() = default; folly::dynamic asDynamic() const;