Skip to content

Commit 5dd2a7c

Browse files
authored
chore: improve marking operation as a transaction - android (#215)
1 parent a261ef6 commit 5dd2a7c

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

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

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

@@ -241,18 +238,17 @@ class EnrichedTextInputView : AppCompatEditText {
241238

242239
fun setValue(value: CharSequence?) {
243240
if (value == null) return
244-
isDuringTransaction = true
245241

246-
val newText = parseText(value)
247-
setText(newText)
248-
249-
// Assign SpanWatcher one more time as our previous spannable has been replaced
250-
addSpanWatcher(EnrichedSpanWatcher(this))
242+
runAsATransaction {
243+
val newText = parseText(value)
244+
setText(newText)
251245

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

255-
isDuringTransaction = false
249+
// Scroll to the last line of text
250+
setSelection(text?.length ?: 0)
251+
}
256252
}
257253

258254
fun setAutoFocus(autoFocus: Boolean) {
@@ -460,13 +456,13 @@ class EnrichedTextInputView : AppCompatEditText {
460456
val end = selection?.end ?: 0
461457
val lengthBefore = text?.length ?: 0
462458

463-
isDuringTransaction = true
464-
val targetRange = getTargetRange(name)
465-
val removed = removeStyle(style, targetRange.first, targetRange.second)
466-
if (removed) {
467-
spanState?.setStart(style, null)
459+
runAsATransaction {
460+
val targetRange = getTargetRange(name)
461+
val removed = removeStyle(style, targetRange.first, targetRange.second)
462+
if (removed) {
463+
spanState?.setStart(style, null)
464+
}
468465
}
469-
isDuringTransaction = false
470466

471467
val lengthAfter = text?.length ?: 0
472468
val charactersRemoved = lengthBefore - lengthAfter
@@ -524,6 +520,18 @@ class EnrichedTextInputView : AppCompatEditText {
524520
parametrizedStyles?.setMentionSpan(text, indicator, attributes)
525521
}
526522

523+
// Sometimes setting up style triggers many changes in sequence
524+
// Eg. removing conflicting styles -> changing text -> applying spans
525+
// In such scenario we want to prevent from handling side effects (eg. onTextChanged)
526+
fun runAsATransaction(block: () -> Unit) {
527+
try {
528+
isDuringTransaction = true
529+
block()
530+
} finally {
531+
isDuringTransaction = false
532+
}
533+
}
534+
527535
override fun onAttachedToWindow() {
528536
super.onAttachedToWindow()
529537

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)