@thelacanians/vue-native-cli 0.4.3 → 0.4.5
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/dist/cli.js +102 -32
- package/native/android/README.md +205 -0
- package/native/android/VueNativeCore/build.gradle.kts +113 -0
- package/native/android/VueNativeCore/consumer-rules.pro +12 -0
- package/native/android/VueNativeCore/proguard-rules.pro +33 -0
- package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +163 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
- package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
- package/native/android/app/build.gradle.kts +45 -0
- package/native/android/app/proguard-rules.pro +5 -0
- package/native/android/app/src/main/AndroidManifest.xml +25 -0
- package/native/android/app/src/main/assets/.gitkeep +0 -0
- package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
- package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
- package/native/android/app/src/main/res/values/strings.xml +3 -0
- package/native/android/app/src/main/res/values/themes.xml +9 -0
- package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
- package/native/android/build.gradle.kts +6 -0
- package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/native/android/gradle.properties +4 -0
- package/native/android/gradlew +87 -0
- package/native/android/gradlew.bat +48 -0
- package/native/android/settings.gradle.kts +20 -0
- package/native/ios/VueNativeCore/Package.resolved +23 -0
- package/native/ios/VueNativeCore/Package.swift +32 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +136 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +89 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +906 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +90 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +149 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +109 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +250 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +174 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/Extensions.swift +31 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +283 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +59 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +371 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +379 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +154 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +315 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +141 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +48 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +256 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
- package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
- package/package.json +3 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Protocol implemented by every native component factory.
|
|
9
|
+
* Mirrors Swift's NativeComponentFactory protocol.
|
|
10
|
+
*/
|
|
11
|
+
interface NativeComponentFactory {
|
|
12
|
+
fun createView(context: Context): View
|
|
13
|
+
fun updateProp(view: View, key: String, value: Any?)
|
|
14
|
+
fun addEventListener(view: View, event: String, handler: (Any?) -> Unit)
|
|
15
|
+
fun removeEventListener(view: View, event: String)
|
|
16
|
+
|
|
17
|
+
fun insertChild(parent: View, child: View, index: Int) {
|
|
18
|
+
(parent as? ViewGroup)?.let { vg ->
|
|
19
|
+
val lp = child.layoutParams ?: ViewGroup.LayoutParams(
|
|
20
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
21
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
22
|
+
)
|
|
23
|
+
if (index >= vg.childCount) vg.addView(child, lp)
|
|
24
|
+
else vg.addView(child, index, lp)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fun removeChild(parent: View, child: View) {
|
|
29
|
+
(parent as? ViewGroup)?.removeView(child)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Called when a view is being permanently destroyed (removed from tree).
|
|
34
|
+
* Override to clean up any factory-level state associated with this view
|
|
35
|
+
* to prevent memory leaks. Default implementation is a no-op.
|
|
36
|
+
*/
|
|
37
|
+
fun destroyView(view: View) {
|
|
38
|
+
// Default: no-op. Override in factories that maintain per-view state.
|
|
39
|
+
}
|
|
40
|
+
}
|
package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import android.widget.TextView
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Represents a JS text node (created by createTextNode).
|
|
9
|
+
* In Android, text nodes must be children of VText/VButton components.
|
|
10
|
+
* This is a lightweight TextView that text factories use to display text node content.
|
|
11
|
+
*/
|
|
12
|
+
class VTextNodeView(context: Context) : TextView(context) {
|
|
13
|
+
init {
|
|
14
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
15
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
16
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fun setText(text: String) {
|
|
21
|
+
super.setText(text)
|
|
22
|
+
}
|
|
23
|
+
}
|
package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Attaches gesture recognizers to a View and fires event handlers.
|
|
7
|
+
*/
|
|
8
|
+
object GestureHelper {
|
|
9
|
+
fun attachTap(view: View, handler: (Any?) -> Unit) {
|
|
10
|
+
view.setOnClickListener { handler(null) }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fun attachLongPress(view: View, handler: (Any?) -> Unit) {
|
|
14
|
+
view.setOnLongClickListener { handler(null); true }
|
|
15
|
+
}
|
|
16
|
+
}
|
package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.GestureDetector
|
|
5
|
+
import android.view.MotionEvent
|
|
6
|
+
import android.view.ViewGroup
|
|
7
|
+
import com.google.android.flexbox.AlignItems
|
|
8
|
+
import com.google.android.flexbox.FlexDirection
|
|
9
|
+
import com.google.android.flexbox.FlexboxLayout
|
|
10
|
+
import com.google.android.flexbox.JustifyContent
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Custom FlexboxLayout subclass that provides button-like touch behavior
|
|
14
|
+
* with configurable active opacity and support for press and long press events.
|
|
15
|
+
* Mirrors the Swift TouchableView (UIView subclass) for Android.
|
|
16
|
+
*/
|
|
17
|
+
open class TouchableView(context: Context) : FlexboxLayout(context) {
|
|
18
|
+
|
|
19
|
+
/** The opacity to apply when the user is pressing the view. */
|
|
20
|
+
var activeOpacity: Float = 1.0f
|
|
21
|
+
|
|
22
|
+
/** Called when a tap completes within the view bounds. */
|
|
23
|
+
var onPress: (() -> Unit)? = null
|
|
24
|
+
|
|
25
|
+
/** Called when a long press gesture is recognized. */
|
|
26
|
+
var onLongPress: (() -> Unit)? = null
|
|
27
|
+
|
|
28
|
+
/** Whether touch interactions are disabled. */
|
|
29
|
+
var isDisabled: Boolean = false
|
|
30
|
+
set(value) {
|
|
31
|
+
field = value
|
|
32
|
+
isEnabled = !value
|
|
33
|
+
isClickable = !value
|
|
34
|
+
alpha = if (value) 0.4f else 1.0f
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private var isTouchInside: Boolean = false
|
|
38
|
+
private var longPressDetected: Boolean = false
|
|
39
|
+
|
|
40
|
+
private val gestureDetector: GestureDetector
|
|
41
|
+
|
|
42
|
+
init {
|
|
43
|
+
flexDirection = FlexDirection.ROW
|
|
44
|
+
alignItems = AlignItems.CENTER
|
|
45
|
+
justifyContent = JustifyContent.CENTER
|
|
46
|
+
isClickable = true
|
|
47
|
+
isFocusable = true
|
|
48
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
49
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
50
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
|
54
|
+
override fun onLongPress(e: MotionEvent) {
|
|
55
|
+
if (!isDisabled) {
|
|
56
|
+
longPressDetected = true
|
|
57
|
+
this@TouchableView.onLongPress?.invoke()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
64
|
+
if (isDisabled) return false
|
|
65
|
+
|
|
66
|
+
gestureDetector.onTouchEvent(event)
|
|
67
|
+
|
|
68
|
+
when (event.action) {
|
|
69
|
+
MotionEvent.ACTION_DOWN -> {
|
|
70
|
+
isTouchInside = true
|
|
71
|
+
longPressDetected = false
|
|
72
|
+
animate().alpha(activeOpacity).setDuration(100).start()
|
|
73
|
+
return true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
MotionEvent.ACTION_MOVE -> {
|
|
77
|
+
val wasInside = isTouchInside
|
|
78
|
+
isTouchInside = event.x >= 0 && event.x <= width &&
|
|
79
|
+
event.y >= 0 && event.y <= height
|
|
80
|
+
|
|
81
|
+
if (wasInside != isTouchInside) {
|
|
82
|
+
val targetAlpha = if (isTouchInside) activeOpacity else 1.0f
|
|
83
|
+
animate().alpha(targetAlpha).setDuration(100).start()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
MotionEvent.ACTION_UP -> {
|
|
88
|
+
animate().alpha(1.0f).setDuration(150).start()
|
|
89
|
+
if (isTouchInside && !longPressDetected) {
|
|
90
|
+
onPress?.invoke()
|
|
91
|
+
}
|
|
92
|
+
isTouchInside = false
|
|
93
|
+
longPressDetected = false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
MotionEvent.ACTION_CANCEL -> {
|
|
97
|
+
animate().alpha(1.0f).setDuration(150).start()
|
|
98
|
+
isTouchInside = false
|
|
99
|
+
longPressDetected = false
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return super.onTouchEvent(event)
|
|
104
|
+
}
|
|
105
|
+
}
|
package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.animation.Animator
|
|
4
|
+
import android.animation.AnimatorListenerAdapter
|
|
5
|
+
import android.animation.AnimatorSet
|
|
6
|
+
import android.animation.Keyframe
|
|
7
|
+
import android.animation.ObjectAnimator
|
|
8
|
+
import android.animation.PropertyValuesHolder
|
|
9
|
+
import android.content.Context
|
|
10
|
+
import android.os.Handler
|
|
11
|
+
import android.os.Looper
|
|
12
|
+
import android.view.View
|
|
13
|
+
import android.view.animation.AccelerateDecelerateInterpolator
|
|
14
|
+
import android.view.animation.AccelerateInterpolator
|
|
15
|
+
import android.view.animation.DecelerateInterpolator
|
|
16
|
+
import android.view.animation.LinearInterpolator
|
|
17
|
+
|
|
18
|
+
class AnimationModule : NativeModule {
|
|
19
|
+
override val moduleName = "Animation"
|
|
20
|
+
private var context: Context? = null
|
|
21
|
+
private var bridge: NativeBridge? = null
|
|
22
|
+
private val mainHandler = Handler(Looper.getMainLooper())
|
|
23
|
+
|
|
24
|
+
override fun initialize(context: Context, bridge: NativeBridge) {
|
|
25
|
+
this.context = context; this.bridge = bridge
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun invoke(method: String, args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
29
|
+
when (method) {
|
|
30
|
+
"timing" -> handleTiming(args, bridge, callback)
|
|
31
|
+
"spring" -> handleSpring(args, bridge, callback)
|
|
32
|
+
"keyframe" -> handleKeyframe(args, bridge, callback)
|
|
33
|
+
"sequence" -> handleSequence(args, bridge, callback)
|
|
34
|
+
"parallel" -> handleParallel(args, bridge, callback)
|
|
35
|
+
"fadeIn" -> {
|
|
36
|
+
val nodeId = StyleEngine.toInt(args.getOrNull(0), -1)
|
|
37
|
+
val view = bridge.nodeViews[nodeId] ?: run { callback(null, null); return }
|
|
38
|
+
mainHandler.post {
|
|
39
|
+
view.alpha = 0f; view.visibility = View.VISIBLE
|
|
40
|
+
view.animate().alpha(1f).setDuration(300).withEndAction { callback(null, null) }.start()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
"fadeOut" -> {
|
|
44
|
+
val nodeId = StyleEngine.toInt(args.getOrNull(0), -1)
|
|
45
|
+
val view = bridge.nodeViews[nodeId] ?: run { callback(null, null); return }
|
|
46
|
+
mainHandler.post {
|
|
47
|
+
view.animate().alpha(0f).setDuration(300).withEndAction {
|
|
48
|
+
view.visibility = View.INVISIBLE
|
|
49
|
+
callback(null, null)
|
|
50
|
+
}.start()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else -> callback(null, "Unknown animation method: $method")
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ── timing(viewId, toStyles, options) ──────────────────────────────────
|
|
58
|
+
// args[0]: nodeId (Int)
|
|
59
|
+
// args[1]: toStyles map { "opacity": 1, "translateX": 100 }
|
|
60
|
+
// args[2]: options { duration, delay, easing }
|
|
61
|
+
|
|
62
|
+
private fun handleTiming(args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
63
|
+
val nodeId = StyleEngine.toInt(args.getOrNull(0), -1)
|
|
64
|
+
val toStyles = toStringKeyMap(args.getOrNull(1)) ?: emptyMap()
|
|
65
|
+
val options = toStringKeyMap(args.getOrNull(2)) ?: emptyMap()
|
|
66
|
+
|
|
67
|
+
val duration = StyleEngine.toInt(options["duration"], 300).toLong()
|
|
68
|
+
val delay = StyleEngine.toInt(options["delay"], 0).toLong()
|
|
69
|
+
val easing = options["easing"]?.toString() ?: "easeInOut"
|
|
70
|
+
|
|
71
|
+
val view = bridge.nodeViews[nodeId] ?: run { callback(null, "timing: view $nodeId not found"); return }
|
|
72
|
+
|
|
73
|
+
mainHandler.post {
|
|
74
|
+
val animators = buildPropertyAnimators(view, toStyles)
|
|
75
|
+
if (animators.isEmpty()) { callback(true, null); return@post }
|
|
76
|
+
|
|
77
|
+
val interpolator = resolveInterpolator(easing)
|
|
78
|
+
val set = AnimatorSet()
|
|
79
|
+
set.playTogether(animators)
|
|
80
|
+
set.duration = duration
|
|
81
|
+
set.startDelay = delay
|
|
82
|
+
set.interpolator = interpolator
|
|
83
|
+
set.addListener(object : AnimatorListenerAdapter() {
|
|
84
|
+
override fun onAnimationEnd(a: Animator) { callback(true, null) }
|
|
85
|
+
})
|
|
86
|
+
set.start()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── spring(viewId, toStyles, options) ──────────────────────────────────
|
|
91
|
+
// args[0]: nodeId
|
|
92
|
+
// args[1]: toStyles map
|
|
93
|
+
// args[2]: options { damping/tension/friction, duration, delay }
|
|
94
|
+
|
|
95
|
+
private fun handleSpring(args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
96
|
+
val nodeId = StyleEngine.toInt(args.getOrNull(0), -1)
|
|
97
|
+
val toStyles = toStringKeyMap(args.getOrNull(1)) ?: emptyMap()
|
|
98
|
+
val options = toStringKeyMap(args.getOrNull(2)) ?: emptyMap()
|
|
99
|
+
|
|
100
|
+
val duration = StyleEngine.toInt(options["duration"], 500).toLong()
|
|
101
|
+
val delay = StyleEngine.toInt(options["delay"], 0).toLong()
|
|
102
|
+
|
|
103
|
+
val view = bridge.nodeViews[nodeId] ?: run { callback(null, "spring: view $nodeId not found"); return }
|
|
104
|
+
|
|
105
|
+
mainHandler.post {
|
|
106
|
+
val animators = buildPropertyAnimators(view, toStyles)
|
|
107
|
+
if (animators.isEmpty()) { callback(true, null); return@post }
|
|
108
|
+
|
|
109
|
+
// Android doesn't have built-in spring for ObjectAnimator pre-API 23 DynamicAnimation.
|
|
110
|
+
// Use overshoot interpolator to approximate spring feel.
|
|
111
|
+
val set = AnimatorSet()
|
|
112
|
+
set.playTogether(animators)
|
|
113
|
+
set.duration = duration
|
|
114
|
+
set.startDelay = delay
|
|
115
|
+
set.interpolator = android.view.animation.OvershootInterpolator(1.5f)
|
|
116
|
+
set.addListener(object : AnimatorListenerAdapter() {
|
|
117
|
+
override fun onAnimationEnd(a: Animator) { callback(true, null) }
|
|
118
|
+
})
|
|
119
|
+
set.start()
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ── keyframe(viewId, keyframeSteps, options) ───────────────────────────
|
|
124
|
+
// args[0]: nodeId
|
|
125
|
+
// args[1]: List<Map> keyframe steps [{ offset: 0.0, opacity: 1 }, ...]
|
|
126
|
+
// args[2]: options { duration }
|
|
127
|
+
|
|
128
|
+
private fun handleKeyframe(args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
129
|
+
val nodeId = StyleEngine.toInt(args.getOrNull(0), -1)
|
|
130
|
+
val stepsRaw = args.getOrNull(1) as? List<*> ?: run { callback(null, "keyframe: invalid keyframes"); return }
|
|
131
|
+
val options = toStringKeyMap(args.getOrNull(2)) ?: emptyMap()
|
|
132
|
+
val duration = StyleEngine.toInt(options["duration"], 300).toLong()
|
|
133
|
+
|
|
134
|
+
val view = bridge.nodeViews[nodeId] ?: run { callback(null, "keyframe: view $nodeId not found"); return }
|
|
135
|
+
|
|
136
|
+
// Parse keyframe steps into Map<String, List<Pair<Float, Float>>> (property -> [(offset, value)])
|
|
137
|
+
val propertyKeyframes = mutableMapOf<String, MutableList<Pair<Float, Float>>>()
|
|
138
|
+
for (raw in stepsRaw) {
|
|
139
|
+
val step = toStringKeyMap(raw) ?: continue
|
|
140
|
+
val offset = StyleEngine.toFloat(step["offset"], 0f)
|
|
141
|
+
for ((key, value) in step) {
|
|
142
|
+
if (key == "offset") continue
|
|
143
|
+
val floatVal = StyleEngine.toFloat(value, Float.NaN)
|
|
144
|
+
if (floatVal.isNaN()) continue
|
|
145
|
+
propertyKeyframes.getOrPut(key) { mutableListOf() }.add(offset to floatVal)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (propertyKeyframes.isEmpty()) { callback(null, null); return }
|
|
150
|
+
|
|
151
|
+
mainHandler.post {
|
|
152
|
+
val animators = mutableListOf<Animator>()
|
|
153
|
+
|
|
154
|
+
for ((propKey, frames) in propertyKeyframes) {
|
|
155
|
+
val androidProps = mapPropertyName(propKey)
|
|
156
|
+
for (androidProp in androidProps) {
|
|
157
|
+
val kfs = frames.map { (offset, value) ->
|
|
158
|
+
Keyframe.ofFloat(offset, value)
|
|
159
|
+
}.toTypedArray()
|
|
160
|
+
val pvh = PropertyValuesHolder.ofKeyframe(androidProp, *kfs)
|
|
161
|
+
val animator = ObjectAnimator.ofPropertyValuesHolder(view, pvh)
|
|
162
|
+
animator.duration = duration
|
|
163
|
+
animators.add(animator)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (animators.isEmpty()) { callback(null, null); return@post }
|
|
168
|
+
|
|
169
|
+
val set = AnimatorSet()
|
|
170
|
+
set.playTogether(animators)
|
|
171
|
+
set.addListener(object : AnimatorListenerAdapter() {
|
|
172
|
+
override fun onAnimationEnd(a: Animator) { callback(null, null) }
|
|
173
|
+
})
|
|
174
|
+
set.start()
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ── sequence(animations) ───────────────────────────────────────────────
|
|
179
|
+
// args[0]: List<Map> animations [{ type, viewId, toStyles, options }, ...]
|
|
180
|
+
|
|
181
|
+
private fun handleSequence(args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
182
|
+
val animationsRaw = args.getOrNull(0) as? List<*> ?: run { callback(null, "sequence: invalid args"); return }
|
|
183
|
+
val animations = animationsRaw.mapNotNull { toStringKeyMap(it) }
|
|
184
|
+
if (animations.isEmpty()) { callback(null, null); return }
|
|
185
|
+
|
|
186
|
+
runSequenceStep(animations, 0, bridge, callback)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun runSequenceStep(
|
|
190
|
+
animations: List<Map<String, Any?>>,
|
|
191
|
+
index: Int,
|
|
192
|
+
bridge: NativeBridge,
|
|
193
|
+
callback: (Any?, String?) -> Unit
|
|
194
|
+
) {
|
|
195
|
+
if (index >= animations.size) { callback(null, null); return }
|
|
196
|
+
|
|
197
|
+
val animData = animations[index]
|
|
198
|
+
val method = animData["type"]?.toString() ?: "timing"
|
|
199
|
+
val viewId = StyleEngine.toInt(animData["viewId"], 0)
|
|
200
|
+
val toStyles = toStringKeyMap(animData["toStyles"]) ?: emptyMap()
|
|
201
|
+
val options = toStringKeyMap(animData["options"]) ?: emptyMap()
|
|
202
|
+
|
|
203
|
+
val subArgs: List<Any?> = listOf(viewId, toStyles, options)
|
|
204
|
+
invoke(method, subArgs, bridge) { _, error ->
|
|
205
|
+
if (error != null) { callback(null, error); return@invoke }
|
|
206
|
+
runSequenceStep(animations, index + 1, bridge, callback)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ── parallel(animations) ───────────────────────────────────────────────
|
|
211
|
+
// args[0]: List<Map> animations [{ type, viewId, toStyles, options }, ...]
|
|
212
|
+
|
|
213
|
+
private fun handleParallel(args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
214
|
+
val animationsRaw = args.getOrNull(0) as? List<*> ?: run { callback(null, "parallel: invalid args"); return }
|
|
215
|
+
val animations = animationsRaw.mapNotNull { toStringKeyMap(it) }
|
|
216
|
+
if (animations.isEmpty()) { callback(null, null); return }
|
|
217
|
+
|
|
218
|
+
val total = animations.size
|
|
219
|
+
var completed = 0
|
|
220
|
+
val lock = Object()
|
|
221
|
+
|
|
222
|
+
for (animData in animations) {
|
|
223
|
+
val method = animData["type"]?.toString() ?: "timing"
|
|
224
|
+
val viewId = StyleEngine.toInt(animData["viewId"], 0)
|
|
225
|
+
val toStyles = toStringKeyMap(animData["toStyles"]) ?: emptyMap()
|
|
226
|
+
val options = toStringKeyMap(animData["options"]) ?: emptyMap()
|
|
227
|
+
|
|
228
|
+
val subArgs: List<Any?> = listOf(viewId, toStyles, options)
|
|
229
|
+
invoke(method, subArgs, bridge) { _, _ ->
|
|
230
|
+
val allDone: Boolean
|
|
231
|
+
synchronized(lock) {
|
|
232
|
+
completed++
|
|
233
|
+
allDone = completed == total
|
|
234
|
+
}
|
|
235
|
+
if (allDone) callback(null, null)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Build a list of ObjectAnimator from a toStyles map like { opacity: 1, translateX: 100 }.
|
|
244
|
+
* Each style key maps to one or more Android View properties.
|
|
245
|
+
*/
|
|
246
|
+
private fun buildPropertyAnimators(view: View, toStyles: Map<String, Any?>): List<Animator> {
|
|
247
|
+
val animators = mutableListOf<Animator>()
|
|
248
|
+
for ((key, value) in toStyles) {
|
|
249
|
+
val toValue = StyleEngine.toFloat(value, Float.NaN)
|
|
250
|
+
if (toValue.isNaN()) continue
|
|
251
|
+
val androidProps = mapPropertyName(key)
|
|
252
|
+
for (prop in androidProps) {
|
|
253
|
+
animators.add(ObjectAnimator.ofFloat(view, prop, toValue))
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return animators
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Map a JS-side property name to Android View property name(s).
|
|
261
|
+
* "scale" maps to both "scaleX" and "scaleY".
|
|
262
|
+
*/
|
|
263
|
+
private fun mapPropertyName(propKey: String): List<String> = when (propKey) {
|
|
264
|
+
"opacity" -> listOf("alpha")
|
|
265
|
+
"translateX" -> listOf("translationX")
|
|
266
|
+
"translateY" -> listOf("translationY")
|
|
267
|
+
"scale" -> listOf("scaleX", "scaleY")
|
|
268
|
+
"scaleX" -> listOf("scaleX")
|
|
269
|
+
"scaleY" -> listOf("scaleY")
|
|
270
|
+
"rotate" -> listOf("rotation")
|
|
271
|
+
else -> emptyList()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Resolve an easing string to an Android Interpolator.
|
|
276
|
+
*/
|
|
277
|
+
private fun resolveInterpolator(easing: String) = when (easing) {
|
|
278
|
+
"linear" -> LinearInterpolator()
|
|
279
|
+
"ease-in", "easeIn" -> AccelerateInterpolator()
|
|
280
|
+
"ease-out", "easeOut" -> DecelerateInterpolator()
|
|
281
|
+
else -> AccelerateDecelerateInterpolator() // "easeInOut", "ease", default
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Safely cast Any? to Map<String, Any?>, handling Map<*, *> from J2V8/JSON deserialization.
|
|
286
|
+
*/
|
|
287
|
+
private fun toStringKeyMap(value: Any?): Map<String, Any?>? {
|
|
288
|
+
val map = value as? Map<*, *> ?: return null
|
|
289
|
+
@Suppress("UNCHECKED_CAST")
|
|
290
|
+
return map as Map<String, Any?>
|
|
291
|
+
}
|
|
292
|
+
}
|
package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Handler
|
|
5
|
+
import android.os.Looper
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import androidx.lifecycle.DefaultLifecycleObserver
|
|
8
|
+
import androidx.lifecycle.LifecycleOwner
|
|
9
|
+
import androidx.lifecycle.ProcessLifecycleOwner
|
|
10
|
+
|
|
11
|
+
class AppStateModule : NativeModule {
|
|
12
|
+
override val moduleName = "AppState"
|
|
13
|
+
private var currentState = "active"
|
|
14
|
+
|
|
15
|
+
override fun initialize(context: Context, bridge: NativeBridge) {
|
|
16
|
+
val mainHandler = Handler(Looper.getMainLooper())
|
|
17
|
+
mainHandler.post {
|
|
18
|
+
try {
|
|
19
|
+
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
|
|
20
|
+
override fun onStart(owner: LifecycleOwner) {
|
|
21
|
+
currentState = "active"
|
|
22
|
+
bridge.dispatchGlobalEvent("appState:change", mapOf("state" to "active"))
|
|
23
|
+
}
|
|
24
|
+
override fun onStop(owner: LifecycleOwner) {
|
|
25
|
+
currentState = "background"
|
|
26
|
+
bridge.dispatchGlobalEvent("appState:change", mapOf("state" to "background"))
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
} catch (e: Exception) {
|
|
30
|
+
Log.e("VueNative", "AppStateModule init failed", e)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun invoke(method: String, args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
36
|
+
when (method) {
|
|
37
|
+
"getState" -> callback(mapOf("state" to currentState), null)
|
|
38
|
+
else -> callback(null, "Unknown method: $method")
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.SharedPreferences
|
|
5
|
+
|
|
6
|
+
class AsyncStorageModule : NativeModule {
|
|
7
|
+
override val moduleName = "AsyncStorage"
|
|
8
|
+
private var prefs: SharedPreferences? = null
|
|
9
|
+
|
|
10
|
+
override fun initialize(context: Context, bridge: NativeBridge) {
|
|
11
|
+
prefs = context.getSharedPreferences("vue_native_async_storage", Context.MODE_PRIVATE)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun invoke(method: String, args: List<Any?>, bridge: NativeBridge, callback: (Any?, String?) -> Unit) {
|
|
15
|
+
val p = prefs ?: run { callback(null, "Storage not initialized"); return }
|
|
16
|
+
when (method) {
|
|
17
|
+
"getItem" -> {
|
|
18
|
+
val key = args.getOrNull(0)?.toString() ?: run { callback(null, "Missing key"); return }
|
|
19
|
+
callback(p.getString(key, null), null)
|
|
20
|
+
}
|
|
21
|
+
"setItem" -> {
|
|
22
|
+
val key = args.getOrNull(0)?.toString() ?: run { callback(null, "Missing key"); return }
|
|
23
|
+
val value = args.getOrNull(1)?.toString() ?: run { callback(null, "Missing value"); return }
|
|
24
|
+
p.edit().putString(key, value).apply()
|
|
25
|
+
callback(null, null)
|
|
26
|
+
}
|
|
27
|
+
"removeItem" -> {
|
|
28
|
+
val key = args.getOrNull(0)?.toString() ?: run { callback(null, "Missing key"); return }
|
|
29
|
+
p.edit().remove(key).apply()
|
|
30
|
+
callback(null, null)
|
|
31
|
+
}
|
|
32
|
+
"getAllKeys" -> {
|
|
33
|
+
callback(p.all.keys.toList(), null)
|
|
34
|
+
}
|
|
35
|
+
"clear" -> {
|
|
36
|
+
p.edit().clear().apply()
|
|
37
|
+
callback(null, null)
|
|
38
|
+
}
|
|
39
|
+
"multiGet" -> {
|
|
40
|
+
val keys = (args.getOrNull(0) as? List<*>)?.map { it?.toString() ?: "" } ?: emptyList()
|
|
41
|
+
val result = keys.map { k -> listOf(k, p.getString(k, null)) }
|
|
42
|
+
callback(result, null)
|
|
43
|
+
}
|
|
44
|
+
"multiSet" -> {
|
|
45
|
+
val pairs = args.getOrNull(0) as? List<*> ?: emptyList<Any>()
|
|
46
|
+
val editor = p.edit()
|
|
47
|
+
pairs.forEach { pair ->
|
|
48
|
+
val kv = pair as? List<*>
|
|
49
|
+
val k = kv?.getOrNull(0)?.toString()
|
|
50
|
+
val v = kv?.getOrNull(1)?.toString()
|
|
51
|
+
if (k != null && v != null) editor.putString(k, v)
|
|
52
|
+
}
|
|
53
|
+
editor.apply()
|
|
54
|
+
callback(null, null)
|
|
55
|
+
}
|
|
56
|
+
else -> callback(null, "Unknown method: $method")
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|