Skip to content

Commit 06fbb68

Browse files
committed
fix: sync img placeholder colors with current text color
1 parent 237c889 commit 06fbb68

11 files changed

Lines changed: 100 additions & 23 deletions

File tree

android/src/main/java/com/swmansion/enriched/common/AsyncDrawable.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import android.os.Build
1313
import android.os.Handler
1414
import android.os.Looper
1515
import android.util.Log
16+
import androidx.core.graphics.drawable.DrawableCompat
1617
import androidx.core.graphics.drawable.toDrawable
1718
import com.swmansion.enriched.R
1819
import java.net.URL
@@ -21,11 +22,14 @@ import java.util.concurrent.Executors
2122

2223
class AsyncDrawable(
2324
private val url: String,
25+
private var placeholderTintColor: Int,
2426
) : Drawable() {
2527
private var internalDrawable: Drawable = Color.TRANSPARENT.toDrawable()
2628
private val mainHandler = Handler(Looper.getMainLooper())
2729
private val executor = Executors.newSingleThreadExecutor()
2830
var isLoaded = false
31+
var isShowingPlaceholder = false
32+
private set
2933

3034
init {
3135
internalDrawable.bounds = bounds
@@ -94,7 +98,20 @@ class AsyncDrawable(
9498
}
9599

96100
private fun loadPlaceholderImage() {
97-
internalDrawable = ResourceManager.getDrawableResource(R.drawable.broken_image)
101+
val drawable = ResourceManager.getDrawableResource(R.drawable.broken_image)
102+
103+
DrawableCompat.setTint(drawable, placeholderTintColor)
104+
105+
isShowingPlaceholder = true
106+
internalDrawable = drawable
107+
}
108+
109+
fun applyPlaceholderTint(color: Int) {
110+
placeholderTintColor = color
111+
112+
if (!isShowingPlaceholder) return
113+
114+
DrawableCompat.setTint(internalDrawable, color)
98115
}
99116

100117
override fun draw(canvas: Canvas) {

android/src/main/java/com/swmansion/enriched/common/parser/EnrichedSpanFactory.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import com.swmansion.enriched.common.spans.EnrichedUnderlineSpan
2222
import com.swmansion.enriched.common.spans.EnrichedUnorderedListSpan
2323

2424
interface EnrichedSpanFactory<T> {
25+
var textColor: Int
26+
2527
fun createAlignmentSpan(cssValue: String): EnrichedAlignmentSpan
2628

2729
fun createBoldSpan(style: T): EnrichedBoldSpan

android/src/main/java/com/swmansion/enriched/common/spans/EnrichedImageSpan.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import android.os.Looper
1313
import android.text.Spannable
1414
import android.text.style.ImageSpan
1515
import android.util.Log
16+
import androidx.core.graphics.drawable.DrawableCompat
1617
import androidx.core.graphics.drawable.toDrawable
1718
import androidx.core.graphics.withSave
1819
import com.swmansion.enriched.common.AsyncDrawable
@@ -26,9 +27,28 @@ open class EnrichedImageSpan :
2627
private var width: Int = 0
2728
private var height: Int = 0
2829

29-
constructor(drawable: Drawable, source: String, width: Int, height: Int) : super(drawable, source, ALIGN_BASELINE) {
30+
private var isStaticPlaceholder: Boolean = false
31+
32+
constructor(
33+
drawable: Drawable,
34+
source: String,
35+
width: Int,
36+
height: Int,
37+
isStaticPlaceholder: Boolean = false,
38+
) : super(drawable, source, ALIGN_BASELINE) {
3039
this.width = width
3140
this.height = height
41+
this.isStaticPlaceholder = isStaticPlaceholder
42+
}
43+
44+
fun refreshPlaceholderTint(color: Int) {
45+
val d = drawable
46+
47+
if (d is AsyncDrawable) {
48+
d.applyPlaceholderTint(color)
49+
} else if (isStaticPlaceholder) {
50+
DrawableCompat.setTint(d, color)
51+
}
3252
}
3353

3454
override fun draw(
@@ -134,11 +154,12 @@ open class EnrichedImageSpan :
134154
src: String,
135155
width: Int,
136156
height: Int,
157+
placeholderTintColor: Int,
137158
): Drawable? {
138159
var cleanPath = src
139160

140161
if (cleanPath.startsWith("http://") || cleanPath.startsWith("https://")) {
141-
return AsyncDrawable(cleanPath)
162+
return AsyncDrawable(cleanPath, placeholderTintColor)
142163
}
143164

144165
if (cleanPath.startsWith("file://")) {

android/src/main/java/com/swmansion/enriched/text/EnrichedTextSpanFactory.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.swmansion.enriched.text
22

3+
import android.graphics.Color
34
import com.swmansion.enriched.common.parser.EnrichedSpanFactory
45
import com.swmansion.enriched.text.spans.EnrichedTextAlignmentSpan
56
import com.swmansion.enriched.text.spans.EnrichedTextBlockQuoteSpan
@@ -23,6 +24,8 @@ import com.swmansion.enriched.text.spans.EnrichedTextUnderlineSpan
2324
import com.swmansion.enriched.text.spans.EnrichedTextUnorderedListSpan
2425

2526
class EnrichedTextSpanFactory : EnrichedSpanFactory<EnrichedTextStyle> {
27+
override var textColor: Int = Color.BLACK
28+
2629
override fun createAlignmentSpan(cssValue: String) = EnrichedTextAlignmentSpan(cssValue)
2730

2831
override fun createBoldSpan(style: EnrichedTextStyle) = EnrichedTextBoldSpan(style)
@@ -52,7 +55,7 @@ class EnrichedTextSpanFactory : EnrichedSpanFactory<EnrichedTextStyle> {
5255
source: String,
5356
width: Int,
5457
height: Int,
55-
) = EnrichedTextImageSpan.createEnrichedImageSpan(source, width, height)
58+
) = EnrichedTextImageSpan.createEnrichedImageSpan(source, width, height, textColor)
5659

5760
override fun createH1Span(style: EnrichedTextStyle) = EnrichedTextH1Span(style)
5861

android/src/main/java/com/swmansion/enriched/text/EnrichedTextView.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,20 @@ class EnrichedTextView : AppCompatTextView {
292292
}
293293

294294
fun setColor(colorInt: Int?) {
295-
if (colorInt == null) {
296-
setTextColor(Color.BLACK)
297-
return
298-
}
295+
val resolvedColor = colorInt ?: Color.BLACK
296+
297+
setTextColor(resolvedColor)
298+
spannableFactory.textColor = resolvedColor
299+
refreshImagePlaceholderTints(resolvedColor)
300+
}
299301

300-
setTextColor(colorInt)
302+
private fun refreshImagePlaceholderTints(color: Int) {
303+
val spanned = text as? Spanned ?: return
304+
val spans = spanned.getSpans(0, spanned.length, EnrichedTextImageSpan::class.java)
305+
306+
for (span in spans) {
307+
span.refreshPlaceholderTint(color)
308+
}
301309
}
302310

303311
fun setFontSize(size: Float) {

android/src/main/java/com/swmansion/enriched/text/spans/EnrichedTextImageSpan.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.swmansion.enriched.text.spans
33
import android.graphics.drawable.Drawable
44
import android.os.Handler
55
import android.os.Looper
6+
import androidx.core.graphics.drawable.DrawableCompat
67
import com.swmansion.enriched.R
78
import com.swmansion.enriched.common.AsyncDrawable
89
import com.swmansion.enriched.common.ResourceManager
@@ -15,7 +16,8 @@ class EnrichedTextImageSpan(
1516
source: String,
1617
width: Int,
1718
height: Int,
18-
) : EnrichedImageSpan(drawable, source, width, height),
19+
isStaticPlaceholder: Boolean = false,
20+
) : EnrichedImageSpan(drawable, source, width, height, isStaticPlaceholder),
1921
EnrichedTextSpan {
2022
override val dependsOnHtmlStyle = false
2123

@@ -44,14 +46,18 @@ class EnrichedTextImageSpan(
4446
src: String,
4547
width: Int,
4648
height: Int,
49+
placeholderTintColor: Int,
4750
): EnrichedImageSpan {
48-
var imgDrawable = prepareDrawableForImage(src, width, height)
51+
var imgDrawable = prepareDrawableForImage(src, width, height, placeholderTintColor)
52+
var isStaticPlaceholder = false
4953

5054
if (imgDrawable == null) {
5155
imgDrawable = ResourceManager.getDrawableResource(R.drawable.broken_image)
56+
isStaticPlaceholder = true
57+
DrawableCompat.setTint(imgDrawable, placeholderTintColor)
5258
}
5359

54-
return EnrichedTextImageSpan(imgDrawable, src, width, height)
60+
return EnrichedTextImageSpan(imgDrawable, src, width, height, isStaticPlaceholder)
5561
}
5662
}
5763
}

android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputSpannableFactory.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.swmansion.enriched.textinput
22

3+
import android.graphics.Color
34
import com.swmansion.enriched.common.parser.EnrichedSpanFactory
45
import com.swmansion.enriched.common.spans.EnrichedImageSpan
56
import com.swmansion.enriched.textinput.spans.EnrichedInputAlignmentSpan
@@ -25,6 +26,8 @@ import com.swmansion.enriched.textinput.spans.EnrichedInputUnorderedListSpan
2526
import com.swmansion.enriched.textinput.styles.HtmlStyle
2627

2728
class EnrichedTextInputSpannableFactory : EnrichedSpanFactory<HtmlStyle> {
29+
override var textColor: Int = Color.BLACK
30+
2831
override fun createAlignmentSpan(cssValue: String) = EnrichedInputAlignmentSpan(cssValue)
2932

3033
override fun createBoldSpan(style: HtmlStyle) = EnrichedInputBoldSpan(style)
@@ -54,7 +57,7 @@ class EnrichedTextInputSpannableFactory : EnrichedSpanFactory<HtmlStyle> {
5457
source: String,
5558
width: Int,
5659
height: Int,
57-
): EnrichedImageSpan = EnrichedInputImageSpan.createEnrichedImageSpan(source, width, height)
60+
): EnrichedImageSpan = EnrichedInputImageSpan.createEnrichedImageSpan(source, width, height, textColor)
5861

5962
override fun createH1Span(style: HtmlStyle) = EnrichedInputH1Span(style)
6063

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -545,12 +545,20 @@ class EnrichedTextInputView :
545545
}
546546

547547
fun setColor(colorInt: Int?) {
548-
if (colorInt == null) {
549-
setTextColor(Color.BLACK)
550-
return
551-
}
548+
val resolvedColor = colorInt ?: Color.BLACK
552549

553-
setTextColor(colorInt)
550+
setTextColor(resolvedColor)
551+
spannableFactory.textColor = resolvedColor
552+
refreshImagePlaceholderTints(resolvedColor)
553+
}
554+
555+
private fun refreshImagePlaceholderTints(color: Int) {
556+
val liveText = text ?: return
557+
val spans = liveText.getSpans(0, liveText.length, EnrichedInputImageSpan::class.java)
558+
559+
for (span in spans) {
560+
span.refreshPlaceholderTint(color)
561+
}
554562
}
555563

556564
fun setFontSize(size: Float) {

android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputImageSpan.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.swmansion.enriched.textinput.spans
22

33
import android.graphics.drawable.Drawable
4+
import androidx.core.graphics.drawable.DrawableCompat
45
import com.swmansion.enriched.R
56
import com.swmansion.enriched.common.ResourceManager
67
import com.swmansion.enriched.common.spans.EnrichedImageSpan
@@ -12,7 +13,8 @@ class EnrichedInputImageSpan(
1213
source: String,
1314
width: Int,
1415
height: Int,
15-
) : EnrichedImageSpan(drawable, source, width, height),
16+
isStaticPlaceholder: Boolean = false,
17+
) : EnrichedImageSpan(drawable, source, width, height, isStaticPlaceholder),
1618
EnrichedInputSpan {
1719
override val dependsOnHtmlStyle: Boolean = false
1820

@@ -23,14 +25,18 @@ class EnrichedInputImageSpan(
2325
src: String,
2426
width: Int,
2527
height: Int,
28+
placeholderTintColor: Int,
2629
): EnrichedInputImageSpan {
27-
var imgDrawable = prepareDrawableForImage(src, width, height)
30+
var imgDrawable = prepareDrawableForImage(src, width, height, placeholderTintColor)
31+
var isStaticPlaceholder = false
2832

2933
if (imgDrawable == null) {
3034
imgDrawable = ResourceManager.getDrawableResource(R.drawable.broken_image)
35+
isStaticPlaceholder = true
36+
DrawableCompat.setTint(imgDrawable, placeholderTintColor)
3137
}
3238

33-
return EnrichedInputImageSpan(imgDrawable, src, width, height)
39+
return EnrichedInputImageSpan(imgDrawable, src, width, height, isStaticPlaceholder)
3440
}
3541
}
3642
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ class ParametrizedStyles(
355355
}
356356

357357
val (imageStart, imageEnd) = spannable.getSafeSpanBoundaries(start, start + 1)
358-
val span = EnrichedInputImageSpan.createEnrichedImageSpan(src, width.toInt(), height.toInt())
358+
val span = EnrichedInputImageSpan.createEnrichedImageSpan(src, width.toInt(), height.toInt(), view.currentTextColor)
359359
span.observeAsyncDrawableLoaded(view.text)
360360

361361
spannable.setSpan(span, imageStart, imageEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

0 commit comments

Comments
 (0)