From 47f3e320456c5bb47daf2d18e99769b0e2dab474 Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Wed, 3 Apr 2024 07:45:05 -0700 Subject: [PATCH] Kotlinify ImageLoadEvent (#43778) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43778 ## Changelog: [Internal] - As in the title. Reviewed By: cortinico Differential Revision: D55640524 --- .../ReactAndroid/api/ReactAndroid.api | 26 ++- .../react/views/image/ImageLoadEvent.java | 176 ------------------ .../react/views/image/ImageLoadEvent.kt | 155 +++++++++++++++ 3 files changed, 173 insertions(+), 184 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index c0d2ec9e7c9015..8defb257abce7b 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -5988,28 +5988,38 @@ public abstract interface class com/facebook/react/views/image/GlobalImageLoadLi public abstract fun onLoadAttempt (Landroid/net/Uri;)V } -public class com/facebook/react/views/image/ImageLoadEvent : com/facebook/react/uimanager/events/Event { +public final class com/facebook/react/views/image/ImageLoadEvent : com/facebook/react/uimanager/events/Event { + public static final field Companion Lcom/facebook/react/views/image/ImageLoadEvent$Companion; public static final field ON_ERROR I public static final field ON_LOAD I public static final field ON_LOAD_END I public static final field ON_LOAD_START I public static final field ON_PROGRESS I + public synthetic fun (IIILjava/lang/String;Ljava/lang/String;IIIILkotlin/jvm/internal/DefaultConstructorMarker;)V public static final fun createErrorEvent (IILjava/lang/Throwable;)Lcom/facebook/react/views/image/ImageLoadEvent; - public static final fun createErrorEvent (ILjava/lang/Throwable;)Lcom/facebook/react/views/image/ImageLoadEvent; - public static final fun createLoadEndEvent (I)Lcom/facebook/react/views/image/ImageLoadEvent; public static final fun createLoadEndEvent (II)Lcom/facebook/react/views/image/ImageLoadEvent; public static final fun createLoadEvent (IILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; - public static final fun createLoadEvent (ILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; - public static final fun createLoadStartEvent (I)Lcom/facebook/react/views/image/ImageLoadEvent; public static final fun createLoadStartEvent (II)Lcom/facebook/react/views/image/ImageLoadEvent; public static final fun createProgressEvent (IILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; - public static final fun createProgressEvent (ILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; - public static fun eventNameForType (I)Ljava/lang/String; + public static final fun eventNameForType (I)Ljava/lang/String; public fun getCoalescingKey ()S - protected fun getEventData ()Lcom/facebook/react/bridge/WritableMap; public fun getEventName ()Ljava/lang/String; } +public final class com/facebook/react/views/image/ImageLoadEvent$Companion { + public final fun createErrorEvent (IILjava/lang/Throwable;)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createErrorEvent (ILjava/lang/Throwable;)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadEndEvent (I)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadEndEvent (II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadEvent (IILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadEvent (ILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadStartEvent (I)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createLoadStartEvent (II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createProgressEvent (IILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun createProgressEvent (ILjava/lang/String;II)Lcom/facebook/react/views/image/ImageLoadEvent; + public final fun eventNameForType (I)Ljava/lang/String; +} + public final class com/facebook/react/views/image/ImageResizeMethod : java/lang/Enum { public static final field AUTO Lcom/facebook/react/views/image/ImageResizeMethod; public static final field RESIZE Lcom/facebook/react/views/image/ImageResizeMethod; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.java deleted file mode 100644 index 23da7501bdb9f8..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.java +++ /dev/null @@ -1,176 +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.image; - -import androidx.annotation.IntDef; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.uimanager.common.ViewUtil; -import com.facebook.react.uimanager.events.Event; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ImageLoadEvent extends Event { - @IntDef({ON_ERROR, ON_LOAD, ON_LOAD_END, ON_LOAD_START, ON_PROGRESS}) - @Retention(RetentionPolicy.SOURCE) - @interface ImageEventType {} - - public static final int ON_ERROR = 1; - public static final int ON_LOAD = 2; - public static final int ON_LOAD_END = 3; - public static final int ON_LOAD_START = 4; - public static final int ON_PROGRESS = 5; - - private final int mEventType; - private final @Nullable String mErrorMessage; - private final @Nullable String mSourceUri; - private final int mWidth; - private final int mHeight; - private final int mLoaded; - private final int mTotal; - - @Deprecated - public static final ImageLoadEvent createLoadStartEvent(int viewId) { - return createLoadStartEvent(ViewUtil.NO_SURFACE_ID, viewId); - } - - @Deprecated - public static final ImageLoadEvent createProgressEvent( - int viewId, @Nullable String imageUri, int loaded, int total) { - return createProgressEvent(ViewUtil.NO_SURFACE_ID, viewId, imageUri, loaded, total); - } - - @Deprecated - public static final ImageLoadEvent createLoadEvent( - int viewId, @Nullable String imageUri, int width, int height) { - return createLoadEvent(ViewUtil.NO_SURFACE_ID, viewId, imageUri, width, height); - } - - @Deprecated - public static final ImageLoadEvent createErrorEvent(int viewId, Throwable throwable) { - return createErrorEvent(ViewUtil.NO_SURFACE_ID, viewId, throwable); - } - - @Deprecated - public static final ImageLoadEvent createLoadEndEvent(int viewId) { - return createLoadEndEvent(ViewUtil.NO_SURFACE_ID, viewId); - } - - public static final ImageLoadEvent createLoadStartEvent(int surfaceId, int viewId) { - return new ImageLoadEvent(surfaceId, viewId, ON_LOAD_START); - } - - /** - * @param loaded Amount of the image that has been loaded. It should be number of bytes, but - * Fresco does not currently provides that information. - * @param total Amount that `loaded` will be when the image is fully loaded. - */ - public static final ImageLoadEvent createProgressEvent( - int surfaceId, int viewId, @Nullable String imageUri, int loaded, int total) { - return new ImageLoadEvent(surfaceId, viewId, ON_PROGRESS, null, imageUri, 0, 0, loaded, total); - } - - public static final ImageLoadEvent createLoadEvent( - int surfaceId, int viewId, @Nullable String imageUri, int width, int height) { - return new ImageLoadEvent(surfaceId, viewId, ON_LOAD, null, imageUri, width, height, 0, 0); - } - - public static final ImageLoadEvent createErrorEvent( - int surfaceId, int viewId, Throwable throwable) { - return new ImageLoadEvent( - surfaceId, viewId, ON_ERROR, throwable.getMessage(), null, 0, 0, 0, 0); - } - - public static final ImageLoadEvent createLoadEndEvent(int surfaceId, int viewId) { - return new ImageLoadEvent(surfaceId, viewId, ON_LOAD_END); - } - - private ImageLoadEvent(int surfaceId, int viewId, @ImageEventType int eventType) { - this(surfaceId, viewId, eventType, null, null, 0, 0, 0, 0); - } - - private ImageLoadEvent( - int surfaceId, - int viewId, - @ImageEventType int eventType, - @Nullable String errorMessage, - @Nullable String sourceUri, - int width, - int height, - int loaded, - int total) { - super(surfaceId, viewId); - mEventType = eventType; - mErrorMessage = errorMessage; - mSourceUri = sourceUri; - mWidth = width; - mHeight = height; - mLoaded = loaded; - mTotal = total; - } - - public static String eventNameForType(@ImageEventType int eventType) { - switch (eventType) { - case ON_ERROR: - return "topError"; - case ON_LOAD: - return "topLoad"; - case ON_LOAD_END: - return "topLoadEnd"; - case ON_LOAD_START: - return "topLoadStart"; - case ON_PROGRESS: - return "topProgress"; - default: - throw new IllegalStateException("Invalid image event: " + Integer.toString(eventType)); - } - } - - @Override - public String getEventName() { - return ImageLoadEvent.eventNameForType(mEventType); - } - - @Override - public short getCoalescingKey() { - // Intentionally casting mEventType because it is guaranteed to be small - // enough to fit into short. - return (short) mEventType; - } - - @Override - protected WritableMap getEventData() { - WritableMap eventData = Arguments.createMap(); - - switch (mEventType) { - case ON_PROGRESS: - eventData.putInt("loaded", mLoaded); - eventData.putInt("total", mTotal); - break; - case ON_LOAD: - eventData.putMap("source", createEventDataSource()); - break; - case ON_ERROR: - eventData.putString("error", mErrorMessage); - break; - } - - return eventData; - } - - private WritableMap createEventDataSource() { - WritableMap source = Arguments.createMap(); - source.putString("uri", mSourceUri); - source.putDouble("width", mWidth); - source.putDouble("height", mHeight); - return source; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.kt new file mode 100644 index 00000000000000..596418d961ffd1 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageLoadEvent.kt @@ -0,0 +1,155 @@ +/* + * 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.image + +import androidx.annotation.IntDef +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.WritableMap +import com.facebook.react.uimanager.common.ViewUtil +import com.facebook.react.uimanager.events.Event + +public class ImageLoadEvent +private constructor( + surfaceId: Int, + viewId: Int, + @param:ImageEventType private val eventType: Int, + private val errorMessage: String? = null, + private val sourceUri: String? = null, + private val width: Int = 0, + private val height: Int = 0, + private val loaded: Int = 0, + private val total: Int = 0 +) : Event(surfaceId, viewId) { + @IntDef(ON_ERROR, ON_LOAD, ON_LOAD_END, ON_LOAD_START, ON_PROGRESS) + @Retention(AnnotationRetention.SOURCE) + internal annotation class ImageEventType + + override fun getEventName(): String = eventNameForType(eventType) + + // Intentionally casting eventType because it is guaranteed to be a short + // enough to fit into short. + override fun getCoalescingKey(): Short = eventType.toShort() + + override fun getEventData(): WritableMap? = + Arguments.createMap().apply { + when (eventType) { + ON_PROGRESS -> { + putInt("loaded", loaded) + putInt("total", total) + } + ON_LOAD -> putMap("source", createEventDataSource()) + ON_ERROR -> putString("error", errorMessage) + } + } + + private fun createEventDataSource(): WritableMap = + Arguments.createMap().apply { + putString("uri", sourceUri) + putDouble("width", width.toDouble()) + putDouble("height", height.toDouble()) + } + + public companion object { + public const val ON_ERROR: Int = 1 + public const val ON_LOAD: Int = 2 + public const val ON_LOAD_END: Int = 3 + public const val ON_LOAD_START: Int = 4 + public const val ON_PROGRESS: Int = 5 + + @Deprecated( + "Use the createLoadStartEvent version that explicitly takes surfaceId as an argument", + ReplaceWith("createLoadStartEvent(surfaceId, viewId)")) + @JvmStatic + public fun createLoadStartEvent(viewId: Int): ImageLoadEvent = + createLoadStartEvent(ViewUtil.NO_SURFACE_ID, viewId) + + @Deprecated( + "Use the createProgressEvent version that explicitly takes surfaceId as an argument", + ReplaceWith("createProgressEvent(surfaceId, viewId, imageUri, loaded, total)")) + @JvmStatic + public fun createProgressEvent( + viewId: Int, + imageUri: String?, + loaded: Int, + total: Int + ): ImageLoadEvent = createProgressEvent(ViewUtil.NO_SURFACE_ID, viewId, imageUri, loaded, total) + + @Deprecated( + "Use the createLoadEvent version that explicitly takes surfaceId as an argument", + ReplaceWith("createLoadEvent(surfaceId, viewId, imageUri, width, height)")) + @JvmStatic + public fun createLoadEvent( + viewId: Int, + imageUri: String?, + width: Int, + height: Int + ): ImageLoadEvent = createLoadEvent(ViewUtil.NO_SURFACE_ID, viewId, imageUri, width, height) + + @Deprecated( + "Use the createErrorEvent version that explicitly takes surfaceId as an argument", + ReplaceWith("createErrorEvent(surfaceId, viewId, throwable)")) + @JvmStatic + public fun createErrorEvent(viewId: Int, throwable: Throwable): ImageLoadEvent = + createErrorEvent(ViewUtil.NO_SURFACE_ID, viewId, throwable) + + @Deprecated( + "Use the createLoadEndEvent version that explicitly takes surfaceId as an argument", + ReplaceWith("createLoadEndEvent(surfaceId, viewId)")) + @JvmStatic + public fun createLoadEndEvent(viewId: Int): ImageLoadEvent = + createLoadEndEvent(ViewUtil.NO_SURFACE_ID, viewId) + + @JvmStatic + public fun createLoadStartEvent(surfaceId: Int, viewId: Int): ImageLoadEvent = + ImageLoadEvent(surfaceId, viewId, ON_LOAD_START) + + /** + * @param loaded Amount of the image that has been loaded. It should be number of bytes, but + * Fresco does not currently provides that information. + * @param total Amount that `loaded` will be when the image is fully loaded. + */ + @JvmStatic + public fun createProgressEvent( + surfaceId: Int, + viewId: Int, + imageUri: String?, + loaded: Int, + total: Int + ): ImageLoadEvent = + ImageLoadEvent(surfaceId, viewId, ON_PROGRESS, null, imageUri, 0, 0, loaded, total) + + @JvmStatic + public fun createLoadEvent( + surfaceId: Int, + viewId: Int, + imageUri: String?, + width: Int, + height: Int + ): ImageLoadEvent = + ImageLoadEvent(surfaceId, viewId, ON_LOAD, null, imageUri, width, height, 0, 0) + + @JvmStatic + public fun createErrorEvent(surfaceId: Int, viewId: Int, throwable: Throwable): ImageLoadEvent = + ImageLoadEvent(surfaceId, viewId, ON_ERROR, throwable.message, null, 0, 0, 0, 0) + + @JvmStatic + public fun createLoadEndEvent(surfaceId: Int, viewId: Int): ImageLoadEvent = + ImageLoadEvent(surfaceId, viewId, ON_LOAD_END) + + @JvmStatic + public fun eventNameForType(@ImageEventType eventType: Int): String = + when (eventType) { + ON_ERROR -> "topError" + ON_LOAD -> "topLoad" + ON_LOAD_END -> "topLoadEnd" + ON_LOAD_START -> "topLoadStart" + ON_PROGRESS -> "topProgress" + else -> error("Invalid image event: $eventType") + } + } +}