diff --git a/example-app-android/build.gradle.kts b/example-app-android/build.gradle.kts index fa0202340..26684a9f3 100644 --- a/example-app-android/build.gradle.kts +++ b/example-app-android/build.gradle.kts @@ -26,7 +26,7 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.3") } kotlinOptions { jvmTarget = "1.8" diff --git a/example-app/build.gradle.kts b/example-app/build.gradle.kts index e6d44809b..469ec9814 100644 --- a/example-app/build.gradle.kts +++ b/example-app/build.gradle.kts @@ -144,7 +144,7 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.3") } } diff --git a/example-app/src/jsMain/resources/index.html b/example-app/src/jsMain/resources/index.html index ee69ea940..15bd61e8b 100644 --- a/example-app/src/jsMain/resources/index.html +++ b/example-app/src/jsMain/resources/index.html @@ -3,6 +3,7 @@ + JS Client diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 55c2430bf..3387b3c19 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -178,7 +178,7 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.2") + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.3") } testOptions { unitTests { diff --git a/library/library.podspec b/library/library.podspec index ac109ee97..037a90a97 100644 --- a/library/library.podspec +++ b/library/library.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'library' - spec.version = 'phone-number-input-SNAPSHOT' + spec.version = 'version-3-SNAPSHOT' spec.homepage = '' spec.source = { :http=> ''} spec.authors = '' diff --git a/library/src/androidMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.android.kt b/library/src/androidMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.android.kt index cd8bac99b..bb844e8e1 100644 --- a/library/src/androidMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.android.kt +++ b/library/src/androidMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.android.kt @@ -10,15 +10,45 @@ import android.widget.EditText import android.widget.TextView import androidx.core.graphics.TypefaceCompat import androidx.core.view.updateLayoutParams +import androidx.core.widget.doAfterTextChanged import com.lightningkite.kiteui.models.* import com.lightningkite.kiteui.reactive.Action import com.lightningkite.kiteui.reactive.ImmediateWritable import com.lightningkite.kiteui.reactive.lens +import com.lightningkite.kiteui.utils.numberAutocommaRepair +import com.lightningkite.kiteui.utils.repairFormatAndPosition import com.lightningkite.kiteui.views.RContext import com.lightningkite.kiteui.views.RViewWithAction actual class FormattedTextInput actual constructor(context: RContext) : RViewWithAction(context) { - override val native = EditText(context.activity) + override val native = EditText(context.activity).apply { + var block = false + doAfterTextChanged { _ -> + if(block) return@doAfterTextChanged + block = true + post { + val str = this.text.toString() + try { + if (str == null) return@post + repairFormatAndPosition( + dirty = str, + selectionStart = selectionStart, + selectionEnd = selectionEnd, + setResult = { + setText(it) + }, + setSelectionRange = { start, end -> + setSelection(start, end) + }, + isRawData = isRawData, + formatter = formatter, + ) + } finally { + block = false + } + } + } + } override fun applyForeground(theme: Theme) { super.applyForeground(theme) native.setTextColor(theme.foreground.colorInt()) diff --git a/library/src/commonTest/kotlin/com/lightningkite/kiteui/reactive/LazyPropertyTests.kt b/library/src/commonTest/kotlin/com/lightningkite/kiteui/reactive/LazyPropertyTests.kt index 0e67fd6b2..8599c0534 100644 --- a/library/src/commonTest/kotlin/com/lightningkite/kiteui/reactive/LazyPropertyTests.kt +++ b/library/src/commonTest/kotlin/com/lightningkite/kiteui/reactive/LazyPropertyTests.kt @@ -277,11 +277,14 @@ class LazyPropertyTests { val basis = Property("Test") val lazy = LazyProperty(stopListeningWhenOverridden = false) { basis() } val lensed = lazy.lens { it.take(3) } + val lensed2 = lazy.lens(get = { it.take(3) }, modify = { o, it -> it }) testContext { println(lensed.state) load { - println("Starting") - println(lensed()) + assertEquals("Tes", lensed()) + } + load { + assertEquals("Tes", lensed2()) } } } @@ -290,7 +293,9 @@ class LazyPropertyTests { val basis = Property("Test") val lazy = LazyProperty(stopListeningWhenOverridden = false) { basis() } val lensed = lazy.lens { it.take(3) } + val lensed2 = lazy.lens(get = { it.take(3) }, modify = { o, it -> it }) var value = "" + var value2 = "" testContext { println(lensed.state) reactive { @@ -298,7 +303,13 @@ class LazyPropertyTests { value = lensed() println(value) } + reactive { + println("Starting") + value2 = lensed2() + println(value2) + } assertEquals("Tes", value) + assertEquals("Tes", value2) } } } \ No newline at end of file diff --git a/library/src/iosMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.ios.kt b/library/src/iosMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.ios.kt index 45bff87f5..35ba1c9fb 100644 --- a/library/src/iosMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.ios.kt +++ b/library/src/iosMain/kotlin/com/lightningkite/kiteui/views/direct/FormattedTextInput.ios.kt @@ -6,7 +6,11 @@ import com.lightningkite.kiteui.reactive.ImmediateWritable import com.lightningkite.kiteui.reactive.onRemove import com.lightningkite.kiteui.utils.commaString import com.lightningkite.kiteui.utils.numberAutocommaRepair +import com.lightningkite.kiteui.utils.repairFormatAndPosition import com.lightningkite.kiteui.views.* +import platform.Foundation.* +import platform.UIKit.* +import platform.darwin.NSObject actual class FormattedTextInput actual constructor(context: RContext) : RViewWithAction(context) { override val native = WrapperView() @@ -23,11 +27,11 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit init { var block = false - textField.onEvent(this@NumberInput, UIControlEventEditingChanged) { + textField.onEvent(this@FormattedTextInput, UIControlEventEditingChanged) { if (block) return@onEvent block = true try { - numberAutocommaRepair( + repairFormatAndPosition( dirty = textField.text ?: "", selectionStart = textField.selectedTextRange?.start?.let { textField.offsetFromPosition(textField.beginningOfDocument, it) }?.toInt(), selectionEnd = textField.selectedTextRange?.end?.let { textField.offsetFromPosition(textField.beginningOfDocument, it) }?.toInt(), @@ -36,16 +40,19 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit }, setSelectionRange = { start, end -> textField.selectedTextRange = textField.textRangeFromPosition( - textField.positionFromPosition(textField.beginningOfDocument, start.toLong()) ?: return@numberAutocommaRepair, - textField.positionFromPosition(textField.beginningOfDocument, end.toLong()) ?: return@numberAutocommaRepair, + textField.positionFromPosition(textField.beginningOfDocument, start.toLong()) ?: return@repairFormatAndPosition, + textField.positionFromPosition(textField.beginningOfDocument, end.toLong()) ?: return@repairFormatAndPosition, ) - } + }, + isRawData = isRawData, + formatter = formatter, ) } finally { block = false } } } + override fun applyForeground(theme: Theme) { textField.textColor = theme.foreground.closestColor().toUiColor() fontAndStyle = theme.font @@ -86,6 +93,7 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit this.isRawData = isRawData this.formatter = formatter } + actual val content: ImmediateWritable = object : ImmediateWritable { override var value: String get() = (textField.text ?: "").filter(isRawData) @@ -96,7 +104,7 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit } override fun addListener(listener: () -> Unit): () -> Unit { - return textField.onEvent(this@NumberInput, UIControlEventEditingChanged, listener) + return textField.onEvent(this@FormattedTextInput, UIControlEventEditingChanged, listener) } } @@ -125,12 +133,13 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit } textField.secureTextEntry = value.autocomplete in setOf(AutoComplete.Password, AutoComplete.NewPassword) } + override fun actionSet(value: Action?) { super.actionSet(value) textField.delegate = value?.let { val d = object : NSObject(), UITextFieldDelegateProtocol { override fun textFieldShouldReturn(textField: UITextField): Boolean { - it?.startAction(this@NumberInput) + it?.startAction(this@FormattedTextInput) return true } } @@ -153,6 +162,7 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit else -> UIReturnKeyType.UIReturnKeyDone } } + actual var hint: String = "" set(value) { field = value @@ -187,16 +197,18 @@ actual class FormattedTextInput actual constructor(context: RContext) : RViewWit textField.enabled = value refreshTheming() } + init { onRemove(textField.observe("highlighted", { refreshTheming() })) onRemove(textField.observe("selected", { refreshTheming() })) onRemove(textField.observe("enabled", { refreshTheming() })) } + override fun applyState(theme: ThemeAndBack): ThemeAndBack { var t = theme - if(!textField.enabled) t = t[DisabledSemantic] - if(textField.highlighted) t = t[DownSemantic] - if(textField.focused) t = t[FocusSemantic] + if (!textField.enabled) t = t[DisabledSemantic] + if (textField.highlighted) t = t[DownSemantic] + if (textField.focused) t = t[FocusSemantic] return super.applyState(t) } } \ No newline at end of file diff --git a/library/src/jsMain/kotlin/com/lightningkite/kiteui/navigation/Navigator.js.kt b/library/src/jsMain/kotlin/com/lightningkite/kiteui/navigation/Navigator.js.kt index c880ce159..dfccca825 100644 --- a/library/src/jsMain/kotlin/com/lightningkite/kiteui/navigation/Navigator.js.kt +++ b/library/src/jsMain/kotlin/com/lightningkite/kiteui/navigation/Navigator.js.kt @@ -113,7 +113,7 @@ external interface BaseUrlScript { var basePath = (document.getElementById("baseUrlLocation") as? HTMLScriptElement)?.innerText?.let { JSON.parse(it).baseUrl -} ?: "/" +} ?: document.baseURI.takeIf { document.getElementsByTagName("base").length != 0 } ?: "/" private fun Location.urlLike() = UrlLikePath( segments = pathname.removePrefix(basePath).split('/').filter { it.isNotBlank() },