Supported div-state

commit_hash:7c930fbb9d0add7285ce31f94cee6bd2d23bf822
This commit is contained in:
burstein
2026-04-07 13:38:49 +03:00
parent b16e7c3f6e
commit 7246de5637
35 changed files with 498 additions and 35 deletions
+21
View File
@@ -642,6 +642,7 @@
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivEdgeInsets.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivEdgeInsets.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivShadow.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivShadow.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivSize.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivSize.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivVariableController.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/DivVariableController.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/Expression.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/Expression.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/Modifier.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/Modifier.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/UnitConversions.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/utils/UnitConversions.kt",
@@ -675,6 +676,8 @@
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/SizeModifiers.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/SizeModifiers.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/TransformModifiers.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/TransformModifiers.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/VisibilityActionModifiers.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/modifiers/VisibilityActionModifiers.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/state/DivStateView.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/state/DivStateView.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/state/ObserveActiveState.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/state/ObserveActiveState.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/DivTextView.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/DivTextView.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/SpanStyle.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/SpanStyle.kt",
"client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/TextStyle.kt":"divkit/public/client/android/compose/src/main/kotlin/com/yandex/div/compose/views/text/TextStyle.kt",
@@ -696,7 +699,9 @@
"client/android/compose/src/test/kotlin/com/yandex/div/compose/actions/VisibilityActionTrackerTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/actions/VisibilityActionTrackerTest.kt",
"client/android/compose/src/test/kotlin/com/yandex/div/compose/expressions/DivComposeExpressionResolverTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/expressions/DivComposeExpressionResolverTest.kt",
"client/android/compose/src/test/kotlin/com/yandex/div/compose/triggers/DivTriggerStorageTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/triggers/DivTriggerStorageTest.kt",
"client/android/compose/src/test/kotlin/com/yandex/div/compose/utils/DivVariableControllerTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/utils/DivVariableControllerTest.kt",
"client/android/compose/src/test/kotlin/com/yandex/div/compose/utils/ExpressionUtilsTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/utils/ExpressionUtilsTest.kt",
"client/android/compose/src/test/kotlin/com/yandex/div/compose/views/state/ObserveActiveStateTest.kt":"divkit/public/client/android/compose/src/test/kotlin/com/yandex/div/compose/views/state/ObserveActiveStateTest.kt",
"client/android/div-common.gradle":"divkit/public/client/android/div-common.gradle",
"client/android/div-core/build.gradle":"divkit/public/client/android/div-core/build.gradle",
"client/android/div-core/proguard-rules.pro":"divkit/public/client/android/div-core/proguard-rules.pro",
@@ -5233,6 +5238,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -6974,6 +6981,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -8715,6 +8724,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -10456,6 +10467,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_720x1600/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -12197,6 +12210,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -13938,6 +13953,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API30_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -15679,6 +15696,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewPixelCopy/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -17420,6 +17439,8 @@
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-height.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-fixed-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-separator/vertical-intrinsic-width.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/borders.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-states/default-state.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/all_attributes.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/auto-ellipsize-by-max-lines.png",
"client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API32_XXHDPI_1080x2400/viewRender/com.yandex.div.DivComposeScreenshotTest/div-text/border-with-stroke.png",
@@ -0,0 +1,33 @@
package com.yandex.div.compose.utils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.yandex.div.core.expression.variables.DivVariableController
import com.yandex.div.data.Variable
@Composable
internal fun DivVariableController.observedVariableValue(name: String): String? {
val variable = this.get(name)
if (variable == null) {
reporter.reportError("variable [$name] not found")
return null
}
if (variable !is Variable.StringVariable) {
reporter.reportError("variable [$name] is not a string variable")
return null
}
val state = remember(variable) {
mutableStateOf(variable.getValue())
}
DisposableEffect(variable) {
val observer: (Variable) -> Unit = { state.value = it.getValue() }
variable.addObserver(observer)
onDispose { variable.removeObserver(observer) }
}
return state.value as? String
}
@@ -10,6 +10,7 @@ import com.yandex.div.compose.views.modifiers.apply
import com.yandex.div.compose.views.modifiers.applyPaddings
import com.yandex.div.compose.utils.observedValue
import com.yandex.div.compose.utils.reporter
import com.yandex.div.compose.views.state.DivStateView
import com.yandex.div.compose.views.text.DivTextView
import com.yandex.div2.Div
import com.yandex.div2.DivVisibility
@@ -32,6 +33,7 @@ internal fun DivBlockView(
is Div.Gallery -> DivGalleryView(modifier, data.value)
is Div.Image -> DivImageView(modifier.applyPaddings(data), data.value)
is Div.Separator -> DivSeparatorView(modifier.applyPaddings(data), data.value)
is Div.State -> DivStateView(modifier, data.value)
is Div.Text -> DivTextView(modifier.applyPaddings(data), data.value)
is Div.Custom -> NotSupported("custom")
is Div.GifImage -> NotSupported("gif")
@@ -41,7 +43,6 @@ internal fun DivBlockView(
is Div.Pager -> NotSupported("pager")
is Div.Select -> NotSupported("select")
is Div.Slider -> NotSupported("slider")
is Div.State -> NotSupported("state")
is Div.Switch -> NotSupported("switch")
is Div.Tabs -> NotSupported("tabs")
is Div.Video -> NotSupported("video")
@@ -0,0 +1,27 @@
package com.yandex.div.compose.views.state
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import com.yandex.div.compose.utils.observedValue
import com.yandex.div.compose.views.DivBlockView
import com.yandex.div.compose.views.modifiers.padding
import com.yandex.div2.DivState
@Composable
internal fun DivStateView(
modifier: Modifier,
data: DivState
) {
val clipToBounds = data.clipToBounds.observedValue()
val modifier = if (clipToBounds) modifier.clipToBounds() else modifier
val activeState = data.observeActiveState()
val activeDiv = activeState?.div
Box(modifier = modifier.padding(data.paddings)) {
if (activeDiv != null) {
DivBlockView(activeDiv)
}
}
}
@@ -0,0 +1,32 @@
package com.yandex.div.compose.views.state
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.yandex.div.compose.context.LocalDivContext
import com.yandex.div.compose.utils.expressionResolver
import com.yandex.div.compose.utils.observedVariableValue
import com.yandex.div.compose.utils.reporter
import com.yandex.div2.DivState
@Composable
internal fun DivState.observeActiveState(): DivState.State? {
val stateVariable = stateIdVariable
if (stateVariable == null) {
reporter.reportWarning("div-state: state switching is not supported without state_id_variable")
}
val activeStateId = stateVariable?.let {
LocalDivContext.current.variableController.observedVariableValue(it)
}
val resolver = expressionResolver
val stateId = activeStateId ?: remember(defaultStateId, resolver) {
defaultStateId?.evaluate(resolver)
}
val activeState = stateId?.let { id -> states.find { it.stateId == id } }
if (activeState == null && stateId != null) {
reporter.reportError("div-state: state with id [$stateId] not found")
}
return activeState ?: states.firstOrNull()
}
@@ -9,6 +9,13 @@ class TestReporter : DivReporter() {
var lastError: String? = null
private set
var lastWarning: String? = null
private set
override fun reportWarning(message: String) {
lastWarning = message
}
override fun reportError(message: String) {
lastError = message
@@ -0,0 +1,163 @@
package com.yandex.div.compose.utils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.yandex.div.compose.DivComposeConfiguration
import com.yandex.div.compose.TestReporter
import com.yandex.div.compose.context.DivLocalContext
import com.yandex.div.compose.context.LocalDivContext
import com.yandex.div.compose.createContext
import com.yandex.div.compose.createExpressionResolver
import com.yandex.div.core.expression.variables.DivVariableController
import com.yandex.div.data.Variable
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
@RunWith(AndroidJUnit4::class)
class DivVariableControllerTest {
@get:Rule
val composeRule = createComposeRule()
private val variableController = DivVariableController()
private val reporter = TestReporter()
private val localContext = DivLocalContext(
actionHandlingContext = mock(),
expressionResolver = createExpressionResolver(
reporter = reporter,
variableController = variableController
),
functionProvider = mock(),
triggerStorage = mock(),
variableController = variableController
)
@Test
fun `returns current value of string variable`() {
variableController.declare(Variable.StringVariable("state", "active"))
var result by mutableStateOf<String?>(null)
setContent {
result = variableController.observedVariableValue("state")
}
assertEquals("active", result)
}
@Test
fun `returns null for nonexistent variable`() {
reporter.failOnError = false
var result by mutableStateOf<String?>("initial")
setContent {
result = variableController.observedVariableValue("nonexistent")
}
assertNull(result)
}
@Test
fun `reports error for nonexistent variable`() {
reporter.failOnError = false
setContent {
variableController.observedVariableValue("missing_var")
}
assertEquals("variable [missing_var] not found", reporter.lastError)
}
@Test
fun `returns null for non-string variable`() {
reporter.failOnError = false
variableController.declare(Variable.IntegerVariable("count", 42))
var result by mutableStateOf<String?>("initial")
setContent {
result = variableController.observedVariableValue("count")
}
assertNull(result)
}
@Test
fun `reports error for non-string variable`() {
reporter.failOnError = false
variableController.declare(Variable.BooleanVariable("flag", true))
setContent {
variableController.observedVariableValue("flag")
}
assertEquals("variable [flag] is not a string variable", reporter.lastError)
}
@Test
fun `updates when variable value changes`() {
val variable = Variable.StringVariable("state", "first")
variableController.declare(variable)
var result by mutableStateOf<String?>(null)
setContent {
result = variableController.observedVariableValue("state")
}
assertEquals("first", result)
variable.set("second")
composeRule.waitForIdle()
assertEquals("second", result)
}
@Test
fun `stops observing when leaving composition`() {
val variable = Variable.StringVariable("state", "initial")
variableController.declare(variable)
var show by mutableStateOf(true)
var result by mutableStateOf<String?>(null)
setContent {
if (show) {
result = variableController.observedVariableValue("state")
}
}
assertEquals("initial", result)
show = false
composeRule.waitForIdle()
variable.set("updated")
composeRule.waitForIdle()
assertEquals("initial", result)
}
private fun setContent(content: @Composable () -> Unit) {
composeRule.setContent {
val configuration = DivComposeConfiguration(
reporter = reporter,
variableController = variableController
)
val divContext = configuration.createContext(baseContext = LocalContext.current)
CompositionLocalProvider(
LocalContext provides divContext,
LocalDivContext provides localContext,
) {
content()
}
}
}
}
@@ -0,0 +1,207 @@
package com.yandex.div.compose.views.state
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.yandex.div.compose.DivComposeConfiguration
import com.yandex.div.compose.TestReporter
import com.yandex.div.compose.context.DivLocalContext
import com.yandex.div.compose.context.LocalDivContext
import com.yandex.div.compose.createContext
import com.yandex.div.compose.createExpressionResolver
import com.yandex.div.core.expression.variables.DivVariableController
import com.yandex.div.data.DivModelInternalApi
import com.yandex.div.data.Variable
import com.yandex.div.json.expressions.Expression
import com.yandex.div.test.data.constant
import com.yandex.div.test.data.expression
import com.yandex.div2.DivState
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
@OptIn(DivModelInternalApi::class)
@RunWith(AndroidJUnit4::class)
class ObserveActiveStateTest {
@get:Rule
val composeRule = createComposeRule()
private val variableController = DivVariableController()
private val reporter = TestReporter()
private val localContext = DivLocalContext(
actionHandlingContext = mock(),
expressionResolver = createExpressionResolver(
reporter = reporter,
variableController = variableController
),
functionProvider = mock(),
triggerStorage = mock(),
variableController = variableController
)
@Test
fun `resolves state by stateIdVariable`() {
val stateVar = Variable.StringVariable("current_state", "second")
variableController.declare(stateVar)
val divState = divState(
stateIdVariable = "current_state",
states = listOf(
DivState.State(stateId = "first"),
DivState.State(stateId = "second"),
)
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertEquals("second", result?.stateId)
}
@Test
fun `fallback to defaultStateId when no variable`() {
val divState = divState(
defaultStateId = constant("second"),
states = listOf(
DivState.State(stateId = "first"),
DivState.State(stateId = "second"),
)
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertEquals("second", result?.stateId)
}
@Test
fun `fallback to first state when nothing specified`() {
val divState = divState(
states = listOf(
DivState.State(stateId = "first"),
DivState.State(stateId = "second"),
)
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertEquals("first", result?.stateId)
}
@Test
fun `variable change triggers state switch`() {
val stateVar = Variable.StringVariable("current_state", "first")
variableController.declare(stateVar)
val divState = divState(
stateIdVariable = "current_state",
states = listOf(
DivState.State(stateId = "first"),
DivState.State(stateId = "second"),
)
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertEquals("first", result?.stateId)
stateVar.set("second")
composeRule.waitForIdle()
assertEquals("second", result?.stateId)
}
@Test
fun `defaultStateId is not reactive`() {
val counterVar = Variable.StringVariable("default_id", "first")
variableController.declare(counterVar)
val divState = divState(
defaultStateId = expression("@{default_id}"),
states = listOf(
DivState.State(stateId = "first"),
DivState.State(stateId = "second"),
)
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertEquals("first", result?.stateId)
counterVar.set("second")
composeRule.waitForIdle()
assertEquals("first", result?.stateId)
}
@Test
fun `reports warning when stateIdVariable is absent`() {
val divState = divState(
defaultStateId = constant("first"),
states = listOf(DivState.State(stateId = "first")),
)
setContent { divState.observeActiveState() }
assertEquals(
"div-state: state switching is not supported without state_id_variable",
reporter.lastWarning,
)
}
@Test
fun `reports error for unknown state id`() {
reporter.failOnError = false
variableController.declare(Variable.StringVariable("s", "missing"))
val divState = divState(
stateIdVariable = "s",
states = listOf(DivState.State(stateId = "first")),
)
var result by mutableStateOf<DivState.State?>(null)
setContent { result = divState.observeActiveState() }
assertNotNull(reporter.lastError)
assertEquals("first", result?.stateId)
}
private fun divState(
states: List<DivState.State>,
defaultStateId: Expression<String>? = null,
stateIdVariable: String? = null,
) = DivState(
states = states,
defaultStateId = defaultStateId,
stateIdVariable = stateIdVariable,
)
private fun setContent(content: @Composable () -> Unit) {
composeRule.setContent {
val configuration = DivComposeConfiguration(
reporter = reporter,
variableController = variableController
)
val divContext = configuration.createContext(baseContext = LocalContext.current)
CompositionLocalProvider(
LocalContext provides divContext,
LocalDivContext provides localContext,
) {
content()
}
}
}
}
@@ -160,6 +160,8 @@ class DivComposeScreenshotTest(case: String, escapedCase: String) {
"snapshot_test_data/div-radial-gradient",
// div-transform
"snapshot_test_data/div-transform",
// div-state
"snapshot_test_data/div-states",
).expandDirectories()
//TODO: to be stabilized
@@ -55,13 +55,7 @@
},
"text_alignment_vertical": "center",
"text_alignment_horizontal": "center",
"text": "Nondefault state",
"actions": [
{
"log_id": "default state",
"url": "div-action://set_state?state_id=0/state_container/default"
}
]
"text": "Nondefault state"
}
},
{
@@ -76,17 +70,8 @@
},
"text_alignment_vertical": "center",
"text_alignment_horizontal": "center",
"text": "Default state",
"actions": [
{
"log_id": "nondefault state",
"url": "div-action://set_state?state_id=0/state_container/nondefaut"
}
]
"text": "Default state"
}
},
{
"state_id": "empty"
}
]
}
@@ -37,13 +37,7 @@
},
"text_alignment_vertical": "center",
"text_alignment_horizontal": "center",
"text": "Nondefault state",
"actions": [
{
"log_id": "default state",
"url": "div-action://set_state?state_id=0/state_container/default"
}
]
"text": "Nondefault state"
}
},
{
@@ -58,17 +52,8 @@
},
"text_alignment_vertical": "center",
"text_alignment_horizontal": "center",
"text": "Default state",
"actions": [
{
"log_id": "nondefault state",
"url": "div-action://set_state?state_id=0/state_container/nondefaut"
}
]
"text": "Default state"
}
},
{
"state_id": "empty"
}
]
}