From 3ef1fac749c46e4a4afc865c7a612d8fcaab6318 Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Wed, 3 Apr 2024 09:05:32 -0700 Subject: [PATCH] Kotlinify ScrollEvent (#43779) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43779 ## Changelog: [Internal] - As in the title. Reviewed By: cortinico Differential Revision: D55641002 fbshipit-source-id: 093fa2f1efbdf2b66593a485cac7e62af7ac69ee --- .../ReactAndroid/api/ReactAndroid.api | 13 +- .../react/views/scroll/ScrollEvent.java | 183 ------------------ .../react/views/scroll/ScrollEvent.kt | 163 ++++++++++++++++ 3 files changed, 172 insertions(+), 187 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 4500e16bb86..80908ef16fa 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6688,15 +6688,20 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager$$PropsSetter public fun setProperty (Lcom/facebook/react/views/scroll/ReactScrollViewManager;Lcom/facebook/react/views/scroll/ReactScrollView;Ljava/lang/String;Ljava/lang/Object;)V } -public class com/facebook/react/views/scroll/ScrollEvent : com/facebook/react/uimanager/events/Event { +public final class com/facebook/react/views/scroll/ScrollEvent : com/facebook/react/uimanager/events/Event { + public static final field Companion Lcom/facebook/react/views/scroll/ScrollEvent$Companion; public fun canCoalesce ()Z - protected fun getEventData ()Lcom/facebook/react/bridge/WritableMap; public fun getEventName ()Ljava/lang/String; - public static fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; - public static fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; + public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; + public static final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; public fun onDispose ()V } +public final class com/facebook/react/views/scroll/ScrollEvent$Companion { + public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; + public final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; +} + public final class com/facebook/react/views/scroll/ScrollEventType : java/lang/Enum { public static final field BEGIN_DRAG Lcom/facebook/react/views/scroll/ScrollEventType; public static final field END_DRAG Lcom/facebook/react/views/scroll/ScrollEventType; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java deleted file mode 100644 index 6818b3682b0..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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. - */ - -package com.facebook.react.views.scroll; - -import androidx.annotation.Nullable; -import androidx.core.util.Pools; -import com.facebook.infer.annotation.Assertions; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactSoftExceptionLogger; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.uimanager.PixelUtil; -import com.facebook.react.uimanager.common.ViewUtil; -import com.facebook.react.uimanager.events.Event; - -/** A event dispatched from a ScrollView scrolling. */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ScrollEvent extends Event { - private static String TAG = ScrollEvent.class.getSimpleName(); - - private static final Pools.SynchronizedPool EVENTS_POOL = - new Pools.SynchronizedPool<>(3); - - private float mScrollX; - private float mScrollY; - private float mXVelocity; - private float mYVelocity; - private int mContentWidth; - private int mContentHeight; - private int mScrollViewWidth; - private int mScrollViewHeight; - private @Nullable ScrollEventType mScrollEventType; - - @Deprecated - public static ScrollEvent obtain( - int viewTag, - ScrollEventType scrollEventType, - float scrollX, - float scrollY, - float xVelocity, - float yVelocity, - int contentWidth, - int contentHeight, - int scrollViewWidth, - int scrollViewHeight) { - return obtain( - ViewUtil.NO_SURFACE_ID, - viewTag, - scrollEventType, - scrollX, - scrollY, - xVelocity, - yVelocity, - contentWidth, - contentHeight, - scrollViewWidth, - scrollViewHeight); - } - - public static ScrollEvent obtain( - int surfaceId, - int viewTag, - ScrollEventType scrollEventType, - float scrollX, - float scrollY, - float xVelocity, - float yVelocity, - int contentWidth, - int contentHeight, - int scrollViewWidth, - int scrollViewHeight) { - ScrollEvent event = EVENTS_POOL.acquire(); - if (event == null) { - event = new ScrollEvent(); - } - event.init( - surfaceId, - viewTag, - scrollEventType, - scrollX, - scrollY, - xVelocity, - yVelocity, - contentWidth, - contentHeight, - scrollViewWidth, - scrollViewHeight); - return event; - } - - @Override - public void onDispose() { - try { - EVENTS_POOL.release(this); - } catch (IllegalStateException e) { - // This exception can be thrown when an event is double-released. - // This is a problem but won't cause user-visible impact, so it's okay to fail silently. - ReactSoftExceptionLogger.logSoftException(TAG, e); - } - } - - private ScrollEvent() {} - - private void init( - int surfaceId, - int viewTag, - ScrollEventType scrollEventType, - float scrollX, - float scrollY, - float xVelocity, - float yVelocity, - int contentWidth, - int contentHeight, - int scrollViewWidth, - int scrollViewHeight) { - super.init(surfaceId, viewTag); - mScrollEventType = scrollEventType; - mScrollX = scrollX; - mScrollY = scrollY; - mXVelocity = xVelocity; - mYVelocity = yVelocity; - mContentWidth = contentWidth; - mContentHeight = contentHeight; - mScrollViewWidth = scrollViewWidth; - mScrollViewHeight = scrollViewHeight; - } - - @Override - public String getEventName() { - return ScrollEventType.getJSEventName(Assertions.assertNotNull(mScrollEventType)); - } - - @Override - public boolean canCoalesce() { - // Only SCROLL events can be coalesced, all others can not be - if (mScrollEventType == ScrollEventType.SCROLL) { - return true; - } - return false; - } - - @Nullable - @Override - protected WritableMap getEventData() { - WritableMap contentInset = Arguments.createMap(); - contentInset.putDouble("top", 0); - contentInset.putDouble("bottom", 0); - contentInset.putDouble("left", 0); - contentInset.putDouble("right", 0); - - WritableMap contentOffset = Arguments.createMap(); - contentOffset.putDouble("x", PixelUtil.toDIPFromPixel(mScrollX)); - contentOffset.putDouble("y", PixelUtil.toDIPFromPixel(mScrollY)); - - WritableMap contentSize = Arguments.createMap(); - contentSize.putDouble("width", PixelUtil.toDIPFromPixel(mContentWidth)); - contentSize.putDouble("height", PixelUtil.toDIPFromPixel(mContentHeight)); - - WritableMap layoutMeasurement = Arguments.createMap(); - layoutMeasurement.putDouble("width", PixelUtil.toDIPFromPixel(mScrollViewWidth)); - layoutMeasurement.putDouble("height", PixelUtil.toDIPFromPixel(mScrollViewHeight)); - - WritableMap velocity = Arguments.createMap(); - velocity.putDouble("x", mXVelocity); - velocity.putDouble("y", mYVelocity); - - WritableMap event = Arguments.createMap(); - event.putMap("contentInset", contentInset); - event.putMap("contentOffset", contentOffset); - event.putMap("contentSize", contentSize); - event.putMap("layoutMeasurement", layoutMeasurement); - event.putMap("velocity", velocity); - - event.putInt("target", getViewTag()); - event.putBoolean("responderIgnoreScroll", true); - return event; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt new file mode 100644 index 00000000000..16870654908 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt @@ -0,0 +1,163 @@ +/* + * 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. + */ + +package com.facebook.react.views.scroll + +import androidx.core.util.Pools.SynchronizedPool +import com.facebook.infer.annotation.Assertions +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.ReactSoftExceptionLogger +import com.facebook.react.bridge.WritableMap +import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel +import com.facebook.react.uimanager.common.ViewUtil +import com.facebook.react.uimanager.events.Event + +/** A event dispatched from a ScrollView scrolling. */ +public class ScrollEvent private constructor() : Event() { + private var scrollX = 0f + private var scrollY = 0f + private var xVelocity = 0f + private var yVelocity = 0f + private var contentWidth = 0 + private var contentHeight = 0 + private var scrollViewWidth = 0 + private var scrollViewHeight = 0 + private var scrollEventType: ScrollEventType? = null + + override fun onDispose() { + try { + EVENTS_POOL.release(this) + } catch (e: IllegalStateException) { + // This exception can be thrown when an event is double-released. + // This is a problem but won't cause user-visible impact, so it's okay to fail silently. + ReactSoftExceptionLogger.logSoftException(TAG, e) + } + } + + private fun init( + surfaceId: Int, + viewTag: Int, + scrollEventType: ScrollEventType?, + scrollX: Float, + scrollY: Float, + xVelocity: Float, + yVelocity: Float, + contentWidth: Int, + contentHeight: Int, + scrollViewWidth: Int, + scrollViewHeight: Int + ) { + super.init(surfaceId, viewTag) + this.scrollEventType = scrollEventType + this.scrollX = scrollX + this.scrollY = scrollY + this.xVelocity = xVelocity + this.yVelocity = yVelocity + this.contentWidth = contentWidth + this.contentHeight = contentHeight + this.scrollViewWidth = scrollViewWidth + this.scrollViewHeight = scrollViewHeight + } + + override fun getEventName(): String = + ScrollEventType.getJSEventName(Assertions.assertNotNull(scrollEventType)) + + override fun canCoalesce(): Boolean = scrollEventType == ScrollEventType.SCROLL + + override fun getEventData(): WritableMap { + val contentInset = Arguments.createMap() + contentInset.putDouble("top", 0.0) + contentInset.putDouble("bottom", 0.0) + contentInset.putDouble("left", 0.0) + contentInset.putDouble("right", 0.0) + val contentOffset = Arguments.createMap() + contentOffset.putDouble("x", toDIPFromPixel(scrollX).toDouble()) + contentOffset.putDouble("y", toDIPFromPixel(scrollY).toDouble()) + val contentSize = Arguments.createMap() + contentSize.putDouble("width", toDIPFromPixel(contentWidth.toFloat()).toDouble()) + contentSize.putDouble("height", toDIPFromPixel(contentHeight.toFloat()).toDouble()) + val layoutMeasurement = Arguments.createMap() + layoutMeasurement.putDouble("width", toDIPFromPixel(scrollViewWidth.toFloat()).toDouble()) + layoutMeasurement.putDouble("height", toDIPFromPixel(scrollViewHeight.toFloat()).toDouble()) + val velocity = Arguments.createMap() + velocity.putDouble("x", xVelocity.toDouble()) + velocity.putDouble("y", yVelocity.toDouble()) + val event = Arguments.createMap() + event.putMap("contentInset", contentInset) + event.putMap("contentOffset", contentOffset) + event.putMap("contentSize", contentSize) + event.putMap("layoutMeasurement", layoutMeasurement) + event.putMap("velocity", velocity) + event.putInt("target", viewTag) + event.putBoolean("responderIgnoreScroll", true) + return event + } + + public companion object { + private val TAG = ScrollEvent::class.java.simpleName + private val EVENTS_POOL = SynchronizedPool(3) + + @JvmStatic + public fun obtain( + surfaceId: Int, + viewTag: Int, + scrollEventType: ScrollEventType?, + scrollX: Float, + scrollY: Float, + xVelocity: Float, + yVelocity: Float, + contentWidth: Int, + contentHeight: Int, + scrollViewWidth: Int, + scrollViewHeight: Int + ): ScrollEvent = + (EVENTS_POOL.acquire() ?: ScrollEvent()).apply { + init( + surfaceId, + viewTag, + scrollEventType, + scrollX, + scrollY, + xVelocity, + yVelocity, + contentWidth, + contentHeight, + scrollViewWidth, + scrollViewHeight) + } + + @Deprecated( + "Use the obtain version that explicitly takes surfaceId as an argument", + ReplaceWith( + "obtain(surfaceId, viewTag, scrollEventType, scrollX, scrollY, xVelocity, yVelocity, contentWidth, contentHeight, scrollViewWidth, scrollViewHeight)")) + @JvmStatic + public fun obtain( + viewTag: Int, + scrollEventType: ScrollEventType?, + scrollX: Float, + scrollY: Float, + xVelocity: Float, + yVelocity: Float, + contentWidth: Int, + contentHeight: Int, + scrollViewWidth: Int, + scrollViewHeight: Int + ): ScrollEvent = + obtain( + ViewUtil.NO_SURFACE_ID, + viewTag, + scrollEventType, + scrollX, + scrollY, + xVelocity, + yVelocity, + contentWidth, + contentHeight, + scrollViewWidth, + scrollViewHeight) + } +}