@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.
Files changed (173) hide show
  1. package/dist/cli.js +102 -32
  2. package/native/android/README.md +205 -0
  3. package/native/android/VueNativeCore/build.gradle.kts +113 -0
  4. package/native/android/VueNativeCore/consumer-rules.pro +12 -0
  5. package/native/android/VueNativeCore/proguard-rules.pro +33 -0
  6. package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
  7. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
  8. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
  9. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
  10. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
  11. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
  12. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
  13. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
  14. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
  15. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
  16. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
  17. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
  18. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
  19. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
  20. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
  21. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
  22. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
  23. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
  24. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
  25. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
  26. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
  27. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
  28. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
  29. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
  30. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
  31. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
  32. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
  33. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
  34. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
  35. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
  36. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
  37. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
  38. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
  39. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
  40. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
  41. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
  42. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
  43. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
  44. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
  45. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
  46. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
  47. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
  48. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
  49. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
  50. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
  51. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
  52. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
  53. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
  54. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
  55. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
  56. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
  57. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
  58. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
  59. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
  60. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
  61. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
  62. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
  63. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
  64. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
  65. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
  66. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
  67. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
  68. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
  69. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
  70. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
  71. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
  72. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
  73. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
  74. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
  75. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +163 -0
  76. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
  77. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
  78. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
  79. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
  80. package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
  81. package/native/android/app/build.gradle.kts +45 -0
  82. package/native/android/app/proguard-rules.pro +5 -0
  83. package/native/android/app/src/main/AndroidManifest.xml +25 -0
  84. package/native/android/app/src/main/assets/.gitkeep +0 -0
  85. package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
  86. package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
  87. package/native/android/app/src/main/res/values/strings.xml +3 -0
  88. package/native/android/app/src/main/res/values/themes.xml +9 -0
  89. package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
  90. package/native/android/build.gradle.kts +6 -0
  91. package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  92. package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  93. package/native/android/gradle.properties +4 -0
  94. package/native/android/gradlew +87 -0
  95. package/native/android/gradlew.bat +48 -0
  96. package/native/android/settings.gradle.kts +20 -0
  97. package/native/ios/VueNativeCore/Package.resolved +23 -0
  98. package/native/ios/VueNativeCore/Package.swift +32 -0
  99. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +136 -0
  100. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +89 -0
  101. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
  102. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
  103. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
  104. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +906 -0
  105. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
  106. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
  107. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +90 -0
  108. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
  109. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +149 -0
  110. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
  111. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
  112. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
  113. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
  114. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
  115. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
  116. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
  117. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +109 -0
  118. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
  119. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
  120. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
  121. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
  122. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
  123. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
  124. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
  125. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
  126. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
  127. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
  128. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
  129. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
  130. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
  131. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +250 -0
  132. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
  133. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +174 -0
  134. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
  135. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/Extensions.swift +31 -0
  136. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
  137. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
  138. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
  139. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +283 -0
  140. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +59 -0
  141. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
  142. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +371 -0
  143. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
  144. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
  145. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +379 -0
  146. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +154 -0
  147. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +315 -0
  148. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
  149. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
  150. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
  151. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
  152. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
  153. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
  154. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
  155. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
  156. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
  157. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
  158. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
  159. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
  160. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
  161. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
  162. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
  163. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +141 -0
  164. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
  165. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
  166. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
  167. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +48 -0
  168. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +256 -0
  169. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
  170. package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
  171. package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
  172. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
  173. 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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }