diff --git a/.mapping.json b/.mapping.json index a7195d430..c63cdc9d2 100644 --- a/.mapping.json +++ b/.mapping.json @@ -1033,6 +1033,7 @@ "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandlerProxy.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandlerProxy.kt", "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHideTooltipHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHideTooltipHandler.kt", "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStateHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStateHandler.kt", + "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStoredValueHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStoredValueHandler.kt", "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetVariableHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetVariableHandler.kt", "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedShowTooltipHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedShowTooltipHandler.kt", "client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedTimerHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedTimerHandler.kt", @@ -16824,6 +16825,7 @@ "schema/div-action-focus-element.json":"divkit/public/schema/div-action-focus-element.json", "schema/div-action-hide-tooltip.json":"divkit/public/schema/div-action-hide-tooltip.json", "schema/div-action-set-state.json":"divkit/public/schema/div-action-set-state.json", + "schema/div-action-set-stored-value.json":"divkit/public/schema/div-action-set-stored-value.json", "schema/div-action-set-variable.json":"divkit/public/schema/div-action-set-variable.json", "schema/div-action-show-tooltip.json":"divkit/public/schema/div-action-show-tooltip.json", "schema/div-action-timer.json":"divkit/public/schema/div-action-timer.json", @@ -17441,6 +17443,7 @@ "test_data/regression_test_data/timers/typed-common-timer.json":"divkit/public/test_data/regression_test_data/timers/typed-common-timer.json", "test_data/regression_test_data/tooltips.json":"divkit/public/test_data/regression_test_data/tooltips.json", "test_data/regression_test_data/typed-tooltips.json":"divkit/public/test_data/regression_test_data/typed-tooltips.json", + "test_data/regression_test_data/typed_stored_value.json":"divkit/public/test_data/regression_test_data/typed_stored_value.json", "test_data/regression_test_data/variables/div_gallery.json":"divkit/public/test_data/regression_test_data/variables/div_gallery.json", "test_data/regression_test_data/variables/div_image.json":"divkit/public/test_data/regression_test_data/variables/div_image.json", "test_data/regression_test_data/variables/div_indicator.json":"divkit/public/test_data/regression_test_data/variables/div_indicator.json", diff --git a/client/android/div-data/src/main/java/com/yandex/div/data/StoredValue.kt b/client/android/div-data/src/main/java/com/yandex/div/data/StoredValue.kt index 8c5417789..eef550383 100644 --- a/client/android/div-data/src/main/java/com/yandex/div/data/StoredValue.kt +++ b/client/android/div-data/src/main/java/com/yandex/div/data/StoredValue.kt @@ -2,6 +2,8 @@ package com.yandex.div.data import com.yandex.div.evaluable.types.Color import com.yandex.div.evaluable.types.Url +import org.json.JSONArray +import org.json.JSONObject sealed class StoredValue { abstract val name: String @@ -12,7 +14,9 @@ sealed class StoredValue { BOOLEAN("boolean"), NUMBER("number"), COLOR("color"), - URL("url"); + URL("url"), + ARRAY("array"), + DICT("dict"); companion object Converter { fun toString(obj: Type): String { @@ -27,6 +31,8 @@ sealed class StoredValue { NUMBER.value -> NUMBER COLOR.value -> COLOR URL.value -> URL + ARRAY.value -> ARRAY + DICT.value -> DICT else -> null } } @@ -63,6 +69,16 @@ sealed class StoredValue { val value: Url, ) : StoredValue() + data class ArrayStoredValue( + override val name: String, + val value: JSONArray + ) : StoredValue() + + data class DictStoredValue( + override val name: String, + val value: JSONObject + ) : StoredValue() + fun getValue(): Any = when (this) { is StringStoredValue -> value is IntegerStoredValue -> value @@ -70,6 +86,8 @@ sealed class StoredValue { is DoubleStoredValue -> value is ColorStoredValue -> value is UrlStoredValue -> value + is ArrayStoredValue -> value + is DictStoredValue -> value } fun getType(): Type = when (this) { @@ -79,6 +97,8 @@ sealed class StoredValue { is DoubleStoredValue -> Type.NUMBER is ColorStoredValue -> Type.COLOR is UrlStoredValue -> Type.URL + is ArrayStoredValue -> Type.ARRAY + is DictStoredValue -> Type.DICT } } diff --git a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/BuiltinFunctionProvider.kt b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/BuiltinFunctionProvider.kt index f7d297a5c..f544ecc88 100644 --- a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/BuiltinFunctionProvider.kt +++ b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/BuiltinFunctionProvider.kt @@ -187,6 +187,8 @@ object BuiltinFunctionProvider : FunctionProvider { registry.register(GetStoredBooleanValue) registry.register(GetStoredUrlValueWithStringFallback) registry.register(GetStoredUrlValueWithUrlFallback) + registry.register(GetStoredArrayValue) + registry.register(GetStoredDictValue) // Dict functions legacy registry.register(GetDictInteger) diff --git a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/FunctionValidator.kt b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/FunctionValidator.kt index f36f53850..fede025e8 100644 --- a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/FunctionValidator.kt +++ b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/FunctionValidator.kt @@ -19,7 +19,7 @@ internal object FunctionValidator { fun validateOverloading(nonValidatedFunction: Function, overloadedFunctions: List): Function { overloadedFunctions.forEach { function -> if (nonValidatedFunction.conflictsWith(function)) { - throw EvaluableException("Function $function has conflict with $function") + throw EvaluableException("Function $nonValidatedFunction has conflict with $function") } } return nonValidatedFunction @@ -60,7 +60,7 @@ private fun Function.conflictsWith(other: Function): Boolean { } else if (shorterArgumentList.size == longerArgumentList.size) { return shorterArgumentList.last().type == longerArgumentList.last().type } else if (longerArgumentList.size == shorterArgumentList.size + 1) { - return !longerArgumentList.last().isVariadic + return longerArgumentList.last().isVariadic } else { return false } diff --git a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/StoredValueFunctions.kt b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/StoredValueFunctions.kt index 162b270a7..955f089e2 100644 --- a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/StoredValueFunctions.kt +++ b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/function/StoredValueFunctions.kt @@ -4,6 +4,9 @@ import com.yandex.div.evaluable.* import com.yandex.div.evaluable.Function import com.yandex.div.evaluable.types.Color import com.yandex.div.evaluable.types.Url +import org.json.JSONArray +import org.json.JSONObject +import java.math.BigDecimal internal object GetStoredIntegerValue : Function() { @@ -222,3 +225,45 @@ internal object GetStoredUrlValueWithUrlFallback: Function() { } } + +internal abstract class GetStoredComplexValue : Function() { + override val isPure = false + override val declaredArgs = listOf( + FunctionArgument(type = EvaluableType.STRING), + ) + + @Suppress("UNCHECKED_CAST") + override fun evaluate( + evaluationContext: EvaluationContext, + expressionContext: ExpressionContext, + args: List + ): Any { + val storedValueName = args[0] as String + val storedValue = evaluationContext.storedValueProvider.get(storedValueName) + ?: throwExceptionOnFunctionEvaluationFailed(name, args, "Missing value.") + + return storedValue as? T + ?: throwWrongTypeException(name, args, resultType, storedValue) + } + + private fun throwWrongTypeException(functionName: String, args: List, expected: EvaluableType, actual: Any): Nothing { + val actualType = when (actual) { + is Int, is Double, is BigDecimal -> "Number" + is JSONObject -> "Dict" + is JSONArray -> "Array" + else -> actual.javaClass.simpleName + } + throwExceptionOnFunctionEvaluationFailed(functionName, args, + "Incorrect value type: expected ${expected.typeName}, got $actualType.") + } +} + +internal object GetStoredArrayValue : GetStoredComplexValue() { + override val name = "getStoredArrayValue" + override val resultType = EvaluableType.ARRAY +} + +internal object GetStoredDictValue : GetStoredComplexValue() { + override val name = "getStoredDictValue" + override val resultType = EvaluableType.DICT +} diff --git a/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStoredValueHandler.kt b/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStoredValueHandler.kt new file mode 100644 index 000000000..fb432645b --- /dev/null +++ b/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedSetStoredValueHandler.kt @@ -0,0 +1,58 @@ +package com.yandex.div.core.actions + +import com.yandex.div.core.expression.storedvalues.StoredValuesActionHandler +import com.yandex.div.core.view2.Div2View +import com.yandex.div.data.StoredValue +import com.yandex.div.evaluable.types.Color +import com.yandex.div.evaluable.types.Url +import com.yandex.div.json.expressions.ExpressionResolver +import com.yandex.div2.DivActionSetStoredValue +import com.yandex.div2.DivActionTyped +import com.yandex.div2.DivTypedValue +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +internal class DivActionTypedSetStoredValueHandler @Inject constructor() : DivActionTypedHandler { + + override fun handleAction( + scopeId: String?, + action: DivActionTyped, + view: Div2View, + resolver: ExpressionResolver + ): Boolean = when(action) { + is DivActionTyped.SetStoredValue -> { + handleAction(action.value, view, resolver) + true + } + else -> false + } + + private fun handleAction( + action: DivActionSetStoredValue, + view: Div2View, + resolver: ExpressionResolver + ) { + val name = action.name.evaluate(resolver) + val lifetime = action.lifetime.evaluate(resolver) + val storedValue = createStoredValue(action.value, name, resolver) + + StoredValuesActionHandler.executeAction(storedValue, lifetime, view) + } + + private fun createStoredValue( + value: DivTypedValue, + name: String, + resolver: ExpressionResolver + ): StoredValue = when (value) { + is DivTypedValue.Str -> StoredValue.StringStoredValue(name, value.value.value.evaluate(resolver)) + is DivTypedValue.Integer -> StoredValue.IntegerStoredValue(name, value.value.value.evaluate(resolver)) + is DivTypedValue.Bool -> StoredValue.BooleanStoredValue(name, value.value.value.evaluate(resolver)) + is DivTypedValue.Number -> StoredValue.DoubleStoredValue(name, value.value.value.evaluate(resolver)) + is DivTypedValue.Color -> StoredValue.ColorStoredValue(name, Color(value.value.value.evaluate(resolver))) + is DivTypedValue.Url -> StoredValue.UrlStoredValue(name, Url.from(value.value.value.evaluate(resolver).toString())) + is DivTypedValue.Array -> StoredValue.ArrayStoredValue(name, value.value.value.evaluate(resolver)) + is DivTypedValue.Dict -> StoredValue.DictStoredValue(name, value.value.value) + } + +} diff --git a/client/android/div/src/main/java/com/yandex/div/core/dagger/DivActionTypedModule.kt b/client/android/div/src/main/java/com/yandex/div/core/dagger/DivActionTypedModule.kt index 0c4f1d7de..e732ea797 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/dagger/DivActionTypedModule.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/dagger/DivActionTypedModule.kt @@ -8,6 +8,7 @@ import com.yandex.div.core.actions.DivActionTypedFocusElementHandler import com.yandex.div.core.actions.DivActionTypedHandler import com.yandex.div.core.actions.DivActionTypedHideTooltipHandler import com.yandex.div.core.actions.DivActionTypedSetStateHandler +import com.yandex.div.core.actions.DivActionTypedSetStoredValueHandler import com.yandex.div.core.actions.DivActionTypedSetVariableHandler import com.yandex.div.core.actions.DivActionTypedShowTooltipHandler import com.yandex.div.core.actions.DivActionTypedTimerHandler @@ -74,6 +75,12 @@ internal interface DivActionTypedModule { impl: DivActionTypedSetVariableHandler ): DivActionTypedHandler + @Binds + @IntoSet + fun provideSetStoredValueActionHandler( + impl: DivActionTypedSetStoredValueHandler + ): DivActionTypedHandler + @Binds @IntoSet fun provideShowTooltipActionHandler( diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt index 19ac78a62..cf435094d 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt @@ -37,18 +37,22 @@ internal object StoredValuesActionHandler { ?.run { StoredValue.Type.fromString(this) } ?: return false - return try { - val storedValue = createStoredValue(type, name, value) - val storedValuesController = div2View.div2Component.storedValuesController - val errorCollector = div2View.viewComponent.errorCollectors.getOrCreate( - div2View.divTag, - div2View.divData - ) - storedValuesController.setStoredValue(storedValue, lifetime, errorCollector) + val storedValue = try { + createStoredValue(type, name, value) } catch (e: StoredValueDeclarationException) { KAssert.fail {"Stored value '$name' declaration failed: ${e.message}" } - false + return false } + return executeAction(storedValue, lifetime, div2View) + } + + fun executeAction(storedValue: StoredValue, lifetime: Long, div2View: Div2View): Boolean { + val storedValuesController = div2View.div2Component.storedValuesController + val errorCollector = div2View.viewComponent.errorCollectors.getOrCreate( + div2View.divTag, + div2View.divData + ) + return storedValuesController.setStoredValue(storedValue, lifetime, errorCollector) } private fun Uri.getParam(forName: String): String? { @@ -72,6 +76,7 @@ internal object StoredValuesActionHandler { StoredValue.Type.NUMBER -> StoredValue.DoubleStoredValue(name, value.parseAsDouble()) StoredValue.Type.COLOR -> StoredValue.ColorStoredValue(name, value.parseAsColor()) StoredValue.Type.URL -> StoredValue.UrlStoredValue(name, value.parseAsUrl()) + else -> throw StoredValueDeclarationException("Cannot create stored value of type = '$type'.") } @Throws(StoredValueDeclarationException::class) diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt index 821edd6bd..2f968ba3a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt @@ -4,8 +4,10 @@ import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.view2.errors.ErrorCollector import com.yandex.div.data.StoredValue +import com.yandex.div.data.StoredValue.ArrayStoredValue import com.yandex.div.data.StoredValue.BooleanStoredValue import com.yandex.div.data.StoredValue.ColorStoredValue +import com.yandex.div.data.StoredValue.DictStoredValue import com.yandex.div.data.StoredValue.DoubleStoredValue import com.yandex.div.data.StoredValue.IntegerStoredValue import com.yandex.div.data.StoredValue.StringStoredValue @@ -115,6 +117,8 @@ internal class StoredValuesController @Inject constructor( StoredValue.Type.NUMBER -> DoubleStoredValue(name, getDouble(KEY_VALUE)) StoredValue.Type.COLOR -> ColorStoredValue(name, Color.parse(getString(KEY_VALUE))) StoredValue.Type.URL -> UrlStoredValue(name, Url.from(getString(KEY_VALUE))) + StoredValue.Type.ARRAY -> ArrayStoredValue(name, getJSONArray(KEY_VALUE)) + StoredValue.Type.DICT -> DictStoredValue(name, getJSONObject(KEY_VALUE)) } private fun StoredValue.toJSONObject(lifetime: Long): JSONObject { @@ -122,6 +126,8 @@ internal class StoredValuesController @Inject constructor( is StringStoredValue, is IntegerStoredValue, is BooleanStoredValue, + is ArrayStoredValue, + is DictStoredValue, is DoubleStoredValue -> getValue() is UrlStoredValue, is ColorStoredValue -> getValue().toString() diff --git a/schema/div-action-set-stored-value.json b/schema/div-action-set-stored-value.json new file mode 100644 index 000000000..e17b2f58d --- /dev/null +++ b/schema/div-action-set-stored-value.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "$description": "translations.json#/div_action_set_stored_value", + "properties": { + "type": { + "type": "string", + "enum": [ + "set_stored_value" + ] + }, + "name": { + "$description": "translations.json#/div_action_set_stored_value_name", + "type": "string" + }, + "value": { + "$description": "translations.json#/div_action_set_stored_value_value", + "$ref": "div-typed-value.json" + }, + "lifetime": { + "$description": "translations.json#/div_action_set_stored_value_lifetime", + "type": "integer" + } + }, + "platforms": [ + "android" + ], + "required": [ + "type", + "name", + "value", + "lifetime" + ] +} diff --git a/schema/div-action-typed.json b/schema/div-action-typed.json index 0756a57c2..905a77912 100644 --- a/schema/div-action-typed.json +++ b/schema/div-action-typed.json @@ -36,6 +36,9 @@ { "$ref": "div-action-set-state.json" }, + { + "$ref": "div-action-set-stored-value.json" + }, { "$ref": "div-action-set-variable.json" }, diff --git a/schema/translations.json b/schema/translations.json index 2a083c408..55cb63033 100644 --- a/schema/translations.json +++ b/schema/translations.json @@ -159,6 +159,22 @@ "en": "Indicates a state change:
  • `true`: The change is temporary and when the element is re-created, the state will change back to the initial one (default value).
  • `false` - The state change is permanent.
  • ", "ru": "Указывает на изменение состояния:
  • `true` — изменение временное и при пересоздании элемента состояние изменится на исходное (значение по умолчанию);
  • `false` — изменение состояния является постоянным.
  • " }, + "div_action_set_stored_value": { + "en": "Temporarily saves variable to the persistent storage.", + "ru": "Временно cохраняет переменную в хранилище." + }, + "div_action_set_stored_value_lifetime": { + "en": "Storing time in seconds.", + "ru": "Время хранения в секундах." + }, + "div_action_set_stored_value_name": { + "en": "Nave of stored variable.", + "ru": "Имя сохраняемой переменной." + }, + "div_action_set_stored_value_value": { + "en": "Value to be stored.", + "ru": "Сохраняемое значение." + }, "div_action_set_variable": { "en": "Assigns a value to the variable", "ru": "Присваивает переменной значение" diff --git a/test_data/expression_test_data/function_signatures_std.json b/test_data/expression_test_data/function_signatures_std.json index cc6e0495c..efcb75a33 100644 --- a/test_data/expression_test_data/function_signatures_std.json +++ b/test_data/expression_test_data/function_signatures_std.json @@ -1256,6 +1256,36 @@ "ios", "web" ] + }, + { + "name": "getStoredArrayValue(string) array", + "function_name": "getStoredArrayValue", + "doc": "Returns the stored value by its name. If the value doesn't exist or has incorrect type, the exception will be thrown.", + "arguments": [ + { + "type": "string", + "doc": "Stored value name." + } + ], + "result_type": "array", + "platforms": [ + "android" + ] + }, + { + "name": "getStoredDictValue(string) dict", + "function_name": "getStoredDictValue", + "doc": "Returns the stored value by its name. If the value doesn't exist or has incorrect type, the exception will be thrown.", + "arguments": [ + { + "type": "string", + "doc": "Stored value name." + } + ], + "result_type": "dict", + "platforms": [ + "android" + ] } ] } diff --git a/test_data/expression_test_data/functions_stored_values.json b/test_data/expression_test_data/functions_stored_values.json index bf12f6dcf..2cf694d53 100644 --- a/test_data/expression_test_data/functions_stored_values.json +++ b/test_data/expression_test_data/functions_stored_values.json @@ -109,6 +109,26 @@ "ios", "web" ] + }, + { + "expression": "@{getStoredArrayValue('unknown_var')}", + "expected": { + "type": "error", + "value": "Failed to evaluate [getStoredArrayValue('unknown_var')]. Missing value." + }, + "platforms": [ + "android" + ] + }, + { + "expression": "@{getStoredDictValue('unknown_var')}", + "expected": { + "type": "error", + "value": "Failed to evaluate [getStoredDictValue('unknown_var')]. Missing value." + }, + "platforms": [ + "android" + ] } ] } diff --git a/test_data/regression_test_data/index.json b/test_data/regression_test_data/index.json index da6f0c3e2..67678eafa 100644 --- a/test_data/regression_test_data/index.json +++ b/test_data/regression_test_data/index.json @@ -2407,7 +2407,8 @@ "title": "Persistent values storage", "platforms": [ "ios", - "web" + "web", + "android" ], "steps": [ "Press 'Store value for 10 seconds'", @@ -2421,6 +2422,30 @@ ], "file": "stored_value.json" }, + { + "title": "Persistent values storage with typed actions", + "tags": [ + "TypedActions" + ], + "platforms": [ + "android" + ], + "steps": [ + "Press 'Store string value for 10 seconds'", + "Press 'Store color value for 10 seconds'", + "Press 'Store url value for 10 seconds'", + "Press 'Store array value for 10 seconds'", + "Press 'Store dict value for 10 seconds'", + "Reopen this json in less than 10 seconds", + "Reopen this json in after 10 seconds" + ], + "expected_results": [ + "In the first open there should be the text 'No String value, https://no-stored-url.com, [], {}'.", + "In the second open there should new values should appear 'Stored typed, https://yandex.ru, [1, 2, 3], {\"key\": \"value\"}' on a green background.", + "In the last open there should be again as it was at first open." + ], + "file": "typed_stored_value.json" + }, { "title": "Patch container", "tags": [ diff --git a/test_data/regression_test_data/typed_stored_value.json b/test_data/regression_test_data/typed_stored_value.json new file mode 100644 index 000000000..ac8001c12 --- /dev/null +++ b/test_data/regression_test_data/typed_stored_value.json @@ -0,0 +1,156 @@ +{ + "templates": { + "button": { + "type": "text", + "height": { + "type": "fixed", + "value": 48 + }, + "margins": { + "top": 16, + "left": 16, + "right": 16, + "bottom": 16 + }, + "border": { + "corner_radius": 16 + }, + "background": [ + { + "type": "solid", + "color": "#00B341" + } + ], + "text_color": "#FFFFFF", + "font_size": 20, + "font_weight": "medium", + "text_alignment_vertical": "center", + "text_alignment_horizontal": "center" + } + }, + "card": { + "log_id": "card", + "states": [ + { + "state_id": 0, + "div": { + "type": "container", + "items": [ + { + "type": "text", + "font_size": 20, + "line_height": 24, + "text_alignment_horizontal": "center", + "font_weight": "bold", + "margins": { + "top": 16, + "left": 16, + "right": 16, + "bottom": 16 + }, + "text": "@{getStoredStringValue('storedString', 'No String value')},\n@{getStoredUrlValue('storedUrl', '') !: 'No Url value'},\n@{getStoredArrayValue('storedArray') !: 'No Array Value'},\n@{getStoredDictValue('storedDict') !: 'No Dict value'}", + "background": [ + { + "type": "solid", + "color": "@{getStoredColorValue('storedColor', '#FFFFFF')}" + } + ] + }, + { + "type": "button", + "text": "Store string value for 10 seconds", + "actions": [ + { + "log_id": "store_value_string", + "typed": { + "type": "set_stored_value", + "name": "storedString", + "lifetime": 10, + "value": { + "type": "string", + "value": "Stored typed" + } + } + } + ] + }, + { + "type": "button", + "text": "Store color value for 10 seconds", + "actions": [ + { + "log_id": "store_value_typed_color", + "typed": { + "type": "set_stored_value", + "name": "storedColor", + "lifetime": 10, + "value": { + "type": "color", + "value": "#00B341" + } + } + } + ] + }, + { + "type": "button", + "text": "Store url value for 10 seconds", + "actions": [ + { + "log_id": "store_value_typed_url", + "typed": { + "type": "set_stored_value", + "name": "storedUrl", + "lifetime": 10, + "value": { + "type": "url", + "value": "https://yandex.ru" + } + } + } + ] + }, + { + "type": "button", + "text": "Store array value for 10 seconds", + "actions": [ + { + "log_id": "store_value_array", + "typed": { + "type": "set_stored_value", + "name": "storedArray", + "lifetime": 10, + "value": { + "type": "array", + "value": [1, 2, 3] + } + } + } + ] + }, + { + "type": "button", + "text": "Store dict value for 10 seconds", + "actions": [ + { + "log_id": "store_value_dict", + "typed": { + "type": "set_stored_value", + "name": "storedDict", + "lifetime": 10, + "value": { + "type": "dict", + "value": { + "key": "value" + } + } + } + } + ] + } + ] + } + } + ] + } +}