@@ -4,13 +4,35 @@ import androidx.annotation.Keep
44import com.facebook.proguard.annotations.DoNotStrip
55import com.facebook.react.uimanager.ThemedReactContext
66import com.margelo.nitro.core.Promise
7+ import com.rive.BindData
78import com.rive.RiveReactNativeView
89import com.rive.ViewConfiguration
910import app.rive.runtime.kotlin.core.Fit as RiveFit
1011import app.rive.runtime.kotlin.core.Alignment as RiveAlignment
1112import kotlinx.coroutines.Dispatchers
1213import kotlinx.coroutines.withContext
1314
15+ fun Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName.toBindData (): BindData {
16+ return when (this ) {
17+ is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .First -> {
18+ val instance = (this .asFirstOrNull() as ? HybridViewModelInstance )?.viewModelInstance
19+ ? : throw Error (" Invalid ViewModelInstance" )
20+ BindData .Instance (instance)
21+ }
22+ is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .Second -> {
23+ when (this .asSecondOrNull()) {
24+ DataBindMode .AUTO -> BindData .Auto
25+ DataBindMode .NONE -> BindData .None
26+ else -> BindData .None
27+ }
28+ }
29+ is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .Third -> {
30+ val name = this .asThirdOrNull()?.byName ? : throw Error (" Missing byName value" )
31+ BindData .ByName (name)
32+ }
33+ }
34+ }
35+
1436object DefaultConfiguration {
1537 const val AUTOPLAY = true
1638 val FIT = RiveFit .CONTAIN
@@ -24,6 +46,7 @@ class HybridRiveView(val context: ThemedReactContext) : HybridRiveViewSpec() {
2446 // region State
2547 override val view: RiveReactNativeView = RiveReactNativeView (context)
2648 private var needsReload = false
49+ private var firstUpdate = true
2750 private var registeredFile: HybridRiveFile ? = null
2851 // endregion
2952
@@ -56,7 +79,7 @@ class HybridRiveView(val context: ThemedReactContext) : HybridRiveViewSpec() {
5679 set(value) {
5780 if (field != value) {
5881 field = value
59- needsReload = true
82+ applyDataBinding()
6083 }
6184 }
6285 // endregion
@@ -111,34 +134,62 @@ class HybridRiveView(val context: ThemedReactContext) : HybridRiveViewSpec() {
111134 view.getTextRunValue(name, path)
112135 // endregion
113136
137+ // region Data Binding
138+ private fun applyDataBinding () {
139+ val stateMachines = view.riveAnimationView?.controller?.stateMachines
140+ if (stateMachines.isNullOrEmpty()) return
141+
142+ val bindData = dataBind.toBindData()
143+ val stateMachine = stateMachines.first()
144+
145+ when (bindData) {
146+ is BindData .None -> {
147+ // Unbind by setting to null
148+ stateMachine.viewModelInstance = null
149+ }
150+ is BindData .Auto -> {
151+ // Get the default view model and create default instance
152+ val artboard = view.riveAnimationView?.controller?.activeArtboard
153+ val file = view.riveAnimationView?.controller?.file
154+ if (artboard != null && file != null ) {
155+ val viewModel = file.defaultViewModelForArtboard(artboard)
156+ val instance = viewModel.createDefaultInstance()
157+ stateMachine.viewModelInstance = instance
158+ }
159+ }
160+ is BindData .Instance -> {
161+ stateMachine.viewModelInstance = bindData.instance
162+ }
163+ is BindData .ByName -> {
164+ val artboard = view.riveAnimationView?.controller?.activeArtboard
165+ val file = view.riveAnimationView?.controller?.file
166+ if (artboard != null && file != null ) {
167+ val viewModel = file.defaultViewModelForArtboard(artboard)
168+ val instance = viewModel.createInstanceFromName(bindData.name)
169+ stateMachine.viewModelInstance = instance
170+ }
171+ }
172+ }
173+
174+ // Only play on subsequent updates, not first
175+ if (! firstUpdate) {
176+ view.riveAnimationView?.controller?.stateMachines?.first()?.name?.let { smName ->
177+ view.riveAnimationView?.play(smName, isStateMachine = true )
178+ }
179+ }
180+ }
181+ // endregion
114182
115183 // region Update
116184 fun refreshAfterAssetChange () {
117185 afterUpdate()
118186 }
119187
120188 override fun afterUpdate () {
189+ firstUpdate = false
121190 val hybridFile = file as ? HybridRiveFile
122191 val riveFile = hybridFile?.riveFile ? : return
123192
124- val (bindMode, bindInstance, bindInstanceName) = when (dataBind) {
125- is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .First -> {
126- val instance = (dataBind.asFirstOrNull() as ? HybridViewModelInstance )?.viewModelInstance
127- Triple (com.rive.BindData .INSTANCE , instance, null )
128- }
129- is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .Second -> {
130- when (dataBind.asSecondOrNull()) {
131- DataBindMode .AUTO -> Triple (com.rive.BindData .AUTO , null , null )
132- DataBindMode .NONE -> Triple (com.rive.BindData .NONE , null , null )
133- else -> Triple (com.rive.BindData .NONE , null , null )
134- }
135- }
136- is Variant_HybridViewModelInstanceSpec_DataBindMode_DataBindByName .Third -> {
137- val name = dataBind.asThirdOrNull()?.byName
138- Triple (com.rive.BindData .BY_NAME , null , name)
139- }
140- }
141-
142193 val config = ViewConfiguration (
143194 artboardName = artboardName,
144195 stateMachineName = stateMachineName,
@@ -147,9 +198,7 @@ class HybridRiveView(val context: ThemedReactContext) : HybridRiveViewSpec() {
147198 alignment = convertAlignment(alignment) ? : DefaultConfiguration .ALIGNMENT ,
148199 fit = convertFit(fit) ? : DefaultConfiguration .FIT ,
149200 layoutScaleFactor = layoutScaleFactor?.toFloat() ? : DefaultConfiguration .LAYOUTSCALEFACTOR ,
150- bindMode = bindMode,
151- bindInstance = bindInstance,
152- bindInstanceName = bindInstanceName
201+ bindData = dataBind.toBindData()
153202 )
154203 view.configure(config, needsReload)
155204
0 commit comments