@@ -9,6 +9,9 @@ import android.text.style.StrikethroughSpan
9
9
import android.text.style.StyleSpan
10
10
import android.view.ViewGroup
11
11
import androidx.core.graphics.ColorUtils
12
+ import androidx.core.text.buildSpannedString
13
+ import androidx.core.text.inSpans
14
+ import androidx.core.text.set
12
15
import androidx.recyclerview.widget.RecyclerView
13
16
import org.wikipedia.R
14
17
import org.wikipedia.dataclient.restbase.DiffResponse
@@ -31,10 +34,10 @@ object DiffUtil {
31
34
if (it.lineNumber > lastItem!! .lineEnd) {
32
35
lastItem!! .lineEnd = it.lineNumber
33
36
}
34
- val str = SpannableStringBuilder ( lastItem!! .parsedText)
35
- str.append( " \n " )
36
- str. append(item.parsedText)
37
- lastItem !! .parsedText = str
37
+ lastItem!! .parsedText = buildSpannedString {
38
+ appendLine(lastItem !! .parsedText )
39
+ append(item.parsedText)
40
+ }
38
41
} else {
39
42
items.add(item)
40
43
lastItem = item
@@ -81,54 +84,43 @@ object DiffUtil {
81
84
}
82
85
83
86
private fun createSpannableDiffText (context : Context , diff : DiffResponse .DiffItem ): CharSequence {
84
- val spannableString = SpannableStringBuilder (diff.text.ifEmpty { " \n " })
85
- if (diff.text.isEmpty()) {
86
- spannableString.setSpan(EmptyLineSpan (ResourceUtil .getThemedColor(context, android.R .attr.colorBackground),
87
- ResourceUtil .getThemedColor(context, R .attr.placeholder_color)), 0 , spannableString.length, 0 )
88
- return spannableString
89
- }
90
- when (diff.type) {
91
- DiffResponse .DIFF_TYPE_LINE_ADDED -> {
92
- updateDiffTextDecor(context, spannableString, true , 0 , diff.text.length)
93
- }
94
- DiffResponse .DIFF_TYPE_LINE_REMOVED -> {
95
- updateDiffTextDecor(context, spannableString, false , 0 , diff.text.length)
96
- }
97
- DiffResponse .DIFF_TYPE_PARAGRAPH_MOVED_FROM -> {
98
- updateDiffTextDecor(context, spannableString, false , 0 , diff.text.length)
99
- }
100
- DiffResponse .DIFF_TYPE_PARAGRAPH_MOVED_TO -> {
101
- updateDiffTextDecor(context, spannableString, true , 0 , diff.text.length)
102
- }
103
- }
104
- if (diff.highlightRanges.isNotEmpty()) {
105
- for (highlightRange in diff.highlightRanges) {
106
- val indices = StringUtil .utf8Indices(diff.text)
107
- val highlightRangeStart = indices[highlightRange.start].coerceIn(0 , diff.text.length)
108
- val highlightRangeEnd = (indices.getOrElse(highlightRange.start + highlightRange.length) { indices.last() + 1 }).coerceIn(0 , diff.text.length)
87
+ return buildSpannedString {
88
+ if (diff.text.isEmpty()) {
89
+ inSpans(EmptyLineSpan (ResourceUtil .getThemedColor(context, android.R .attr.colorBackground),
90
+ ResourceUtil .getThemedColor(context, R .attr.placeholder_color))) {
91
+ appendLine()
92
+ }
93
+ } else {
94
+ append(diff.text)
95
+
96
+ when (diff.type) {
97
+ DiffResponse .DIFF_TYPE_LINE_ADDED , DiffResponse .DIFF_TYPE_PARAGRAPH_MOVED_TO -> {
98
+ updateDiffTextDecor(context, true , 0 , diff.text.length)
99
+ }
100
+ DiffResponse .DIFF_TYPE_LINE_REMOVED , DiffResponse .DIFF_TYPE_PARAGRAPH_MOVED_FROM -> {
101
+ updateDiffTextDecor(context, false , 0 , diff.text.length)
102
+ }
103
+ }
104
+
105
+ for (highlightRange in diff.highlightRanges) {
106
+ val indices = StringUtil .utf8Indices(diff.text)
107
+ val highlightRangeStart = indices[highlightRange.start].coerceIn(0 , diff.text.length)
108
+ val highlightRangeEnd = (indices.getOrElse(highlightRange.start + highlightRange.length) { indices.last() + 1 }).coerceIn(0 , diff.text.length)
109
+ val isAddition = highlightRange.type == DiffResponse .HIGHLIGHT_TYPE_ADD
109
110
110
- if (highlightRange.type == DiffResponse .HIGHLIGHT_TYPE_ADD ) {
111
- updateDiffTextDecor(context, spannableString, true , highlightRangeStart, highlightRangeEnd)
112
- } else {
113
- updateDiffTextDecor(context, spannableString, false , highlightRangeStart, highlightRangeEnd)
111
+ updateDiffTextDecor(context, isAddition, highlightRangeStart, highlightRangeEnd)
114
112
}
115
113
}
116
114
}
117
- return spannableString
118
115
}
119
116
120
- private fun updateDiffTextDecor (context : Context , spannableText : SpannableStringBuilder , isAddition : Boolean , start : Int , end : Int ) {
121
- val boldStyle = StyleSpan (Typeface .BOLD )
122
- val foregroundAddedColor = ForegroundColorSpan (ResourceUtil .getThemedColor(context, R .attr.primary_color))
123
- val foregroundRemovedColor = ForegroundColorSpan (ResourceUtil .getThemedColor(context, R .attr.primary_color))
124
- spannableText.setSpan(BackgroundColorSpan (ColorUtils .setAlphaComponent(ResourceUtil .getThemedColor(context,
125
- if (isAddition) R .attr.success_color else R .attr.destructive_color), 48 )), start, end, 0 )
126
- spannableText.setSpan(boldStyle, start, end, 0 )
127
- if (isAddition) {
128
- spannableText.setSpan(foregroundAddedColor, start, end, 0 )
129
- } else {
130
- spannableText.setSpan(foregroundRemovedColor, start, end, 0 )
131
- spannableText.setSpan(StrikethroughSpan (), start, end, 0 )
117
+ private fun SpannableStringBuilder.updateDiffTextDecor (context : Context , isAddition : Boolean , start : Int , end : Int ) {
118
+ this [start, end] = BackgroundColorSpan (ColorUtils .setAlphaComponent(ResourceUtil .getThemedColor(context,
119
+ if (isAddition) R .attr.success_color else R .attr.destructive_color), 48 ))
120
+ this [start, end] = StyleSpan (Typeface .BOLD )
121
+ this [start, end] = ForegroundColorSpan (ResourceUtil .getThemedColor(context, R .attr.primary_color))
122
+ if (! isAddition) {
123
+ this [start, end] = StrikethroughSpan ()
132
124
}
133
125
}
134
126
}
0 commit comments