Skip to content

Commit 979d0bf

Browse files
committed
chore: improve marking operation as a transition
1 parent 9c7b434 commit 979d0bf

2 files changed

Lines changed: 37 additions & 28 deletions

File tree

android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ class EnrichedTextInputView : AppCompatEditText {
5151
val paragraphStyles: ParagraphStyles? = ParagraphStyles(this)
5252
val listStyles: ListStyles? = ListStyles(this)
5353
val parametrizedStyles: ParametrizedStyles? = ParametrizedStyles(this)
54-
// Sometimes setting up style triggers many changes in sequence
55-
// Eg. removing conflicting styles -> changing text -> applying spans
56-
// In such scenario we want to prevent from handling side effects (eg. onTextChanged)
5754
var isDuringTransaction: Boolean = false
5855
var isRemovingMany: Boolean = false
5956

@@ -236,18 +233,17 @@ class EnrichedTextInputView : AppCompatEditText {
236233

237234
fun setValue(value: CharSequence?) {
238235
if (value == null) return
239-
isDuringTransaction = true
240236

241-
val newText = parseText(value)
242-
setText(newText)
243-
244-
// Assign SpanWatcher one more time as our previous spannable has been replaced
245-
addSpanWatcher(EnrichedSpanWatcher(this))
237+
runAsATransaction {
238+
val newText = parseText(value)
239+
setText(newText)
246240

247-
// Scroll to the last line of text
248-
setSelection(text?.length ?: 0)
241+
// Assign SpanWatcher one more time as our previous spannable has been replaced
242+
addSpanWatcher(EnrichedSpanWatcher(this))
249243

250-
isDuringTransaction = false
244+
// Scroll to the last line of text
245+
setSelection(text?.length ?: 0)
246+
}
251247
}
252248

253249
fun setAutoFocus(autoFocus: Boolean) {
@@ -455,13 +451,13 @@ class EnrichedTextInputView : AppCompatEditText {
455451
val end = selection?.end ?: 0
456452
val lengthBefore = text?.length ?: 0
457453

458-
isDuringTransaction = true
459-
val targetRange = getTargetRange(name)
460-
val removed = removeStyle(style, targetRange.first, targetRange.second)
461-
if (removed) {
462-
spanState?.setStart(style, null)
454+
runAsATransaction {
455+
val targetRange = getTargetRange(name)
456+
val removed = removeStyle(style, targetRange.first, targetRange.second)
457+
if (removed) {
458+
spanState?.setStart(style, null)
459+
}
463460
}
464-
isDuringTransaction = false
465461

466462
val lengthAfter = text?.length ?: 0
467463
val charactersRemoved = lengthBefore - lengthAfter
@@ -519,6 +515,18 @@ class EnrichedTextInputView : AppCompatEditText {
519515
parametrizedStyles?.setMentionSpan(text, indicator, attributes)
520516
}
521517

518+
// Sometimes setting up style triggers many changes in sequence
519+
// Eg. removing conflicting styles -> changing text -> applying spans
520+
// In such scenario we want to prevent from handling side effects (eg. onTextChanged)
521+
fun runAsATransaction(block: () -> Unit) {
522+
try {
523+
isDuringTransaction = true
524+
block()
525+
} finally {
526+
isDuringTransaction = false
527+
}
528+
}
529+
522530
override fun onAttachedToWindow() {
523531
super.onAttachedToWindow()
524532

android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,20 +201,21 @@ class ParametrizedStyles(private val view: EnrichedTextInputView) {
201201
}
202202

203203
val start = mentionStart ?: return
204-
view.isDuringTransaction = true
205-
spannable.replace(start, selectionEnd, text)
206204

207-
val span = EnrichedMentionSpan(text, indicator, attributes, view.htmlStyle)
208-
val spanEnd = start + text.length
209-
val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(start, spanEnd)
210-
spannable.setSpan(span, safeStart, safeEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
205+
view.runAsATransaction {
206+
spannable.replace(start, selectionEnd, text)
211207

212-
val hasSpaceAtTheEnd = spannable.length > safeEnd && spannable[safeEnd] == ' '
213-
if (!hasSpaceAtTheEnd) {
214-
spannable.insert(safeEnd, " ")
208+
val span = EnrichedMentionSpan(text, indicator, attributes, view.htmlStyle)
209+
val spanEnd = start + text.length
210+
val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(start, spanEnd)
211+
spannable.setSpan(span, safeStart, safeEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
212+
213+
val hasSpaceAtTheEnd = spannable.length > safeEnd && spannable[safeEnd] == ' '
214+
if (!hasSpaceAtTheEnd) {
215+
spannable.insert(safeEnd, " ")
216+
}
215217
}
216218

217-
view.isDuringTransaction = false
218219
view.mentionHandler?.reset()
219220
view.selection.validateStyles()
220221
}

0 commit comments

Comments
 (0)