react-native-typerich 0.1.8 → 0.1.9
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.
|
@@ -63,6 +63,8 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
63
63
|
private var keyboardAppearance: String = "default"
|
|
64
64
|
private var inputMethodManager: InputMethodManager? = null
|
|
65
65
|
private var lineHeightPx: Int? = null
|
|
66
|
+
private var isSettingTextFromJS = false
|
|
67
|
+
|
|
66
68
|
|
|
67
69
|
constructor(context: Context) : super(context) {
|
|
68
70
|
prepareComponent()
|
|
@@ -101,10 +103,12 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
101
103
|
layoutManager = TypeRichTextInputViewLayoutManager(this)
|
|
102
104
|
|
|
103
105
|
addTextChangedListener(object : TextWatcher {
|
|
104
|
-
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
|
106
|
+
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { if (isSettingTextFromJS) return}
|
|
105
107
|
|
|
106
108
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
|
107
109
|
if (!isDuringTransaction) {
|
|
110
|
+
if (isSettingTextFromJS) return
|
|
111
|
+
|
|
108
112
|
val reactContext = context as ReactContext
|
|
109
113
|
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
|
|
110
114
|
val dispatcher =
|
|
@@ -360,26 +364,48 @@ class TypeRichTextInputView : AppCompatEditText {
|
|
|
360
364
|
// }
|
|
361
365
|
}
|
|
362
366
|
|
|
363
|
-
|
|
364
367
|
fun setValue(value: CharSequence?) {
|
|
365
368
|
if (value == null) return
|
|
366
369
|
|
|
367
|
-
val
|
|
370
|
+
val current = text?.toString() ?: ""
|
|
371
|
+
val newText = value.toString()
|
|
368
372
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
373
|
+
if (current == newText) {
|
|
374
|
+
return
|
|
375
|
+
}
|
|
372
376
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
isSettingTextFromJS = true
|
|
378
|
+
try {
|
|
379
|
+
// Save current selection BEFORE text change
|
|
380
|
+
val prevStart = selectionStart
|
|
381
|
+
val prevEnd = selectionEnd
|
|
382
|
+
|
|
383
|
+
runAsATransaction {
|
|
384
|
+
// Check if this is just an insertion at cursor (fast typing case)
|
|
385
|
+
val isSimpleInsertion = prevStart == prevEnd &&
|
|
386
|
+
newText.length > current.length &&
|
|
387
|
+
prevStart <= newText.length &&
|
|
388
|
+
current.substring(0, minOf(prevStart, current.length)) ==
|
|
389
|
+
newText.substring(0, minOf(prevStart, current.length))
|
|
390
|
+
|
|
391
|
+
setText(newText)
|
|
392
|
+
|
|
393
|
+
val len = text?.length ?: 0
|
|
394
|
+
|
|
395
|
+
if (isSimpleInsertion) {
|
|
396
|
+
// For insertions, move cursor to end of new content
|
|
397
|
+
val diff = newText.length - current.length
|
|
398
|
+
val newPos = (prevStart + diff).coerceIn(0, len)
|
|
399
|
+
setSelection(newPos)
|
|
400
|
+
} else {
|
|
401
|
+
// For other changes, try to preserve relative position
|
|
402
|
+
val start = prevStart.coerceIn(0, len)
|
|
403
|
+
val end = prevEnd.coerceIn(0, len)
|
|
404
|
+
setSelection(start, end)
|
|
405
|
+
}
|
|
376
406
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
val start = prevStart.coerceIn(0, len)
|
|
380
|
-
val end = prevEnd.coerceIn(0, len)
|
|
381
|
-
|
|
382
|
-
setSelection(start, end)
|
|
407
|
+
} finally {
|
|
408
|
+
isSettingTextFromJS = false
|
|
383
409
|
}
|
|
384
410
|
}
|
|
385
411
|
|