mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
,Fixed image preview not rebinding
This commit is contained in:
@@ -55,10 +55,10 @@ internal class DivImageBinder @Inject constructor(
|
||||
div.scale.observeAndGet(expressionResolver) { scale -> view.imageScale = scale.toImageScale() }
|
||||
)
|
||||
view.observeContentAlignment(expressionResolver, div.contentAlignmentHorizontal, div.contentAlignmentVertical)
|
||||
view.observePreview(divView, expressionResolver, errorCollector, div)
|
||||
view.addSubscription(
|
||||
div.imageUrl.observeAndGet(expressionResolver) { view.applyImage(divView, expressionResolver, errorCollector, div) }
|
||||
)
|
||||
view.observePreview(divView, expressionResolver, errorCollector, div)
|
||||
view.observeTint(expressionResolver, div.tintColor, div.tintMode)
|
||||
view.observeFilters(div.filters, divView, subscriber, expressionResolver)
|
||||
}
|
||||
@@ -122,12 +122,10 @@ internal class DivImageBinder @Inject constructor(
|
||||
div: DivImage) {
|
||||
div.preview?.let {
|
||||
val callback = { _: Any ->
|
||||
if (!isImageLoaded) {
|
||||
applyPreview(divView, resolver, div, errorCollector, synchronous = isHighPriorityShow(resolver, this, div))
|
||||
}
|
||||
applyPreview(divView, resolver, div, errorCollector, synchronous = isHighPriorityShow(resolver, this, div))
|
||||
}
|
||||
|
||||
addSubscription(it.observe(resolver, callback))
|
||||
addSubscription(it.observeAndGet(resolver, callback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,10 +134,24 @@ internal class DivImageBinder @Inject constructor(
|
||||
div: DivImage,
|
||||
errorCollector: ErrorCollector,
|
||||
synchronous: Boolean) {
|
||||
if (isImageLoaded) {
|
||||
return
|
||||
}
|
||||
|
||||
val newPreview = div.preview?.evaluate(resolver)
|
||||
|
||||
if (preview != null && newPreview == preview) {
|
||||
return
|
||||
}
|
||||
|
||||
resetPreviewLoaded()
|
||||
|
||||
preview = newPreview
|
||||
|
||||
placeholderLoader.applyPlaceholder(
|
||||
this,
|
||||
errorCollector,
|
||||
div.preview?.evaluate(resolver),
|
||||
newPreview,
|
||||
div.placeholderColor.evaluate(resolver),
|
||||
synchronous = synchronous,
|
||||
onSetPlaceholder = { drawable ->
|
||||
@@ -173,6 +185,7 @@ internal class DivImageBinder @Inject constructor(
|
||||
val isHighPriorityShowPreview = isHighPriorityShow(resolver, this, div)
|
||||
|
||||
resetImageLoaded()
|
||||
resetPreviewLoaded()
|
||||
|
||||
applyPreview(divView, resolver, div, errorCollector, synchronous = isHighPriorityShowPreview)
|
||||
|
||||
|
||||
+6
@@ -25,6 +25,7 @@ internal open class DivImageView @JvmOverloads constructor(
|
||||
|
||||
internal var div: DivImage? = null
|
||||
internal var imageUrl: Uri? = null
|
||||
internal var preview: String? = null
|
||||
|
||||
private var borderDrawer: DivBorderDrawer? = null
|
||||
override val border: DivBorder?
|
||||
@@ -51,6 +52,11 @@ internal open class DivImageView @JvmOverloads constructor(
|
||||
imageUrl = null
|
||||
}
|
||||
|
||||
fun resetPreviewLoaded() {
|
||||
super.resetImageLoaded()
|
||||
preview = null
|
||||
}
|
||||
|
||||
override fun setAdjustViewBounds(adjustViewBounds: Boolean) = Unit
|
||||
|
||||
override fun setCropToPadding(cropToPadding: Boolean) = Unit
|
||||
|
||||
+35
-20
@@ -15,18 +15,7 @@ import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.anyOrNull
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.never
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
import org.mockito.kotlin.*
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@@ -65,7 +54,13 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
@Test
|
||||
fun `bind image when image wasn't previously bound`() {
|
||||
val (view, divContainer) = createTestDiv("with_action.json")
|
||||
val (view, _) = createTestDiv("with_action.json")
|
||||
|
||||
val divContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
|
||||
binder.bindView(view, divContainer, divView)
|
||||
|
||||
@@ -75,10 +70,22 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
@Test
|
||||
fun `do not rebind image when imageUrl did not change and bitmap was not loaded`() {
|
||||
val (view, divContainer) = createTestDiv("with_action.json")
|
||||
val (view, _) = createTestDiv("with_action.json")
|
||||
|
||||
val divContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
|
||||
binder.bindView(view, divContainer, divView)
|
||||
|
||||
val (_, nextDivContainer) = createTestDiv("with_action.json")
|
||||
val nextDivContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
|
||||
binder.bindView(view, nextDivContainer, divView)
|
||||
|
||||
verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any())
|
||||
@@ -90,6 +97,7 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
val (view, divContainer) = createTestDiv("with_action.json")
|
||||
|
||||
binder.bindView(view, divContainer, divView)
|
||||
reset(placeholderLoader)
|
||||
|
||||
whenImageLoaded(divContainer.imageUrl.evaluate(ExpressionResolver.EMPTY).toString())
|
||||
|
||||
@@ -101,7 +109,13 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
@Test
|
||||
fun `bind image when bitmap was loaded but imageUrl changed`() {
|
||||
val (view, divContainer) = createTestDiv("with_action.json")
|
||||
val (view, _) = createTestDiv("with_action.json")
|
||||
|
||||
val divContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
|
||||
binder.bindView(view, divContainer, divView)
|
||||
|
||||
@@ -110,7 +124,7 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
val nextDivContainer = DivImage(imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression())
|
||||
binder.bindView(view, nextDivContainer, divView)
|
||||
|
||||
verify(placeholderLoader, times(2)).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any())
|
||||
verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any())
|
||||
verify(imageLoader).loadImage(eq(nextDivContainer.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()), any<DivImageDownloadCallback>())
|
||||
}
|
||||
|
||||
@@ -120,6 +134,7 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
val divContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
binder.bindView(view, divContainer, divView)
|
||||
@@ -132,6 +147,7 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
val nextDivContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/bar.png").asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
highPriorityPreviewShow = true.asExpression()
|
||||
)
|
||||
binder.bindView(view, nextDivContainer, divView)
|
||||
@@ -217,11 +233,10 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
@Test
|
||||
fun `tint color applied to preview`() {
|
||||
val preview = "iVBORw0KGgoAAAANSUhEUgAAAEEAAABACAYAAABFqxrgAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIsSURBVHgB7ZqNbcIwEIXdTsAI6QRtN2CDMgIblA1CJ2g3gE5QOkEYgQ3MBnSDV1s2KjKOf0gVfOY+yUImF8Kdz+aeDiEYhmEYhmEYhjwAJmq0anRqHGA42Plc1I5ycnbieB9SjUbUiF39VHSgnkRN6JVFPjoQE5HJvSiXzvPemxoPdwr1+qzGp3NdB2AhakCntWeVZz22y//IhuJQTiwcxzYRe/fgnIoMSt0OjTPfRuy/I/cHoRKEGPTT/whMUfTuOQ+6yH1yyHYoBsSLor6DsXUNBTVg6oEOabSwlaG9z5c1K0EF/OmBvtWPlco+JKiUz+qLTnG+j0+dX9ogLZDOdcpmZKo7mBT+CjjSuSupPycQsCPyWgHIUnfq9RXh1J8FntXYYHQoRUojX93tAtc/QK3MxWXqzkcHwr/n0uOQPsgae12Ln3XAeZ0ZdJUehqk7zQrUFR5GVndjkSugGme+jdgPUndjkRuE3FQmkfq5Qdg585eI/aMz3wvqwJS7qQdj6xqKWoBf8WmHG3u9T91pJGpolvRkQy4dqDdLkKfuQqxIBwPp6k4LrXXErg0FAyX3IpGh7qztBuGAzT3PqK8XaZ2SKcFA7b1IxLeTRD40u08wQksmOpmiVpeCIjDnRezwvI1eZCAYt9OLVB33vRpzca4+t5Fbq+xF/og8BqV/qUFgtQpWqwZcrlbp9CJj4DK1KlHbX/lAoRc5Bii5FzkmKLEXyTAMwzAMw9wQvznV1eV5FJ3aAAAAAElFTkSuQmCC"
|
||||
val (view, _) = createTestDiv("with_action.json")
|
||||
val divContainer = DivImage(
|
||||
imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(),
|
||||
preview = preview.asExpression(),
|
||||
preview = PREVIEW.asExpression(),
|
||||
tintColor = Color.parseColor("#ffffff").asExpression())
|
||||
|
||||
binder.bindView(view, divContainer, divView)
|
||||
@@ -232,7 +247,6 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
private fun whenImageLoaded(imageUrl: String) {
|
||||
val imageDownloadCallbackCaptor = argumentCaptor<DivImageDownloadCallback>()
|
||||
verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any())
|
||||
verify(imageLoader).loadImage(eq(imageUrl), imageDownloadCallbackCaptor.capture())
|
||||
val cachedBitmap = mock<CachedBitmap> {
|
||||
on { bitmap } doReturn mock()
|
||||
@@ -257,5 +271,6 @@ class DivImageBinderTest : DivBinderTest() {
|
||||
|
||||
companion object {
|
||||
private const val IMAGE_DIR = "div-image"
|
||||
private const val PREVIEW = "iVBORw0KGgoAAAANSUhEUgAAAEEAAABACAYAAABFqxrgAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIsSURBVHgB7ZqNbcIwEIXdTsAI6QRtN2CDMgIblA1CJ2g3gE5QOkEYgQ3MBnSDV1s2KjKOf0gVfOY+yUImF8Kdz+aeDiEYhmEYhmEYhjwAJmq0anRqHGA42Plc1I5ycnbieB9SjUbUiF39VHSgnkRN6JVFPjoQE5HJvSiXzvPemxoPdwr1+qzGp3NdB2AhakCntWeVZz22y//IhuJQTiwcxzYRe/fgnIoMSt0OjTPfRuy/I/cHoRKEGPTT/whMUfTuOQ+6yH1yyHYoBsSLor6DsXUNBTVg6oEOabSwlaG9z5c1K0EF/OmBvtWPlco+JKiUz+qLTnG+j0+dX9ogLZDOdcpmZKo7mBT+CjjSuSupPycQsCPyWgHIUnfq9RXh1J8FntXYYHQoRUojX93tAtc/QK3MxWXqzkcHwr/n0uOQPsgae12Ln3XAeZ0ZdJUehqk7zQrUFR5GVndjkSugGme+jdgPUndjkRuE3FQmkfq5Qdg585eI/aMz3wvqwJS7qQdj6xqKWoBf8WmHG3u9T91pJGpolvRkQy4dqDdLkKfuQqxIBwPp6k4LrXXErg0FAyX3IpGh7qztBuGAzT3PqK8XaZ2SKcFA7b1IxLeTRD40u08wQksmOpmiVpeCIjDnRezwvI1eZCAYt9OLVB33vRpzca4+t5Fbq+xF/og8BqV/qUFgtQpWqwZcrlbp9CJj4DK1KlHbX/lAoRc5Bii5FzkmKLEXyTAMwzAMw9wQvznV1eV5FJ3aAAAAAElFTkSuQmCC"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user