@thelacanians/vue-native-cli 0.4.3 → 0.4.4
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 +34 -17
- package/native/android/README.md +205 -0
- package/native/android/VueNativeCore/build.gradle.kts +100 -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 +160 -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 +132 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +92 -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 +891 -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 +91 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +150 -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 +112 -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 +246 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +172 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -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 +291 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +65 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +366 -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 +387 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +161 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +318 -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 +138 -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 +49 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +240 -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,210 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.text.Editable
|
|
6
|
+
import android.text.InputFilter
|
|
7
|
+
import android.text.InputType
|
|
8
|
+
import android.text.TextWatcher
|
|
9
|
+
import android.view.View
|
|
10
|
+
import android.view.ViewGroup
|
|
11
|
+
import android.view.inputmethod.EditorInfo
|
|
12
|
+
import android.widget.EditText
|
|
13
|
+
|
|
14
|
+
class VInputFactory : NativeComponentFactory {
|
|
15
|
+
private val changeHandlers = mutableMapOf<EditText, (Any?) -> Unit>()
|
|
16
|
+
private val submitHandlers = mutableMapOf<EditText, (Any?) -> Unit>()
|
|
17
|
+
private val focusHandlers = mutableMapOf<EditText, (Any?) -> Unit>()
|
|
18
|
+
private val blurHandlers = mutableMapOf<EditText, (Any?) -> Unit>()
|
|
19
|
+
private val textWatchers = mutableMapOf<EditText, TextWatcher>()
|
|
20
|
+
|
|
21
|
+
override fun createView(context: Context): View {
|
|
22
|
+
return EditText(context).apply {
|
|
23
|
+
setBackgroundColor(Color.TRANSPARENT)
|
|
24
|
+
setPadding(0, 0, 0, 0)
|
|
25
|
+
textSize = 16f
|
|
26
|
+
setTextColor(Color.BLACK)
|
|
27
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
28
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
29
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
override fun updateProp(view: View, key: String, value: Any?) {
|
|
35
|
+
val et = view as? EditText ?: return
|
|
36
|
+
when (key) {
|
|
37
|
+
"text", "value" -> {
|
|
38
|
+
val newText = value?.toString() ?: ""
|
|
39
|
+
if (et.text.toString() != newText) {
|
|
40
|
+
et.setText(newText)
|
|
41
|
+
et.setSelection(newText.length)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
"placeholder" -> et.hint = value?.toString()
|
|
45
|
+
"placeholderColor", "placeholderTextColor" -> {
|
|
46
|
+
val color = StyleEngine.parseColor(value)
|
|
47
|
+
if (color != null) et.setHintTextColor(color)
|
|
48
|
+
}
|
|
49
|
+
"editable" -> et.isEnabled = value != false && value != "false"
|
|
50
|
+
"keyboardType" -> {
|
|
51
|
+
et.inputType = when (value) {
|
|
52
|
+
"numeric", "number-pad", "decimal-pad" ->
|
|
53
|
+
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
|
|
54
|
+
"email-address", "email" ->
|
|
55
|
+
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
|
56
|
+
"phone-pad", "phone" -> InputType.TYPE_CLASS_PHONE
|
|
57
|
+
"url" -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
|
|
58
|
+
else -> InputType.TYPE_CLASS_TEXT
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
"secureTextEntry" -> {
|
|
62
|
+
if (value == true || value == "true") {
|
|
63
|
+
et.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
"multiline" -> {
|
|
67
|
+
if (value == true || value == "true") {
|
|
68
|
+
et.inputType = et.inputType or InputType.TYPE_TEXT_FLAG_MULTI_LINE
|
|
69
|
+
et.isSingleLine = false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
"returnKeyType" -> {
|
|
73
|
+
et.imeOptions = when (value) {
|
|
74
|
+
"done" -> EditorInfo.IME_ACTION_DONE
|
|
75
|
+
"go" -> EditorInfo.IME_ACTION_GO
|
|
76
|
+
"next" -> EditorInfo.IME_ACTION_NEXT
|
|
77
|
+
"search" -> EditorInfo.IME_ACTION_SEARCH
|
|
78
|
+
"send" -> EditorInfo.IME_ACTION_SEND
|
|
79
|
+
else -> EditorInfo.IME_ACTION_DONE
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
"maxLength" -> {
|
|
83
|
+
val n = StyleEngine.toInt(value, 0)
|
|
84
|
+
if (n > 0) {
|
|
85
|
+
et.filters = arrayOf(InputFilter.LengthFilter(n))
|
|
86
|
+
} else {
|
|
87
|
+
// Remove length filter
|
|
88
|
+
et.filters = et.filters.filter { it !is InputFilter.LengthFilter }.toTypedArray()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
"autoCapitalize", "autocapitalize" -> {
|
|
92
|
+
// Clear existing cap flags first
|
|
93
|
+
val baseType = et.inputType and
|
|
94
|
+
(InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS or
|
|
95
|
+
InputType.TYPE_TEXT_FLAG_CAP_WORDS or
|
|
96
|
+
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES).inv()
|
|
97
|
+
et.inputType = when (value) {
|
|
98
|
+
"characters", "allCharacters" -> baseType or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
|
|
99
|
+
"words" -> baseType or InputType.TYPE_TEXT_FLAG_CAP_WORDS
|
|
100
|
+
"sentences" -> baseType or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
|
|
101
|
+
"none" -> baseType
|
|
102
|
+
else -> baseType or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
"autoCorrect", "autocorrect" -> {
|
|
106
|
+
if (value == true || value == "true") {
|
|
107
|
+
et.inputType = et.inputType or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
|
|
108
|
+
} else if (value == false || value == "false") {
|
|
109
|
+
et.inputType = et.inputType and InputType.TYPE_TEXT_FLAG_AUTO_CORRECT.inv()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
"textAlign", "textAlignment" -> {
|
|
113
|
+
et.textAlignment = when (value) {
|
|
114
|
+
"left" -> View.TEXT_ALIGNMENT_TEXT_START
|
|
115
|
+
"center" -> View.TEXT_ALIGNMENT_CENTER
|
|
116
|
+
"right" -> View.TEXT_ALIGNMENT_TEXT_END
|
|
117
|
+
else -> View.TEXT_ALIGNMENT_TEXT_START
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
"color" -> {
|
|
121
|
+
val color = StyleEngine.parseColor(value)
|
|
122
|
+
if (color != null) et.setTextColor(color)
|
|
123
|
+
}
|
|
124
|
+
"fontSize" -> {
|
|
125
|
+
val size = when (value) {
|
|
126
|
+
is Number -> value.toFloat()
|
|
127
|
+
is String -> value.toFloatOrNull()
|
|
128
|
+
else -> null
|
|
129
|
+
}
|
|
130
|
+
if (size != null) et.textSize = size
|
|
131
|
+
}
|
|
132
|
+
else -> StyleEngine.apply(key, value, view)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
override fun addEventListener(view: View, event: String, handler: (Any?) -> Unit) {
|
|
137
|
+
val et = view as? EditText ?: return
|
|
138
|
+
when (event) {
|
|
139
|
+
"change", "input", "changetext" -> {
|
|
140
|
+
changeHandlers[et] = handler
|
|
141
|
+
// Remove old watcher if any
|
|
142
|
+
textWatchers[et]?.let { et.removeTextChangedListener(it) }
|
|
143
|
+
val watcher = object : TextWatcher {
|
|
144
|
+
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
|
145
|
+
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
|
146
|
+
override fun afterTextChanged(s: Editable?) {
|
|
147
|
+
changeHandlers[et]?.invoke(mapOf("value" to (s?.toString() ?: "")))
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
textWatchers[et] = watcher
|
|
151
|
+
et.addTextChangedListener(watcher)
|
|
152
|
+
}
|
|
153
|
+
"submit" -> {
|
|
154
|
+
submitHandlers[et] = handler
|
|
155
|
+
et.setOnEditorActionListener { _, _, _ ->
|
|
156
|
+
submitHandlers[et]?.invoke(mapOf("value" to et.text.toString()))
|
|
157
|
+
true
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
"focus" -> {
|
|
161
|
+
focusHandlers[et] = handler
|
|
162
|
+
ensureFocusListener(et)
|
|
163
|
+
}
|
|
164
|
+
"blur" -> {
|
|
165
|
+
blurHandlers[et] = handler
|
|
166
|
+
ensureFocusListener(et)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
override fun removeEventListener(view: View, event: String) {
|
|
172
|
+
val et = view as? EditText ?: return
|
|
173
|
+
when (event) {
|
|
174
|
+
"change", "input", "changetext" -> {
|
|
175
|
+
changeHandlers.remove(et)
|
|
176
|
+
textWatchers.remove(et)?.let { et.removeTextChangedListener(it) }
|
|
177
|
+
}
|
|
178
|
+
"submit" -> {
|
|
179
|
+
submitHandlers.remove(et)
|
|
180
|
+
et.setOnEditorActionListener(null)
|
|
181
|
+
}
|
|
182
|
+
"focus" -> {
|
|
183
|
+
focusHandlers.remove(et)
|
|
184
|
+
if (blurHandlers[et] == null) {
|
|
185
|
+
et.onFocusChangeListener = null
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
"blur" -> {
|
|
189
|
+
blurHandlers.remove(et)
|
|
190
|
+
if (focusHandlers[et] == null) {
|
|
191
|
+
et.onFocusChangeListener = null
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Sets a single OnFocusChangeListener that dispatches to both focus and blur handlers.
|
|
199
|
+
* This avoids the problem of one listener overwriting the other.
|
|
200
|
+
*/
|
|
201
|
+
private fun ensureFocusListener(et: EditText) {
|
|
202
|
+
et.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
|
|
203
|
+
if (hasFocus) {
|
|
204
|
+
focusHandlers[et]?.invoke(null)
|
|
205
|
+
} else {
|
|
206
|
+
blurHandlers[et]?.invoke(null)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.view.ViewTreeObserver
|
|
7
|
+
import com.google.android.flexbox.FlexDirection
|
|
8
|
+
import com.google.android.flexbox.FlexboxLayout
|
|
9
|
+
|
|
10
|
+
class VKeyboardAvoidingFactory : NativeComponentFactory {
|
|
11
|
+
override fun createView(context: Context): View {
|
|
12
|
+
val flex = FlexboxLayout(context).apply {
|
|
13
|
+
flexDirection = FlexDirection.COLUMN
|
|
14
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
15
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
16
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
// The Activity sets android:windowSoftInputMode="adjustResize" which
|
|
20
|
+
// makes the system handle keyboard avoidance automatically on Android.
|
|
21
|
+
return flex
|
|
22
|
+
}
|
|
23
|
+
override fun updateProp(view: View, key: String, value: Any?) = StyleEngine.apply(key, value, view)
|
|
24
|
+
override fun addEventListener(view: View, event: String, handler: (Any?) -> Unit) {}
|
|
25
|
+
override fun removeEventListener(view: View, event: String) {}
|
|
26
|
+
override fun insertChild(parent: View, child: View, index: Int) {
|
|
27
|
+
val flex = parent as? FlexboxLayout ?: return
|
|
28
|
+
val lp = StyleEngine.buildFlexLayoutParams(child)
|
|
29
|
+
if (index >= flex.childCount) flex.addView(child, lp) else flex.addView(child, index, lp)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import androidx.recyclerview.widget.LinearLayoutManager
|
|
7
|
+
import androidx.recyclerview.widget.RecyclerView
|
|
8
|
+
|
|
9
|
+
class VListFactory : NativeComponentFactory {
|
|
10
|
+
// For each RecyclerView, store child views managed by the bridge.
|
|
11
|
+
// All maps are cleaned up in cleanupRecyclerView() when the view is removed.
|
|
12
|
+
private val childViews = mutableMapOf<RecyclerView, MutableList<View>>()
|
|
13
|
+
private val scrollHandlers = mutableMapOf<RecyclerView, (Any?) -> Unit>()
|
|
14
|
+
private val endReachedHandlers = mutableMapOf<RecyclerView, (Any?) -> Unit>()
|
|
15
|
+
private val scrollListeners = mutableMapOf<RecyclerView, RecyclerView.OnScrollListener>()
|
|
16
|
+
private val firedEndReached = mutableMapOf<RecyclerView, Boolean>()
|
|
17
|
+
private val estimatedItemHeights = mutableMapOf<RecyclerView, Int>()
|
|
18
|
+
|
|
19
|
+
override fun createView(context: Context): View {
|
|
20
|
+
val rv = RecyclerView(context).apply {
|
|
21
|
+
layoutManager = LinearLayoutManager(context)
|
|
22
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
23
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
24
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
childViews[rv] = mutableListOf()
|
|
28
|
+
firedEndReached[rv] = false
|
|
29
|
+
rv.adapter = VListAdapter(childViews[rv]!!)
|
|
30
|
+
return rv
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun updateProp(view: View, key: String, value: Any?) {
|
|
34
|
+
val rv = view as? RecyclerView ?: return
|
|
35
|
+
when (key) {
|
|
36
|
+
"horizontal" -> {
|
|
37
|
+
if (value == true) {
|
|
38
|
+
rv.layoutManager = LinearLayoutManager(rv.context, LinearLayoutManager.HORIZONTAL, false)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
"bounces" -> {
|
|
42
|
+
rv.overScrollMode = if (value == false || value == "false")
|
|
43
|
+
View.OVER_SCROLL_NEVER else View.OVER_SCROLL_ALWAYS
|
|
44
|
+
}
|
|
45
|
+
"showsScrollIndicator" -> {
|
|
46
|
+
val show = value != false && value != "false"
|
|
47
|
+
rv.isVerticalScrollBarEnabled = show
|
|
48
|
+
rv.isHorizontalScrollBarEnabled = show
|
|
49
|
+
}
|
|
50
|
+
"estimatedItemHeight" -> {
|
|
51
|
+
val h = when (value) {
|
|
52
|
+
is Number -> value.toInt()
|
|
53
|
+
is String -> value.toIntOrNull() ?: 44
|
|
54
|
+
else -> 44
|
|
55
|
+
}
|
|
56
|
+
estimatedItemHeights[rv] = h
|
|
57
|
+
}
|
|
58
|
+
else -> StyleEngine.apply(key, value, view)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun addEventListener(view: View, event: String, handler: (Any?) -> Unit) {
|
|
63
|
+
val rv = view as? RecyclerView ?: return
|
|
64
|
+
when (event) {
|
|
65
|
+
"scroll" -> {
|
|
66
|
+
scrollHandlers[rv] = handler
|
|
67
|
+
ensureScrollListener(rv)
|
|
68
|
+
}
|
|
69
|
+
"endReached" -> {
|
|
70
|
+
endReachedHandlers[rv] = handler
|
|
71
|
+
ensureScrollListener(rv)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun removeEventListener(view: View, event: String) {
|
|
77
|
+
val rv = view as? RecyclerView ?: return
|
|
78
|
+
when (event) {
|
|
79
|
+
"scroll" -> scrollHandlers.remove(rv)
|
|
80
|
+
"endReached" -> endReachedHandlers.remove(rv)
|
|
81
|
+
}
|
|
82
|
+
// Remove listener if neither handler is registered
|
|
83
|
+
if (!scrollHandlers.containsKey(rv) && !endReachedHandlers.containsKey(rv)) {
|
|
84
|
+
scrollListeners.remove(rv)?.let { rv.removeOnScrollListener(it) }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private fun ensureScrollListener(rv: RecyclerView) {
|
|
89
|
+
if (scrollListeners.containsKey(rv)) return
|
|
90
|
+
// Track cumulative scroll position
|
|
91
|
+
var cumulativeX = 0
|
|
92
|
+
var cumulativeY = 0
|
|
93
|
+
val listener = object : RecyclerView.OnScrollListener() {
|
|
94
|
+
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
95
|
+
cumulativeX += dx
|
|
96
|
+
cumulativeY += dy
|
|
97
|
+
|
|
98
|
+
// Dispatch scroll event with cumulative position
|
|
99
|
+
scrollHandlers[recyclerView]?.invoke(
|
|
100
|
+
mapOf("x" to cumulativeX, "y" to cumulativeY)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
// endReached detection (threshold = 20% from bottom)
|
|
104
|
+
val lm = recyclerView.layoutManager as? LinearLayoutManager ?: return
|
|
105
|
+
val totalItems = lm.itemCount
|
|
106
|
+
if (totalItems == 0) return
|
|
107
|
+
val lastVisible = lm.findLastVisibleItemPosition()
|
|
108
|
+
val threshold = (totalItems * 0.2).toInt().coerceAtLeast(1)
|
|
109
|
+
|
|
110
|
+
if (lastVisible >= totalItems - threshold) {
|
|
111
|
+
if (firedEndReached[recyclerView] != true) {
|
|
112
|
+
firedEndReached[recyclerView] = true
|
|
113
|
+
endReachedHandlers[recyclerView]?.invoke(null)
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
// Reset when scrolled back up significantly
|
|
117
|
+
firedEndReached[recyclerView] = false
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
scrollListeners[rv] = listener
|
|
122
|
+
rv.addOnScrollListener(listener)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override fun insertChild(parent: View, child: View, index: Int) {
|
|
126
|
+
val rv = parent as? RecyclerView ?: return
|
|
127
|
+
val list = childViews[rv] ?: return
|
|
128
|
+
val insertIdx = if (index >= list.size) list.size else index
|
|
129
|
+
list.add(insertIdx, child)
|
|
130
|
+
rv.adapter?.notifyItemInserted(insertIdx)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
override fun removeChild(parent: View, child: View) {
|
|
134
|
+
val rv = parent as? RecyclerView ?: return
|
|
135
|
+
val list = childViews[rv] ?: return
|
|
136
|
+
val idx = list.indexOf(child)
|
|
137
|
+
if (idx >= 0) {
|
|
138
|
+
list.removeAt(idx)
|
|
139
|
+
rv.adapter?.notifyItemRemoved(idx)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Clean up all state associated with a RecyclerView when it is removed from the tree.
|
|
145
|
+
* Prevents memory leaks by clearing all map entries that reference the view.
|
|
146
|
+
*/
|
|
147
|
+
fun cleanupRecyclerView(rv: RecyclerView) {
|
|
148
|
+
scrollListeners.remove(rv)?.let { rv.removeOnScrollListener(it) }
|
|
149
|
+
scrollHandlers.remove(rv)
|
|
150
|
+
endReachedHandlers.remove(rv)
|
|
151
|
+
firedEndReached.remove(rv)
|
|
152
|
+
estimatedItemHeights.remove(rv)
|
|
153
|
+
childViews.remove(rv)
|
|
154
|
+
rv.adapter = null
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Called when the parent view is being destroyed. Cleans up the RecyclerView.
|
|
159
|
+
*/
|
|
160
|
+
fun destroyView(view: View) {
|
|
161
|
+
val rv = view as? RecyclerView ?: return
|
|
162
|
+
cleanupRecyclerView(rv)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
class VListAdapter(private val items: List<View>) : RecyclerView.Adapter<VListAdapter.VH>() {
|
|
167
|
+
class VH(val view: View) : RecyclerView.ViewHolder(view)
|
|
168
|
+
|
|
169
|
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
|
170
|
+
val v = items.getOrNull(viewType) ?: android.widget.FrameLayout(parent.context)
|
|
171
|
+
// Remove from any existing parent
|
|
172
|
+
(v.parent as? ViewGroup)?.removeView(v)
|
|
173
|
+
v.layoutParams = RecyclerView.LayoutParams(
|
|
174
|
+
RecyclerView.LayoutParams.MATCH_PARENT,
|
|
175
|
+
RecyclerView.LayoutParams.WRAP_CONTENT
|
|
176
|
+
)
|
|
177
|
+
return VH(v)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
override fun onBindViewHolder(holder: VH, position: Int) {}
|
|
181
|
+
override fun getItemCount(): Int = items.size
|
|
182
|
+
override fun getItemViewType(position: Int): Int = position
|
|
183
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.app.Dialog
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.graphics.drawable.ColorDrawable
|
|
7
|
+
import android.view.View
|
|
8
|
+
import android.view.ViewGroup
|
|
9
|
+
import android.view.Window
|
|
10
|
+
import com.google.android.flexbox.FlexDirection
|
|
11
|
+
import com.google.android.flexbox.FlexboxLayout
|
|
12
|
+
|
|
13
|
+
class VModalFactory : NativeComponentFactory {
|
|
14
|
+
private val dialogs = mutableMapOf<View, Dialog>()
|
|
15
|
+
private val contentContainers = mutableMapOf<View, FlexboxLayout>()
|
|
16
|
+
private val dismissHandlers = mutableMapOf<View, (Any?) -> Unit>()
|
|
17
|
+
|
|
18
|
+
override fun createView(context: Context): View {
|
|
19
|
+
// Return a zero-size placeholder view
|
|
20
|
+
return View(context).apply {
|
|
21
|
+
layoutParams = ViewGroup.LayoutParams(0, 0)
|
|
22
|
+
visibility = View.GONE
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override fun updateProp(view: View, key: String, value: Any?) {
|
|
27
|
+
when (key) {
|
|
28
|
+
"visible" -> {
|
|
29
|
+
val show = value == true || value == "true"
|
|
30
|
+
if (show) showModal(view) else dismissModal(view)
|
|
31
|
+
}
|
|
32
|
+
"animationType" -> {} // TODO: dialog animation
|
|
33
|
+
"transparent" -> {
|
|
34
|
+
if (value == true) {
|
|
35
|
+
dialogs[view]?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private fun showModal(view: View) {
|
|
42
|
+
val ctx = view.context
|
|
43
|
+
if (dialogs[view]?.isShowing == true) return
|
|
44
|
+
val dialog = Dialog(ctx, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen)
|
|
45
|
+
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
46
|
+
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
47
|
+
|
|
48
|
+
val content = contentContainers.getOrPut(view) {
|
|
49
|
+
FlexboxLayout(ctx).apply {
|
|
50
|
+
flexDirection = FlexDirection.COLUMN
|
|
51
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
52
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
53
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
(content.parent as? ViewGroup)?.removeView(content)
|
|
58
|
+
dialog.setContentView(content)
|
|
59
|
+
dialog.setOnDismissListener { dismissHandlers[view]?.invoke(null) }
|
|
60
|
+
dialog.show()
|
|
61
|
+
dialogs[view] = dialog
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private fun dismissModal(view: View) {
|
|
65
|
+
dialogs[view]?.dismiss()
|
|
66
|
+
dialogs.remove(view)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun addEventListener(view: View, event: String, handler: (Any?) -> Unit) {
|
|
70
|
+
if (event == "dismiss") dismissHandlers[view] = handler
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override fun removeEventListener(view: View, event: String) {
|
|
74
|
+
if (event == "dismiss") dismissHandlers.remove(view)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override fun insertChild(parent: View, child: View, index: Int) {
|
|
78
|
+
val container = contentContainers.getOrPut(parent) {
|
|
79
|
+
FlexboxLayout(parent.context).apply {
|
|
80
|
+
flexDirection = FlexDirection.COLUMN
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
val lp = StyleEngine.buildFlexLayoutParams(child)
|
|
84
|
+
if (index >= container.childCount) container.addView(child, lp)
|
|
85
|
+
else container.addView(child, index, lp)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun removeChild(parent: View, child: View) {
|
|
89
|
+
contentContainers[parent]?.removeView(child)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Clean up all state associated with a modal view when it is removed from the tree.
|
|
94
|
+
* Dismisses the dialog and clears all map entries that reference the view,
|
|
95
|
+
* preventing memory leaks.
|
|
96
|
+
*/
|
|
97
|
+
fun destroyView(view: View) {
|
|
98
|
+
dialogs[view]?.let { dialog ->
|
|
99
|
+
if (dialog.isShowing) dialog.dismiss()
|
|
100
|
+
}
|
|
101
|
+
dialogs.remove(view)
|
|
102
|
+
contentContainers.remove(view)
|
|
103
|
+
dismissHandlers.remove(view)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package com.vuenative.core
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.widget.DatePicker
|
|
7
|
+
import android.widget.TimePicker
|
|
8
|
+
import java.util.Calendar
|
|
9
|
+
|
|
10
|
+
class VPickerFactory : NativeComponentFactory {
|
|
11
|
+
private val changeHandlers = mutableMapOf<View, (Any?) -> Unit>()
|
|
12
|
+
|
|
13
|
+
override fun createView(context: Context): View {
|
|
14
|
+
return DatePicker(context).apply {
|
|
15
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
16
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
17
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override fun updateProp(view: View, key: String, value: Any?) {
|
|
23
|
+
val dp = view as? DatePicker ?: return
|
|
24
|
+
when (key) {
|
|
25
|
+
"value" -> {
|
|
26
|
+
val ms = StyleEngine.toFloat(value, 0f).toLong()
|
|
27
|
+
val cal = Calendar.getInstance().apply { timeInMillis = ms }
|
|
28
|
+
dp.updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH))
|
|
29
|
+
}
|
|
30
|
+
"minimumDate" -> {
|
|
31
|
+
val ms = StyleEngine.toFloat(value, 0f).toLong()
|
|
32
|
+
dp.minDate = ms
|
|
33
|
+
}
|
|
34
|
+
"maximumDate" -> {
|
|
35
|
+
val ms = StyleEngine.toFloat(value, 0f).toLong()
|
|
36
|
+
dp.maxDate = ms
|
|
37
|
+
}
|
|
38
|
+
"mode" -> {} // DatePicker handles date mode; TimePicker for time
|
|
39
|
+
else -> StyleEngine.apply(key, value, view)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override fun addEventListener(view: View, event: String, handler: (Any?) -> Unit) {
|
|
44
|
+
val dp = view as? DatePicker ?: return
|
|
45
|
+
if (event == "change") {
|
|
46
|
+
changeHandlers[view] = handler
|
|
47
|
+
dp.init(
|
|
48
|
+
dp.year, dp.month, dp.dayOfMonth
|
|
49
|
+
) { _, year, month, day ->
|
|
50
|
+
val cal = Calendar.getInstance().apply { set(year, month, day) }
|
|
51
|
+
changeHandlers[view]?.invoke(mapOf("value" to cal.timeInMillis.toDouble()))
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override fun removeEventListener(view: View, event: String) { changeHandlers.remove(view) }
|
|
57
|
+
}
|