From c4629e628729002f9dd9e361eab93778f4c5441b Mon Sep 17 00:00:00 2001 From: Zach Plata Date: Wed, 20 Sep 2023 18:16:50 -0500 Subject: [PATCH] feat: bump android runtime and integrate events listener --- android/build.gradle | 2 +- .../rivereactnative/RiveReactNativeView.kt | 56 +++++++++++++++++- .../android/app/src/main/res/raw/rating.riv | Bin 0 -> 16204 bytes 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 example/android/app/src/main/res/raw/rating.riv diff --git a/android/build.gradle b/android/build.gradle index 90ddfd2..83a10e5 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -135,7 +135,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1' - implementation 'app.rive:rive-android:8.2.1' + implementation 'app.rive:rive-android:8.4.0' implementation "androidx.startup:startup-runtime:1.1.1" implementation 'com.android.volley:volley:1.2.0' } diff --git a/android/src/main/java/com/rivereactnative/RiveReactNativeView.kt b/android/src/main/java/com/rivereactnative/RiveReactNativeView.kt index 2cf2a6e..25a48d9 100644 --- a/android/src/main/java/com/rivereactnative/RiveReactNativeView.kt +++ b/android/src/main/java/com/rivereactnative/RiveReactNativeView.kt @@ -4,7 +4,6 @@ import android.widget.FrameLayout import app.rive.runtime.kotlin.PointerEvents import app.rive.runtime.kotlin.RiveAnimationView import app.rive.runtime.kotlin.controllers.RiveFileController -import app.rive.runtime.kotlin.RiveArtboardRenderer import app.rive.runtime.kotlin.core.* import app.rive.runtime.kotlin.core.errors.* import com.android.volley.NetworkResponse @@ -13,14 +12,14 @@ import com.android.volley.Request import com.android.volley.Response import com.android.volley.toolbox.HttpHeaderParser import com.android.volley.toolbox.Volley -import com.facebook.react.uimanager.events.RCTEventEmitter import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.WritableMap import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.ReadableArray import com.facebook.react.modules.core.ExceptionsManagerModule import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.events.RCTEventEmitter import java.io.UnsupportedEncodingException -import kotlin.IllegalStateException class RiveReactNativeView(private val context: ThemedReactContext) : FrameLayout(context) { @@ -43,6 +42,7 @@ class RiveReactNativeView(private val context: ThemedReactContext) : FrameLayout STOP("onStop"), LOOP_END("onLoopEnd"), STATE_CHANGED("onStateChanged"), + RIVE_EVENT("onRiveEventReceived"), ERROR("onError"); override fun toString(): String { @@ -92,7 +92,18 @@ class RiveReactNativeView(private val context: ThemedReactContext) : FrameLayout } } + + val eventListener = object : RiveFileController.RiveEventListener { + override fun notifyEvent(event: RiveEvent) { + when (event) { + is RiveGeneralEvent -> onRiveEventReceived(event as RiveGeneralEvent) + is RiveOpenURLEvent -> onRiveEventReceived(event as RiveOpenURLEvent) + } + } + } + riveAnimationView.registerListener(listener) + riveAnimationView.addEventListener(eventListener) autoplay = false addView(riveAnimationView) } @@ -146,6 +157,45 @@ class RiveReactNativeView(private val context: ThemedReactContext) : FrameLayout reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, Events.STATE_CHANGED.toString(), data) } + private fun convertHashMapToWritableMap(hashMap: HashMap): WritableMap { + val writableMap = Arguments.createMap() + + for ((key, value) in hashMap) { + when (value) { + is String -> writableMap.putString(key, value) + is Int -> writableMap.putInt(key, value) + is Float -> writableMap.putDouble(key, value.toDouble()) + is Double -> writableMap.putDouble(key, value) + is Boolean -> writableMap.putBoolean(key, value) + } + } + + return writableMap + } + + fun onRiveEventReceived(event: RiveEvent) { + val reactContext = context as ReactContext + val topLevelDict = Arguments.createMap() + + val eventProperties = Arguments.createMap().apply { + putString("name", event.name) + putDouble("delay", event.delay.toDouble()) + putMap("properties", convertHashMapToWritableMap(event.properties)) + } + + if (event is RiveOpenURLEvent) { + eventProperties.putString("url", event.url) + eventProperties.putString("target", event.target) + } + + topLevelDict.putMap( + "riveEvent", + eventProperties + ) + + reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, Events.RIVE_EVENT.toString(), topLevelDict) + } + fun play(animationName: String, rnLoopMode: RNLoopMode, rnDirection: RNDirection, isStateMachine: Boolean) { val loop = RNLoopMode.mapToRiveLoop(rnLoopMode) val direction = RNDirection.mapToRiveDirection(rnDirection) diff --git a/example/android/app/src/main/res/raw/rating.riv b/example/android/app/src/main/res/raw/rating.riv new file mode 100644 index 0000000000000000000000000000000000000000..330f7e91c741daeea0b15d7e77e1e19c058007cc GIT binary patch literal 16204 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 literal 0 HcmV?d00001