@rive-app/react-native 0.1.1-beta.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -7
- package/android/src/main/java/com/margelo/nitro/rive/BaseHybridViewModelProperty.kt +9 -7
- package/android/src/main/java/com/margelo/nitro/rive/BaseHybridViewModelPropertyImpl.kt +43 -24
- package/android/src/main/java/com/margelo/nitro/rive/HybridRiveFile.kt +0 -1
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelBooleanProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelColorProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelEnumProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelImageProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelInstance.kt +26 -47
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelListProperty.kt +64 -0
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelNumberProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelStringProperty.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/rive/HybridViewModelTriggerProperty.kt +3 -2
- package/ios/BaseHybridViewModelProperty.swift +22 -6
- package/ios/HybridViewModel.swift +1 -6
- package/ios/HybridViewModelBooleanProperty.swift +1 -9
- package/ios/HybridViewModelColorProperty.swift +3 -12
- package/ios/HybridViewModelEnumProperty.swift +1 -9
- package/ios/HybridViewModelImageProperty.swift +4 -4
- package/ios/HybridViewModelInstance.swift +6 -6
- package/ios/HybridViewModelListProperty.swift +62 -0
- package/ios/HybridViewModelNumberProperty.swift +2 -13
- package/ios/HybridViewModelStringProperty.swift +1 -9
- package/ios/HybridViewModelTriggerProperty.swift +5 -14
- package/ios/RiveReactNativeView.swift +36 -0
- package/lib/module/hooks/useRiveColor.js +0 -1
- package/lib/module/hooks/useRiveColor.js.map +1 -1
- package/lib/module/hooks/useRiveList.js +71 -0
- package/lib/module/hooks/useRiveList.js.map +1 -0
- package/lib/module/hooks/useRiveProperty.js +6 -12
- package/lib/module/hooks/useRiveProperty.js.map +1 -1
- package/lib/module/hooks/useViewModelInstance.js +139 -0
- package/lib/module/hooks/useViewModelInstance.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/hooks/useRiveColor.d.ts +6 -4
- package/lib/typescript/src/hooks/useRiveColor.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useRiveList.d.ts +11 -0
- package/lib/typescript/src/hooks/useRiveList.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useRiveProperty.d.ts +6 -1
- package/lib/typescript/src/hooks/useRiveProperty.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useViewModelInstance.d.ts +86 -0
- package/lib/typescript/src/hooks/useViewModelInstance.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/ViewModel.nitro.d.ts +39 -15
- package/lib/typescript/src/specs/ViewModel.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +47 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelBooleanPropertySpec.cpp +14 -4
- package/nitrogen/generated/android/c++/JHybridViewModelBooleanPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelColorPropertySpec.cpp +14 -4
- package/nitrogen/generated/android/c++/JHybridViewModelColorPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelEnumPropertySpec.cpp +14 -4
- package/nitrogen/generated/android/c++/JHybridViewModelEnumPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelImagePropertySpec.cpp +15 -6
- package/nitrogen/generated/android/c++/JHybridViewModelImagePropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.cpp +9 -0
- package/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.hpp +1 -0
- package/nitrogen/generated/android/c++/JHybridViewModelListPropertySpec.cpp +102 -0
- package/nitrogen/generated/android/c++/JHybridViewModelListPropertySpec.hpp +73 -0
- package/nitrogen/generated/android/c++/JHybridViewModelNumberPropertySpec.cpp +14 -4
- package/nitrogen/generated/android/c++/JHybridViewModelNumberPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelStringPropertySpec.cpp +14 -4
- package/nitrogen/generated/android/c++/JHybridViewModelStringPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridViewModelTriggerPropertySpec.cpp +12 -3
- package/nitrogen/generated/android/c++/JHybridViewModelTriggerPropertySpec.hpp +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelBooleanPropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelColorPropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelEnumPropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelImagePropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelInstanceSpec.kt +4 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelListPropertySpec.kt +92 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelNumberPropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelStringPropertySpec.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelTriggerPropertySpec.kt +3 -3
- package/nitrogen/generated/android/rive+autolinking.cmake +2 -0
- package/nitrogen/generated/android/riveOnLoad.cpp +4 -74
- package/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.hpp +53 -0
- package/nitrogen/generated/ios/RNRive-Swift-Cxx-Umbrella.hpp +5 -0
- package/nitrogen/generated/ios/RNRiveAutolinking.mm +0 -72
- package/nitrogen/generated/ios/RNRiveAutolinking.swift +0 -135
- package/nitrogen/generated/ios/c++/HybridViewModelBooleanPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelColorPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelEnumPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelImagePropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelInstanceSpecSwift.hpp +11 -0
- package/nitrogen/generated/ios/c++/HybridViewModelListPropertySpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridViewModelListPropertySpecSwift.hpp +134 -0
- package/nitrogen/generated/ios/c++/HybridViewModelNumberPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelStringPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/c++/HybridViewModelTriggerPropertySpecSwift.hpp +3 -1
- package/nitrogen/generated/ios/swift/HybridViewModelBooleanPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelBooleanPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelColorPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelColorPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelEnumPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelEnumPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelImagePropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelImagePropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec_cxx.swift +21 -0
- package/nitrogen/generated/ios/swift/HybridViewModelListPropertySpec.swift +63 -0
- package/nitrogen/generated/ios/swift/HybridViewModelListPropertySpec_cxx.swift +248 -0
- package/nitrogen/generated/ios/swift/HybridViewModelNumberPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelNumberPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelStringPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelStringPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/ios/swift/HybridViewModelTriggerPropertySpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridViewModelTriggerPropertySpec_cxx.swift +8 -4
- package/nitrogen/generated/shared/c++/HybridViewModelBooleanPropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelColorPropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelEnumPropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelImagePropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.hpp +4 -0
- package/nitrogen/generated/shared/c++/HybridViewModelListPropertySpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridViewModelListPropertySpec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridViewModelNumberPropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelStringPropertySpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridViewModelTriggerPropertySpec.hpp +1 -1
- package/package.json +3 -3
- package/src/hooks/useRiveColor.ts +7 -4
- package/src/hooks/useRiveList.ts +108 -0
- package/src/hooks/useRiveProperty.ts +20 -13
- package/src/hooks/useViewModelInstance.ts +195 -0
- package/src/index.tsx +4 -0
- package/src/specs/ViewModel.nitro.ts +43 -15
- package/src/types.tsx +58 -3
package/README.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
# @rive-app/react-native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/rive-app/rive-nitro-react-native/actions)
|
|
4
|
+
[](https://www.npmjs.com/package/@rive-app/react-native)
|
|
5
|
+
[](https://www.npmjs.com/package/@rive-app/react-native)
|
|
6
|
+
[](https://reactnative.dev/)
|
|
7
|
+
[](#requirements)
|
|
8
|
+
[](#requirements)
|
|
9
|
+
[](https://github.com/rive-app/rive-ios/releases)
|
|
10
|
+
[](https://github.com/rive-app/rive-android/releases)
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
**Rive React Native 2.0**
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## Early Release
|
|
17
|
+
|
|
18
|
+
> **⚠️ Early Release**: This package is in active development. We recommend testing thoroughly before using in production applications. We're actively gathering feedback to improve the library. Please share your thoughts and report any issues you encounter.
|
|
8
19
|
|
|
9
20
|
## Requirements
|
|
10
21
|
|
|
@@ -23,7 +34,7 @@ Rive React Native 2.0
|
|
|
23
34
|
## Installation
|
|
24
35
|
|
|
25
36
|
```sh
|
|
26
|
-
npm install rive-app/
|
|
37
|
+
npm install @rive-app/react-native react-native-nitro-modules
|
|
27
38
|
```
|
|
28
39
|
|
|
29
40
|
> `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
|
|
@@ -117,6 +128,7 @@ export default {
|
|
|
117
128
|
},
|
|
118
129
|
};
|
|
119
130
|
```
|
|
131
|
+
|
|
120
132
|
</details>
|
|
121
133
|
|
|
122
134
|
## Error Handling
|
|
@@ -237,9 +249,9 @@ This section tracks new features and improvements planned for this runtime that
|
|
|
237
249
|
| Feature | Status |
|
|
238
250
|
| ----------------------------------------------------------------------------------------------------- | ------ |
|
|
239
251
|
| [Reusable .riv File resources (preloading)](https://github.com/rive-app/rive-react-native/issues/260) | ✅ |
|
|
240
|
-
| [Data Binding - Images](https://github.com/rive-app/rive-nitro-react-native/issues/9) |
|
|
252
|
+
| [Data Binding - Images](https://github.com/rive-app/rive-nitro-react-native/issues/9) | ✅ |
|
|
241
253
|
| [Data Binding - Artboards](https://github.com/rive-app/rive-nitro-react-native/issues/10) | 🚧 |
|
|
242
|
-
| [Data Binding - Lists](https://github.com/rive-app/rive-nitro-react-native/issues/11) |
|
|
254
|
+
| [Data Binding - Lists](https://github.com/rive-app/rive-nitro-react-native/issues/11) | ✅ |
|
|
243
255
|
| [Data Binding - Value props](https://github.com/rive-app/rive-nitro-react-native/pull/24) | 🚧 |
|
|
244
256
|
| [Suspense](https://github.com/rive-app/rive-nitro-react-native/pull/19) | 🚧 |
|
|
245
257
|
|
|
@@ -254,4 +266,3 @@ MIT
|
|
|
254
266
|
---
|
|
255
267
|
|
|
256
268
|
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
257
|
-
|
|
@@ -9,12 +9,14 @@ import kotlinx.coroutines.flow.Flow
|
|
|
9
9
|
@Keep
|
|
10
10
|
@DoNotStrip
|
|
11
11
|
interface BaseHybridViewModelProperty<T> {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
val scope: CoroutineScope?
|
|
13
|
+
val job: Job?
|
|
14
|
+
val listeners: MutableMap<String, (T) -> Unit>
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
fun ensureValueListenerJob(valueFlow: Flow<T>, drop: Int = 0)
|
|
17
|
+
fun onChanged(value: T)
|
|
18
|
+
fun addListenerInternal(callback: (T) -> Unit): () -> Unit
|
|
19
|
+
fun removeListener(id: String)
|
|
20
|
+
fun removeListeners()
|
|
21
|
+
fun dispose()
|
|
20
22
|
}
|
|
@@ -9,42 +9,61 @@ import kotlinx.coroutines.cancel
|
|
|
9
9
|
import kotlinx.coroutines.launch
|
|
10
10
|
import kotlinx.coroutines.flow.Flow
|
|
11
11
|
import kotlinx.coroutines.flow.drop
|
|
12
|
+
import java.lang.ref.WeakReference
|
|
13
|
+
import java.util.UUID
|
|
12
14
|
|
|
13
15
|
@Keep
|
|
14
16
|
@DoNotStrip
|
|
15
17
|
class BaseHybridViewModelPropertyImpl<T> : BaseHybridViewModelProperty<T> {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
override var scope: CoroutineScope? = null
|
|
19
|
+
override var job: Job? = null
|
|
20
|
+
override val listeners = mutableMapOf<String, (T) -> Unit>()
|
|
19
21
|
|
|
20
22
|
override fun ensureValueListenerJob(valueFlow: Flow<T>, drop: Int) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
}
|
|
23
|
+
if (scope == null) {
|
|
24
|
+
scope = CoroutineScope(Dispatchers.Default)
|
|
25
|
+
}
|
|
26
|
+
if (job == null) {
|
|
27
|
+
job = scope?.launch {
|
|
28
|
+
valueFlow.drop(drop).collect { value ->
|
|
29
|
+
onChanged(value)
|
|
30
30
|
}
|
|
31
|
+
}
|
|
31
32
|
}
|
|
33
|
+
}
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
35
|
+
override fun onChanged(value: T) {
|
|
36
|
+
listeners.values.forEach { listener ->
|
|
37
|
+
listener(value)
|
|
37
38
|
}
|
|
39
|
+
}
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
override fun addListenerInternal(callback: (T) -> Unit): () -> Unit {
|
|
42
|
+
val id = UUID.randomUUID().toString()
|
|
43
|
+
listeners[id] = callback
|
|
44
|
+
val weakSelf = WeakReference(this)
|
|
45
|
+
return {
|
|
46
|
+
weakSelf.get()?.removeListener(id)
|
|
45
47
|
}
|
|
48
|
+
}
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
override fun removeListener(id: String) {
|
|
51
|
+
listeners.remove(id)
|
|
52
|
+
if (listeners.isEmpty()) {
|
|
53
|
+
job?.cancel()
|
|
54
|
+
job = null
|
|
49
55
|
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun removeListeners() {
|
|
59
|
+
listeners.clear()
|
|
60
|
+
job?.cancel()
|
|
61
|
+
scope?.cancel()
|
|
62
|
+
job = null
|
|
63
|
+
scope = null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override fun dispose() {
|
|
67
|
+
removeListeners()
|
|
68
|
+
}
|
|
50
69
|
}
|
|
@@ -3,7 +3,6 @@ package com.margelo.nitro.rive
|
|
|
3
3
|
import androidx.annotation.Keep
|
|
4
4
|
import app.rive.runtime.kotlin.core.File
|
|
5
5
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
|
-
import com.margelo.nitro.NitroModules
|
|
7
6
|
import java.lang.ref.WeakReference
|
|
8
7
|
import kotlinx.coroutines.CoroutineScope
|
|
9
8
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -15,8 +15,9 @@ class HybridViewModelBooleanProperty(private val viewModelBoolean: ViewModelBool
|
|
|
15
15
|
viewModelBoolean.value = value
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
override fun addListener(onChanged: (value: Boolean) -> Unit) {
|
|
19
|
-
|
|
18
|
+
override fun addListener(onChanged: (value: Boolean) -> Unit): () -> Unit {
|
|
19
|
+
val remover = addListenerInternal(onChanged)
|
|
20
20
|
ensureValueListenerJob(viewModelBoolean.valueFlow)
|
|
21
|
+
return remover
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -15,8 +15,9 @@ class HybridViewModelColorProperty(private val viewModelColor: ViewModelColorPro
|
|
|
15
15
|
viewModelColor.value = value.toInt()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
override fun addListener(onChanged: (value: Double) -> Unit) {
|
|
19
|
-
|
|
18
|
+
override fun addListener(onChanged: (value: Double) -> Unit): () -> Unit {
|
|
19
|
+
val remover = addListenerInternal { intValue: Int -> onChanged(intValue.toDouble()) }
|
|
20
20
|
ensureValueListenerJob(viewModelColor.valueFlow)
|
|
21
|
+
return remover
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -15,8 +15,9 @@ class HybridViewModelEnumProperty(private val viewModelEnum: ViewModelEnumProper
|
|
|
15
15
|
viewModelEnum.value = value
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
override fun addListener(onChanged: (value: String) -> Unit) {
|
|
19
|
-
|
|
18
|
+
override fun addListener(onChanged: (value: String) -> Unit): () -> Unit {
|
|
19
|
+
val remover = addListenerInternal(onChanged)
|
|
20
20
|
ensureValueListenerJob(viewModelEnum.valueFlow)
|
|
21
|
+
return remover
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -14,8 +14,9 @@ class HybridViewModelImageProperty(private val viewModelImage: ViewModelImagePro
|
|
|
14
14
|
viewModelImage.set((image as? HybridRiveImage)?.renderImage)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
override fun addListener(onChanged: () -> Unit) {
|
|
18
|
-
|
|
17
|
+
override fun addListener(onChanged: () -> Unit): () -> Unit {
|
|
18
|
+
val remover = addListenerInternal { _ -> onChanged() }
|
|
19
19
|
ensureValueListenerJob(viewModelImage.valueFlow.map { })
|
|
20
|
+
return remover
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -11,66 +11,45 @@ class HybridViewModelInstance(val viewModelInstance: ViewModelInstance) : Hybrid
|
|
|
11
11
|
override val instanceName: String
|
|
12
12
|
get() = viewModelInstance.name
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
// Returns null if ViewModelException is thrown for iOS parity
|
|
15
|
+
// (iOS SDK returns nil when property not found, Android SDK throws)
|
|
16
|
+
private inline fun <T> getPropertyOrNull(block: () -> T): T? {
|
|
17
|
+
return try {
|
|
18
|
+
block()
|
|
18
19
|
} catch (e: ViewModelException) {
|
|
19
|
-
|
|
20
|
+
null
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
override fun
|
|
24
|
-
|
|
25
|
-
val stringProperty = viewModelInstance.getStringProperty(path)
|
|
26
|
-
return HybridViewModelStringProperty(stringProperty)
|
|
27
|
-
} catch (e: ViewModelException) {
|
|
28
|
-
return null
|
|
29
|
-
}
|
|
24
|
+
override fun numberProperty(path: String) = getPropertyOrNull {
|
|
25
|
+
HybridViewModelNumberProperty(viewModelInstance.getNumberProperty(path))
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
override fun
|
|
33
|
-
|
|
34
|
-
val booleanProperty = viewModelInstance.getBooleanProperty(path)
|
|
35
|
-
return HybridViewModelBooleanProperty(booleanProperty)
|
|
36
|
-
} catch (e: ViewModelException) {
|
|
37
|
-
return null
|
|
38
|
-
}
|
|
28
|
+
override fun stringProperty(path: String) = getPropertyOrNull {
|
|
29
|
+
HybridViewModelStringProperty(viewModelInstance.getStringProperty(path))
|
|
39
30
|
}
|
|
40
31
|
|
|
41
|
-
override fun
|
|
42
|
-
|
|
43
|
-
val colorProperty = viewModelInstance.getColorProperty(path)
|
|
44
|
-
return HybridViewModelColorProperty(colorProperty)
|
|
45
|
-
} catch (e: ViewModelException) {
|
|
46
|
-
return null
|
|
47
|
-
}
|
|
32
|
+
override fun booleanProperty(path: String) = getPropertyOrNull {
|
|
33
|
+
HybridViewModelBooleanProperty(viewModelInstance.getBooleanProperty(path))
|
|
48
34
|
}
|
|
49
35
|
|
|
50
|
-
override fun
|
|
51
|
-
|
|
52
|
-
val enumProperty = viewModelInstance.getEnumProperty(path)
|
|
53
|
-
return HybridViewModelEnumProperty(enumProperty)
|
|
54
|
-
} catch (e: ViewModelException) {
|
|
55
|
-
return null
|
|
56
|
-
}
|
|
36
|
+
override fun colorProperty(path: String) = getPropertyOrNull {
|
|
37
|
+
HybridViewModelColorProperty(viewModelInstance.getColorProperty(path))
|
|
57
38
|
}
|
|
58
39
|
|
|
59
|
-
override fun
|
|
60
|
-
|
|
61
|
-
val triggerProperty = viewModelInstance.getTriggerProperty(path)
|
|
62
|
-
return HybridViewModelTriggerProperty(triggerProperty)
|
|
63
|
-
} catch (e: ViewModelException) {
|
|
64
|
-
return null
|
|
65
|
-
}
|
|
40
|
+
override fun enumProperty(path: String) = getPropertyOrNull {
|
|
41
|
+
HybridViewModelEnumProperty(viewModelInstance.getEnumProperty(path))
|
|
66
42
|
}
|
|
67
43
|
|
|
68
|
-
override fun
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
44
|
+
override fun triggerProperty(path: String) = getPropertyOrNull {
|
|
45
|
+
HybridViewModelTriggerProperty(viewModelInstance.getTriggerProperty(path))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override fun imageProperty(path: String) = getPropertyOrNull {
|
|
49
|
+
HybridViewModelImageProperty(viewModelInstance.getImageProperty(path))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun listProperty(path: String) = getPropertyOrNull {
|
|
53
|
+
HybridViewModelListProperty(viewModelInstance.getListProperty(path))
|
|
75
54
|
}
|
|
76
55
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
package com.margelo.nitro.rive
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.Keep
|
|
4
|
+
import app.rive.runtime.kotlin.core.ViewModelListProperty
|
|
5
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
|
+
import kotlinx.coroutines.flow.map
|
|
7
|
+
|
|
8
|
+
@Keep
|
|
9
|
+
@DoNotStrip
|
|
10
|
+
class HybridViewModelListProperty(private val listProperty: ViewModelListProperty) :
|
|
11
|
+
HybridViewModelListPropertySpec(),
|
|
12
|
+
BaseHybridViewModelProperty<Unit> by BaseHybridViewModelPropertyImpl() {
|
|
13
|
+
override val length: Double
|
|
14
|
+
get() = listProperty.size.toDouble()
|
|
15
|
+
|
|
16
|
+
private fun requireHybridInstance(instance: HybridViewModelInstanceSpec): HybridViewModelInstance {
|
|
17
|
+
return instance as? HybridViewModelInstance
|
|
18
|
+
?: throw IllegalArgumentException("Expected HybridViewModelInstance but got ${instance::class.simpleName}")
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override fun getInstanceAt(index: Double): HybridViewModelInstanceSpec? {
|
|
22
|
+
val idx = index.toInt()
|
|
23
|
+
if (idx < 0 || idx >= listProperty.size) return null
|
|
24
|
+
return HybridViewModelInstance(listProperty.elementAt(idx))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override fun addInstance(instance: HybridViewModelInstanceSpec) {
|
|
28
|
+
val hybridInstance = requireHybridInstance(instance)
|
|
29
|
+
listProperty.add(hybridInstance.viewModelInstance)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override fun addInstanceAt(instance: HybridViewModelInstanceSpec, index: Double): Boolean {
|
|
33
|
+
val hybridInstance = requireHybridInstance(instance)
|
|
34
|
+
val idx = index.toInt()
|
|
35
|
+
if (idx < 0 || idx > listProperty.size) return false
|
|
36
|
+
listProperty.add(idx, hybridInstance.viewModelInstance)
|
|
37
|
+
return true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override fun removeInstance(instance: HybridViewModelInstanceSpec) {
|
|
41
|
+
val hybridInstance = requireHybridInstance(instance)
|
|
42
|
+
listProperty.remove(hybridInstance.viewModelInstance)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun removeInstanceAt(index: Double) {
|
|
46
|
+
listProperty.removeAt(index.toInt())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override fun swap(index1: Double, index2: Double): Boolean {
|
|
50
|
+
val idx1 = index1.toInt()
|
|
51
|
+
val idx2 = index2.toInt()
|
|
52
|
+
if (idx1 < 0 || idx1 >= listProperty.size || idx2 < 0 || idx2 >= listProperty.size) {
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
listProperty.swap(idx1, idx2)
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
override fun addListener(onChanged: () -> Unit): () -> Unit {
|
|
60
|
+
val remover = addListenerInternal { _ -> onChanged() }
|
|
61
|
+
ensureValueListenerJob(listProperty.valueFlow.map { })
|
|
62
|
+
return remover
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -16,8 +16,9 @@ class HybridViewModelNumberProperty(private val viewModelNumber: ViewModelNumber
|
|
|
16
16
|
viewModelNumber.value = value.toFloat()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
override fun addListener(onChanged: (value: Double) -> Unit) {
|
|
20
|
-
|
|
19
|
+
override fun addListener(onChanged: (value: Double) -> Unit): () -> Unit {
|
|
20
|
+
val remover = addListenerInternal(onChanged)
|
|
21
21
|
ensureValueListenerJob(viewModelNumber.valueFlow.map { it.toDouble() })
|
|
22
|
+
return remover
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -15,8 +15,9 @@ class HybridViewModelStringProperty(private val viewModelString: ViewModelString
|
|
|
15
15
|
viewModelString.value = value
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
override fun addListener(onChanged: (value: String) -> Unit) {
|
|
19
|
-
|
|
18
|
+
override fun addListener(onChanged: (value: String) -> Unit): () -> Unit {
|
|
19
|
+
val remover = addListenerInternal(onChanged)
|
|
20
20
|
ensureValueListenerJob(viewModelString.valueFlow)
|
|
21
|
+
return remover
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -13,9 +13,10 @@ class HybridViewModelTriggerProperty(private val viewModelTrigger: ViewModelTrig
|
|
|
13
13
|
viewModelTrigger.trigger()
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
override fun addListener(onChanged: () -> Unit) {
|
|
17
|
-
|
|
16
|
+
override fun addListener(onChanged: () -> Unit): () -> Unit {
|
|
17
|
+
val remover = addListenerInternal { _ -> onChanged() }
|
|
18
18
|
// We drop the first value as a trigger has no initial value
|
|
19
19
|
ensureValueListenerJob(viewModelTrigger.valueFlow, 1)
|
|
20
|
+
return remover
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -23,6 +23,7 @@ typealias EnumPropertyType = RiveDataBindingViewModel.Instance.EnumProperty
|
|
|
23
23
|
typealias ColorPropertyType = RiveDataBindingViewModel.Instance.ColorProperty
|
|
24
24
|
typealias TriggerPropertyType = RiveDataBindingViewModel.Instance.TriggerProperty
|
|
25
25
|
typealias ImagePropertyType = RiveDataBindingViewModel.Instance.ImageProperty
|
|
26
|
+
typealias ListPropertyType = RiveDataBindingViewModel.Instance.ListProperty
|
|
26
27
|
|
|
27
28
|
// Make all Rive property types conform to the protocol
|
|
28
29
|
extension BooleanPropertyType: RivePropertyWithListeners {
|
|
@@ -56,6 +57,14 @@ extension ImagePropertyType: RivePropertyWithListeners {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
extension ListPropertyType: RivePropertyWithListeners {
|
|
61
|
+
typealias ListenerValueType = Void
|
|
62
|
+
|
|
63
|
+
func addListener(_ callback: @escaping ListenerType) -> UUID {
|
|
64
|
+
addListener { callback(()) }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
/// Helper class for managing ViewModel property listeners
|
|
60
69
|
class PropertyListenerHelper<PropertyType: RivePropertyWithListeners> {
|
|
61
70
|
private var listenerIds: [UUID] = []
|
|
@@ -65,11 +74,18 @@ class PropertyListenerHelper<PropertyType: RivePropertyWithListeners> {
|
|
|
65
74
|
self.property = property
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
/// Adds a listener to the property and
|
|
69
|
-
func addListener(_ callback: @escaping (PropertyType.ListenerValueType) -> Void) {
|
|
70
|
-
guard let property = property else {
|
|
77
|
+
/// Adds a listener to the property and returns a removal function for cleanup
|
|
78
|
+
func addListener(_ callback: @escaping (PropertyType.ListenerValueType) -> Void) -> () -> Void {
|
|
79
|
+
guard let property = property else {
|
|
80
|
+
return {}
|
|
81
|
+
}
|
|
71
82
|
let id = property.addListener(callback)
|
|
72
83
|
listenerIds.append(id)
|
|
84
|
+
return { [weak self, weak property] in
|
|
85
|
+
guard let property = property else { return }
|
|
86
|
+
property.removeListener(id)
|
|
87
|
+
self?.listenerIds.removeAll { $0 == id }
|
|
88
|
+
}
|
|
73
89
|
}
|
|
74
90
|
|
|
75
91
|
func removeListeners() throws {
|
|
@@ -94,7 +110,7 @@ protocol ValuedPropertyProtocol<ValueType> {
|
|
|
94
110
|
var property: PropertyType! { get }
|
|
95
111
|
var helper: PropertyListenerHelper<PropertyType> { get }
|
|
96
112
|
|
|
97
|
-
func addListener(onChanged: @escaping (ValueType) -> Void) throws
|
|
113
|
+
func addListener(onChanged: @escaping (ValueType) -> Void) throws -> () -> Void
|
|
98
114
|
func removeListeners() throws
|
|
99
115
|
func dispose() throws
|
|
100
116
|
}
|
|
@@ -112,7 +128,7 @@ extension ValuedPropertyProtocol {
|
|
|
112
128
|
|
|
113
129
|
/// Automatic addListener() ONLY when ListenerValueType == ValueType (no conversion needed)
|
|
114
130
|
extension ValuedPropertyProtocol where PropertyType.ListenerValueType == ValueType {
|
|
115
|
-
func addListener(onChanged: @escaping (ValueType) -> Void) throws {
|
|
116
|
-
helper.addListener(onChanged)
|
|
131
|
+
func addListener(onChanged: @escaping (ValueType) -> Void) throws -> () -> Void {
|
|
132
|
+
return helper.addListener(onChanged)
|
|
117
133
|
}
|
|
118
134
|
}
|
|
@@ -6,12 +6,7 @@ class HybridViewModel: HybridViewModelSpec {
|
|
|
6
6
|
init(viewModel: RiveDataBindingViewModel) {
|
|
7
7
|
self.viewModel = viewModel
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
override init() {
|
|
11
|
-
self.viewModel = nil
|
|
12
|
-
super.init()
|
|
13
|
-
}
|
|
14
|
-
|
|
9
|
+
|
|
15
10
|
var propertyCount: Double { Double(viewModel?.propertyCount ?? 0) }
|
|
16
11
|
|
|
17
12
|
var instanceCount: Double { Double(viewModel?.instanceCount ?? 0) }
|
|
@@ -9,15 +9,7 @@ class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec, Valued
|
|
|
9
9
|
self.property = property
|
|
10
10
|
super.init()
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
/// ⚠️ DO NOT REMOVE
|
|
14
|
-
/// Nitro requires a parameterless initializer for JS bridging.
|
|
15
|
-
/// This is invoked automatically during hybrid module construction.
|
|
16
|
-
/// Internally we always use `init(property:)`
|
|
17
|
-
override init() {
|
|
18
|
-
super.init()
|
|
19
|
-
}
|
|
20
|
-
|
|
12
|
+
|
|
21
13
|
var value: Bool {
|
|
22
14
|
get {
|
|
23
15
|
return property.value
|
|
@@ -9,15 +9,7 @@ class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ValuedProp
|
|
|
9
9
|
self.property = property
|
|
10
10
|
super.init()
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
/// ⚠️ DO NOT REMOVE
|
|
14
|
-
/// Nitro requires a parameterless initializer for JS bridging.
|
|
15
|
-
/// This is invoked automatically during hybrid module construction.
|
|
16
|
-
/// Internally we always use `init(property:)`
|
|
17
|
-
override init() {
|
|
18
|
-
super.init()
|
|
19
|
-
}
|
|
20
|
-
|
|
12
|
+
|
|
21
13
|
var value: Double {
|
|
22
14
|
get {
|
|
23
15
|
return property.value.toHexDouble()
|
|
@@ -27,9 +19,8 @@ class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ValuedProp
|
|
|
27
19
|
}
|
|
28
20
|
}
|
|
29
21
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
helper.addListener { (color: UIColor) in
|
|
22
|
+
func addListener(onChanged: @escaping (Double) -> Void) throws -> () -> Void {
|
|
23
|
+
return helper.addListener { (color: UIColor) in
|
|
33
24
|
onChanged(color.toHexDouble())
|
|
34
25
|
}
|
|
35
26
|
}
|
|
@@ -9,15 +9,7 @@ class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec, ValuedProper
|
|
|
9
9
|
self.property = property
|
|
10
10
|
super.init()
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
/// ⚠️ DO NOT REMOVE
|
|
14
|
-
/// Nitro requires a parameterless initializer for JS bridging.
|
|
15
|
-
/// This is invoked automatically during hybrid module construction.
|
|
16
|
-
/// Internally we always use `init(property:)`
|
|
17
|
-
override init() {
|
|
18
|
-
super.init()
|
|
19
|
-
}
|
|
20
|
-
|
|
12
|
+
|
|
21
13
|
var value: String {
|
|
22
14
|
get {
|
|
23
15
|
return property.value
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import RiveRuntime
|
|
2
2
|
|
|
3
3
|
class HybridViewModelImageProperty: HybridViewModelImagePropertySpec, ValuedPropertyProtocol {
|
|
4
|
-
func addListener(onChanged: @escaping () -> Void) throws {
|
|
5
|
-
try addListener(onChanged: { _ in onChanged() })
|
|
6
|
-
}
|
|
7
|
-
|
|
8
4
|
var property: ImagePropertyType!
|
|
9
5
|
lazy var helper = PropertyListenerHelper(property: property!)
|
|
10
6
|
|
|
7
|
+
func addListener(onChanged: @escaping () -> Void) throws -> () -> Void {
|
|
8
|
+
return helper.addListener { _ in onChanged() }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
11
|
init(property: ImagePropertyType) {
|
|
12
12
|
self.property = property
|
|
13
13
|
super.init()
|
|
@@ -6,12 +6,7 @@ class HybridViewModelInstance: HybridViewModelInstanceSpec {
|
|
|
6
6
|
init(viewModelInstance: RiveDataBindingViewModel.Instance) {
|
|
7
7
|
self.viewModelInstance = viewModelInstance
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
override init() {
|
|
11
|
-
self.viewModelInstance = nil
|
|
12
|
-
super.init()
|
|
13
|
-
}
|
|
14
|
-
|
|
9
|
+
|
|
15
10
|
var instanceName: String { viewModelInstance?.name ?? "" }
|
|
16
11
|
|
|
17
12
|
func numberProperty(path: String) throws -> (any HybridViewModelNumberPropertySpec)? {
|
|
@@ -48,4 +43,9 @@ class HybridViewModelInstance: HybridViewModelInstanceSpec {
|
|
|
48
43
|
guard let property = viewModelInstance?.imageProperty(fromPath: path) else { return nil }
|
|
49
44
|
return HybridViewModelImageProperty(property: property)
|
|
50
45
|
}
|
|
46
|
+
|
|
47
|
+
func listProperty(path: String) throws -> (any HybridViewModelListPropertySpec)? {
|
|
48
|
+
guard let property = viewModelInstance?.listProperty(fromPath: path) else { return nil }
|
|
49
|
+
return HybridViewModelListProperty(property: property)
|
|
50
|
+
}
|
|
51
51
|
}
|