Revert "change div-action scheme"

This commit is contained in:
darjke
2023-08-28 15:41:46 +03:00
parent 6133989849
commit 945668ff7f
25 changed files with 185 additions and 334 deletions
-5
View File
@@ -860,7 +860,6 @@
"client/android/div/src/main/java/com/yandex/div/core/Div2ImageStubProvider.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/Div2ImageStubProvider.java",
"client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java",
"client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java",
"client/android/div/src/main/java/com/yandex/div/core/DivActionHandlerInternal.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivActionHandlerInternal.kt",
"client/android/div/src/main/java/com/yandex/div/core/DivAutoLogger.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivAutoLogger.java",
"client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java",
"client/android/div/src/main/java/com/yandex/div/core/DivCreationTracker.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivCreationTracker.kt",
@@ -878,9 +877,6 @@
"client/android/div/src/main/java/com/yandex/div/core/DivViewFacade.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivViewFacade.java",
"client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java",
"client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java",
"client/android/div/src/main/java/com/yandex/div/core/action/DivActionInfo.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/action/DivActionInfo.kt",
"client/android/div/src/main/java/com/yandex/div/core/action/DivActionMapper.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/action/DivActionMapper.kt",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivTypedActionHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivTypedActionHandler.kt",
"client/android/div/src/main/java/com/yandex/div/core/animation/EaseInInterpolator.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/animation/EaseInInterpolator.kt",
"client/android/div/src/main/java/com/yandex/div/core/animation/EaseInOutInterpolator.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/animation/EaseInOutInterpolator.kt",
"client/android/div/src/main/java/com/yandex/div/core/animation/EaseInterpolator.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/animation/EaseInterpolator.kt",
@@ -14503,7 +14499,6 @@
"schema/div-absolute-edge-insets.json":"divkit/public/schema/div-absolute-edge-insets.json",
"schema/div-accessibility.json":"divkit/public/schema/div-accessibility.json",
"schema/div-action-base.json":"divkit/public/schema/div-action-base.json",
"schema/div-action-default.json":"divkit/public/schema/div-action-default.json",
"schema/div-action.json":"divkit/public/schema/div-action.json",
"schema/div-actionable.json":"divkit/public/schema/div-actionable.json",
"schema/div-alignment-horizontal.json":"divkit/public/schema/div-alignment-horizontal.json",
@@ -4,9 +4,9 @@ import android.net.Uri;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yandex.div.core.action.DivActionInfo;
import com.yandex.div.core.annotations.PublicApi;
import com.yandex.div.core.view2.Div2View;
import com.yandex.div2.DivAction;
import com.yandex.div2.DivDisappearAction;
import com.yandex.div2.DivGallery;
import com.yandex.div2.DivPager;
@@ -27,49 +27,49 @@ public interface Div2Logger {
/**
* Is called when element is clicked.
*/
default void logClick(Div2View divView, View view, DivActionInfo action) {
default void logClick(Div2View divView, View view, DivAction action) {
// do nothing
}
/**
* Is called when element is clicked.
*/
default void logClick(Div2View divView, View view, DivActionInfo action, String actionUid) {
default void logClick(Div2View divView, View view, DivAction action, String actionUid) {
logClick(divView, view, action);
}
/**
* Is called when element is long clicked.
*/
default void logLongClick(Div2View divView, View view, DivActionInfo action) {
default void logLongClick(Div2View divView, View view, DivAction action) {
// do nothing
}
/**
* Is called when element is long clicked.
*/
default void logLongClick(Div2View divView, View view, DivActionInfo action, String actionUid) {
default void logLongClick(Div2View divView, View view, DivAction action, String actionUid) {
logLongClick(divView, view, action);
}
/**
* Is called when element is double clicked.
*/
default void logDoubleClick(Div2View divView, View view, DivActionInfo action) {
default void logDoubleClick(Div2View divView, View view, DivAction action) {
// do nothing
}
/**
* Is called when element is double clicked.
*/
default void logDoubleClick(Div2View divView, View view, DivActionInfo action, String actionUid) {
default void logDoubleClick(Div2View divView, View view, DivAction action, String actionUid) {
logDoubleClick(divView, view, action);
}
/**
* Is called when element focus changed.
*/
default void logFocusChanged(Div2View divView, View view, DivActionInfo action, Boolean haveFocus) {
default void logFocusChanged(Div2View divView, View view, DivAction action, Boolean haveFocus) {
// do nothing
}
@@ -80,7 +80,7 @@ public interface Div2Logger {
// do nothing
}
default void logActiveTabTitleClick(@NonNull Div2View divView, int selectedTab, @NonNull DivActionInfo action) {
default void logActiveTabTitleClick(@NonNull Div2View divView, int selectedTab, @NonNull DivAction action) {
// do nothing
}
@@ -160,21 +160,22 @@ public interface Div2Logger {
* Is called when menu item is clicked.
*/
default void logPopupMenuItemClick(Div2View divView, int position,
@Nullable String text, DivActionInfo action) {
logPopupMenuItemClick(divView, position, text, action.url);
@Nullable String text, DivAction action) {
Uri url = action.url != null ? action.url.evaluate(divView.getExpressionResolver()) : null;
logPopupMenuItemClick(divView, position, text, url);
}
/**
* Is called when div state (alert) is swiped away.
*/
default void logSwipedAway(Div2View div2View, View view, DivActionInfo action) {
default void logSwipedAway(Div2View div2View, View view, DivAction action) {
//do nothing
}
/**
* Is called when trigger activates.
*/
default void logTrigger(Div2View divView, DivActionInfo action) {
default void logTrigger(Div2View divView, DivAction action) {
//do nothing
}
}
@@ -4,7 +4,6 @@ import android.net.Uri;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yandex.div.core.action.DivActionInfo;
import com.yandex.div.core.annotations.PublicApi;
import com.yandex.div.core.downloader.DivDownloadActionHandler;
import com.yandex.div.core.expression.storedvalues.StoredValuesActionHandler;
@@ -15,10 +14,9 @@ import com.yandex.div.core.view2.items.DivItemChangeActionHandler;
import com.yandex.div.data.VariableMutationException;
import com.yandex.div.internal.Assert;
import com.yandex.div2.DivAction;
import com.yandex.div2.DivVisibilityAction;
import com.yandex.div2.DivDisappearAction;
import com.yandex.div2.DivSightAction;
import com.yandex.div2.DivVisibilityAction;
import org.json.JSONObject;
/**
@@ -64,27 +62,31 @@ public class DivActionHandler {
* Handles the given div action.
* Call super implementation to automatically handle internal div schemes when overriding.
*
* @param info action info to handle
* @param action full div action to handle
* @param view calling DivView
* @return TRUE if uri was handled
*/
@CallSuper
public boolean handleAction(@NonNull DivActionInfo info, @NonNull DivViewFacade view) {
return handleActionUrl(info.url, view);
public boolean handleAction(@NonNull DivAction action, @NonNull DivViewFacade view) {
Uri url = action.url != null ? action.url.evaluate(view.getExpressionResolver()) : null;
if (DivDownloadActionHandler.canHandle(url, view)) {
return DivDownloadActionHandler.handleAction(action, (Div2View) view);
}
return handleActionUrl(url, view);
}
/**
* Handles the given div action.
* Call super implementation to automatically handle internal div schemes when overriding.
*
* @param info div action info to handle
* @param action full div action to handle
* @param view calling DivView
* @param actionUid action UUID string
* @return TRUE if uri was handled
*/
@CallSuper
public boolean handleAction(@NonNull DivActionInfo info, @NonNull DivViewFacade view, @NonNull String actionUid) {
return handleAction(info, view);
public boolean handleAction(@NonNull DivAction action, @NonNull DivViewFacade view, @NonNull String actionUid) {
return handleAction(action, view);
}
/**
@@ -179,33 +181,6 @@ public class DivActionHandler {
*/
public void handlePayload(@NonNull JSONObject payload) { /* not implemented */ }
/**
* Handles the given div action.
* Call super implementation to automatically handle internal div schemes when overriding.
*
* @param action full div action to handle
* @param view calling DivView
* @return TRUE if uri was handled
*/
public final boolean handleAction(@NonNull DivAction action, @NonNull DivViewFacade view) {
return DivActionHandlerInternal
.handleAction(action, view, info -> handleAction(info, view));
}
/**
* Handles the given div action.
* Call super implementation to automatically handle internal div schemes when overriding.
*
* @param action full div action to handle
* @param view calling DivView
* @param actionUid action UUID string
* @return TRUE if uri was handled
*/
public final boolean handleAction(@NonNull DivAction action, @NonNull DivViewFacade view, @NonNull String actionUid) {
return DivActionHandlerInternal
.handleAction(action, view, info -> handleAction(info, view, actionUid));
}
/**
* Handles the URI with {@code div-action} scheme.
*
@@ -1,32 +0,0 @@
package com.yandex.div.core
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.action.toInfo
import com.yandex.div.core.actions.DivTypedActionHandler
import com.yandex.div.core.downloader.DivDownloadActionHandler
import com.yandex.div.core.view2.Div2View
import com.yandex.div2.DivAction
internal object DivActionHandlerInternal {
@JvmStatic
fun handleAction(
action: DivAction,
view: DivViewFacade,
divActionInfoHandler: (DivActionInfo) -> Boolean
): Boolean {
return when (action) {
is DivAction.Default -> {
val info = action.toInfo(view.expressionResolver)
when {
DivDownloadActionHandler.canHandle(info.url, view) -> {
DivDownloadActionHandler.handleAction(action, view as Div2View)
}
else -> divActionInfoHandler(info)
}
}
else -> DivTypedActionHandler.handleAction(action, view)
}
}
}
@@ -1,22 +0,0 @@
package com.yandex.div.core.action
import android.net.Uri
import com.yandex.div.core.annotations.PublicApi
import com.yandex.div2.DivActionDefault
import com.yandex.div2.DivDownloadCallbacks
import org.json.JSONObject
/**
* Model for default Div2 UI-events
*/
@PublicApi
data class DivActionInfo(
@JvmField val downloadCallbacks: DivDownloadCallbacks? = null,
@JvmField val logId: String,
@JvmField val logUrl: Uri? = null,
@JvmField val menuItems: List<DivActionDefault.MenuItem>? = null,
@JvmField val payload: JSONObject? = null,
@JvmField val referer: Uri? = null,
@JvmField val target: DivActionDefault.Target? = null,
@JvmField val url: Uri? = null,
)
@@ -1,20 +0,0 @@
package com.yandex.div.core.action
import com.yandex.div.json.expressions.ExpressionResolver
import com.yandex.div2.DivAction
internal fun DivAction.toInfo(resolver: ExpressionResolver): DivActionInfo = when (this) {
is DivAction.Default -> toInfo(resolver)
}
internal fun DivAction.Default.toInfo(resolver: ExpressionResolver) = DivActionInfo(
downloadCallbacks = value.downloadCallbacks,
logId = value.logId,
logUrl = value.logUrl?.evaluate(resolver),
menuItems = value.menuItems,
payload = value.payload,
referer = value.referer?.evaluate(resolver),
target = value.target?.evaluate(resolver),
url = value.url?.evaluate(resolver)
)
@@ -1,14 +0,0 @@
package com.yandex.div.core.actions
import com.yandex.div.core.DivViewFacade
import com.yandex.div2.DivAction
internal object DivTypedActionHandler {
@JvmStatic
fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
when (action) {
is DivAction.Default -> return false
}
}
}
@@ -33,10 +33,9 @@ internal object DivDownloadActionHandler {
}
@JvmStatic
fun handleAction(action: DivAction.Default, view: Div2View): Boolean {
val defaultAction = action.value
val uri = defaultAction.url?.evaluate(view.expressionResolver) ?: return false
return handleAction(uri, defaultAction.downloadCallbacks, view)
fun handleAction(action: DivAction, view: Div2View): Boolean {
val uri = action.url?.evaluate(view.expressionResolver) ?: return false
return handleAction(uri, action.downloadCallbacks, view)
}
@JvmStatic
@@ -4,7 +4,6 @@ import com.yandex.div.core.Div2Logger
import com.yandex.div.core.Disposable
import com.yandex.div.core.DivActionHandler
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.toInfo
import com.yandex.div.core.annotations.Mockable
import com.yandex.div.core.expression.variables.VariableController
import com.yandex.div.core.view2.Div2View
@@ -144,8 +143,7 @@ private class TriggerExecutor(
}
actions.forEach {
val info = it.toInfo(viewFacade.expressionResolver)
logger.logTrigger(viewFacade as Div2View, info)
logger.logTrigger(viewFacade as Div2View, it)
divActionHandler.handleAction(it, viewFacade)
}
}
@@ -1,7 +1,6 @@
package com.yandex.div.core.view2.divs
import com.yandex.android.beacon.SendBeaconManager
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.annotations.Mockable
import com.yandex.div.core.dagger.DivScope
import com.yandex.div.core.dagger.ExperimentFlag
@@ -9,6 +8,7 @@ import com.yandex.div.core.experiments.Experiment.TAP_BEACONS_ENABLED
import com.yandex.div.core.experiments.Experiment.VISIBILITY_BEACONS_ENABLED
import com.yandex.div.internal.KAssert
import com.yandex.div.json.expressions.ExpressionResolver
import com.yandex.div2.DivAction
import com.yandex.div2.DivSightAction
import dagger.Lazy
import javax.inject.Inject
@@ -21,15 +21,15 @@ internal class DivActionBeaconSender @Inject constructor(
@ExperimentFlag(VISIBILITY_BEACONS_ENABLED) private val isVisibilityBeaconsEnabled: Boolean,
) {
fun sendTapActionBeacon(actionInfo: DivActionInfo) {
val url = actionInfo.logUrl
fun sendTapActionBeacon(action: DivAction, resolver: ExpressionResolver) {
val url = action.logUrl?.evaluate(resolver)
if (isTapBeaconsEnabled && url != null) {
val sendBeaconManager = sendBeaconManagerLazy.get()
if (sendBeaconManager == null) {
KAssert.fail { "SendBeaconManager was not configured" }
return
}
sendBeaconManager.addUrl(url, actionInfo.toHttpHeaders(), actionInfo.payload)
sendBeaconManager.addUrl(url, action.toHttpHeaders(resolver), action.payload)
}
}
@@ -45,22 +45,22 @@ internal class DivActionBeaconSender @Inject constructor(
}
}
fun sendSwipeOutActionBeacon(actionInfo: DivActionInfo) {
val url = actionInfo.logUrl
fun sendSwipeOutActionBeacon(action: DivAction, resolver: ExpressionResolver) {
val url = action.logUrl?.evaluate(resolver)
if (url != null) {
val sendBeaconManager = sendBeaconManagerLazy.get()
if (sendBeaconManager == null) {
KAssert.fail { "SendBeaconManager was not configured" }
return
}
sendBeaconManager.addUrl(url, actionInfo.toHttpHeaders(), actionInfo.payload)
sendBeaconManager.addUrl(url, action.toHttpHeaders(resolver), action.payload)
}
}
private fun DivActionInfo.toHttpHeaders(): Map<String, String> {
private fun DivAction.toHttpHeaders(resolver: ExpressionResolver): Map<String, String> {
val headers = mutableMapOf<String, String>()
referer?.let { referer ->
headers[HTTP_HEADER_REFERER] = referer.toString()
headers[HTTP_HEADER_REFERER] = referer.evaluate(resolver).toString()
}
return headers
}
@@ -8,7 +8,6 @@ import androidx.appcompat.widget.PopupMenu
import com.yandex.div.R
import com.yandex.div.core.Div2Logger
import com.yandex.div.core.DivActionHandler
import com.yandex.div.core.action.toInfo
import com.yandex.div.core.annotations.Mockable
import com.yandex.div.core.dagger.DivScope
import com.yandex.div.core.dagger.ExperimentFlag
@@ -28,7 +27,6 @@ import com.yandex.div.internal.util.allIsNullOrEmpty
import com.yandex.div.internal.widget.menu.OverflowMenuWrapper
import com.yandex.div2.DivAccessibility
import com.yandex.div2.DivAction
import com.yandex.div2.DivActionDefault
import com.yandex.div2.DivAnimation
import java.util.*
import javax.inject.Inject
@@ -103,8 +101,8 @@ internal class DivActionBinder @Inject constructor(
return
}
val menuAction = actions.filterIsInstance<DivAction.Default>().firstOrNull { action ->
!action.value.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
val menuAction = actions.firstOrNull { action ->
!action.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
}
fun setTapListener(listener: View.OnClickListener) {
@@ -120,9 +118,9 @@ internal class DivActionBinder @Inject constructor(
if (menuAction != null) {
prepareMenu(target, divView, menuAction) { overflowMenuWrapper ->
setTapListener {
val divActionInfo = menuAction.toInfo(divView.expressionResolver)
logger.logClick(divView, target, divActionInfo)
divActionBeaconSender.sendTapActionBeacon(divActionInfo)
logger.logClick(divView, target, menuAction)
divActionBeaconSender.sendTapActionBeacon(menuAction,
divView.expressionResolver)
overflowMenuWrapper.onMenuClickListener.onClick(target)
}
}
@@ -145,21 +143,18 @@ internal class DivActionBinder @Inject constructor(
return
}
val menuAction = actions.filterIsInstance<DivAction.Default>().firstOrNull { action ->
!action.value.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
val menuAction = actions.firstOrNull { action ->
!action.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
}
if (menuAction != null) {
prepareMenu(target, divView, menuAction) { overflowMenuWrapper ->
target.setOnLongClickListener {
val uuid = UUID.randomUUID().toString()
divActionBeaconSender.sendTapActionBeacon(
menuAction.toInfo(divView.expressionResolver))
divActionBeaconSender.sendTapActionBeacon(menuAction,
divView.expressionResolver)
overflowMenuWrapper.onMenuClickListener.onClick(target)
actions.forEach { action ->
val info = action.toInfo(divView.expressionResolver)
logger.logLongClick(divView, target, info, uuid)
}
actions.forEach { action -> logger.logLongClick(divView, target, action, uuid) }
return@setOnLongClickListener true
}
@@ -208,15 +203,15 @@ internal class DivActionBinder @Inject constructor(
return
}
val menuAction = actions.filterIsInstance<DivAction.Default>().firstOrNull { action ->
!action.value.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
val menuAction = actions.firstOrNull { action ->
!action.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems
}
if (menuAction != null) {
prepareMenu(target, divView, menuAction) { overflowMenuWrapper ->
divGestureListener.onDoubleTapListener = {
val actionInfo = menuAction.toInfo(divView.expressionResolver)
logger.logDoubleClick(divView, target, actionInfo)
divActionBeaconSender.sendTapActionBeacon(actionInfo)
logger.logDoubleClick(divView, target, menuAction)
divActionBeaconSender.sendTapActionBeacon(menuAction,
divView.expressionResolver)
overflowMenuWrapper.onMenuClickListener.onClick(target)
}
}
@@ -237,16 +232,16 @@ internal class DivActionBinder @Inject constructor(
val uuid = UUID.randomUUID().toString()
actions.forEach { action ->
val actionInfo = action.toInfo(divView.expressionResolver)
when(actionLogType) {
LOG_CLICK -> logger.logClick(divView, target, actionInfo, uuid)
LOG_LONG_CLICK -> logger.logLongClick(divView, target, actionInfo, uuid)
LOG_DOUBLE_CLICK -> logger.logDoubleClick(divView, target, actionInfo, uuid)
LOG_FOCUS -> logger.logFocusChanged(divView, target, actionInfo, true)
LOG_BLUR -> logger.logFocusChanged(divView, target, actionInfo, false)
LOG_CLICK -> logger.logClick(divView, target, action, uuid)
LOG_LONG_CLICK -> logger.logLongClick(divView, target, action, uuid)
LOG_DOUBLE_CLICK -> logger.logDoubleClick(divView, target, action, uuid)
LOG_FOCUS -> logger.logFocusChanged(divView, target, action, true)
LOG_BLUR -> logger.logFocusChanged(divView, target, action, false)
else -> Assert.fail("Please, add new logType")
}
divActionBeaconSender.sendTapActionBeacon(actionInfo)
divActionBeaconSender.sendTapActionBeacon(action,
divView.expressionResolver)
handleAction(divView, action, uuid)
}
}
@@ -266,13 +261,12 @@ internal class DivActionBinder @Inject constructor(
}
internal fun handleTapClick(divView: Div2View, target: View, actions: List<DivAction>) {
val menuAction = actions.filterIsInstance<DivAction.Default>()
.firstOrNull { action -> !action.value.menuItems.isNullOrEmpty() }
val menuAction = actions.firstOrNull { action -> !action.menuItems.isNullOrEmpty() }
if (menuAction != null) {
prepareMenu(target, divView, menuAction) { overflowMenuWrapper ->
val divActionInfo = menuAction.toInfo(divView.expressionResolver)
logger.logClick(divView, target, divActionInfo)
divActionBeaconSender.sendTapActionBeacon(divActionInfo)
logger.logClick(divView, target, menuAction)
divActionBeaconSender.sendTapActionBeacon(menuAction,
divView.expressionResolver)
overflowMenuWrapper.onMenuClickListener.onClick(target)
}
} else {
@@ -283,12 +277,12 @@ internal class DivActionBinder @Inject constructor(
private inline fun prepareMenu(
target: View,
divView: Div2View,
action: DivAction.Default,
action: DivAction,
onPrepared: (OverflowMenuWrapper) -> Unit
) {
val menuItems = action.value.menuItems
val menuItems = action.menuItems
if (menuItems == null) {
KAssert.fail { "Unable to bind empty menu action: ${action.value.logId}" }
KAssert.fail { "Unable to bind empty menu action: ${action.logId}" }
return
}
@@ -308,7 +302,7 @@ internal class DivActionBinder @Inject constructor(
private inner class MenuWrapperListener(
private val divView: Div2View,
private val items: List<DivActionDefault.MenuItem>
private val items: List<DivAction.MenuItem>
) : OverflowMenuWrapper.Listener.Simple() {
override fun onMenuCreated(popupMenu: PopupMenu) {
@@ -326,18 +320,17 @@ internal class DivActionBinder @Inject constructor(
KAssert.fail { "Menu item does not have any action" }
return@bulkActions
}
actions
.forEach { action ->
val actionInfo = action.toInfo(divView.expressionResolver)
logger.logPopupMenuItemClick(
divView,
itemPosition,
itemData.text.evaluate(expressionResolver),
actionInfo
)
divActionBeaconSender.sendTapActionBeacon(actionInfo)
handleAction(divView, action)
}
actions.forEach { action ->
logger.logPopupMenuItemClick(
divView,
itemPosition,
itemData.text.evaluate(expressionResolver),
action
)
divActionBeaconSender.sendTapActionBeacon(action,
divView.expressionResolver)
handleAction(divView, action)
}
actionsHandled = true
}
actionsHandled
@@ -10,7 +10,6 @@ import androidx.transition.TransitionManager
import androidx.transition.TransitionSet
import androidx.transition.Visibility
import com.yandex.div.core.Div2Logger
import com.yandex.div.core.action.toInfo
import com.yandex.div.core.dagger.DivScope
import com.yandex.div.core.downloader.DivPatchCache
import com.yandex.div.core.downloader.DivPatchManager
@@ -192,9 +191,8 @@ internal class DivStateBinder @Inject constructor(
divView.bulkActions {
actions.forEach {
divActionBinder.handleAction(divView, it)
val actionInfo = it.toInfo(divView.expressionResolver)
div2Logger.logSwipedAway(divView, layout, actionInfo)
divActionBeaconSender.sendSwipeOutActionBeacon(actionInfo)
div2Logger.logSwipedAway(divView, layout, it)
divActionBeaconSender.sendSwipeOutActionBeacon(it, resolver)
}
}
}
@@ -2,7 +2,6 @@ package com.yandex.div.core.view2.divs.tabs
import androidx.viewpager.widget.ViewPager
import com.yandex.div.core.Div2Logger
import com.yandex.div.core.action.toInfo
import com.yandex.div.core.view2.Div2View
import com.yandex.div.core.view2.DivVisibilityActionTracker
import com.yandex.div.core.view2.divs.DivActionBinder
@@ -56,12 +55,11 @@ internal class DivTabsEventManager(
}
override fun onActiveTabClicked(action: DivAction, tabPosition: Int) {
if (action is DivAction.Default && action.value.menuItems != null) {
if (action.menuItems != null) {
// TODO(MORDAANDROID-90): handle case with menuItems != null
KLog.w(TAG) { "non-null menuItems ignored in title click action" }
}
val info = action.toInfo(div2View.expressionResolver)
div2Logger.logActiveTabTitleClick(div2View, tabPosition, info)
div2Logger.logActiveTabTitleClick(div2View, tabPosition, action)
actionBinder.handleAction(div2View, action)
}
@@ -23,8 +23,8 @@ internal fun assertActionApplied(divView: Div2View, target: View, actionUri: Uri
actionAnimation = any(),
)
val action = actionCaptor.firstValue.filterIsInstance<DivAction.Default>().find {
action -> action.value.url?.evaluate(divView.expressionResolver) == actionUri
val action = actionCaptor.firstValue.find {
action -> action.url?.evaluate(divView.expressionResolver) == actionUri
}
assertNotNull(action)
assertTrue(target.hasOnClickListeners())
@@ -166,8 +166,6 @@ class PagerSelectedActionsDispatcherTest {
private const val PAGER_DIR = "div-pager"
private const val CARD_ID = "div_pager_card"
private fun urlEq(urlStr: String) = argThat<DivAction.Default> {
value.url?.evaluate(ExpressionResolver.EMPTY).toString() == urlStr
}
private fun urlEq(urlStr: String) = argThat<DivAction> { url?.evaluate(ExpressionResolver.EMPTY).toString() == urlStr }
}
}
@@ -3,7 +3,7 @@ package com.yandex.div.utils
import android.net.Uri
import com.yandex.div.core.DivActionHandler
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div2.DivAction
private const val DIV_UI_TEST_SCHEME = "ui-test"
private const val CLICK_ACTION_HOST = "click"
@@ -13,13 +13,13 @@ private const val CLICK_DESCRIPTION_PARAM = "description"
class UiTestDivActionHandler(
private val onClick: ((clickType: String, description: String) -> Unit)? = null
) : DivActionHandler() {
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val url = info.url ?: return false
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
val url = action.url?.evaluate(view.expressionResolver) ?: return false
if (url.scheme == DIV_UI_TEST_SCHEME) {
handleDemoActionUrl(url, view)
return true
}
return super.handleAction(info, view)
return super.handleAction(action, view)
}
private fun handleDemoActionUrl(url: Uri, view: DivViewFacade) {
@@ -2,9 +2,9 @@ package com.yandex.divkit.demo.div
import android.view.View
import com.yandex.div.core.Div2Logger
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.view2.Div2View
import com.yandex.div.internal.KLog
import com.yandex.div2.DivAction
import com.yandex.div2.DivDisappearAction
import com.yandex.div2.DivGallery
import com.yandex.div2.DivPager
@@ -37,25 +37,25 @@ class DemoDiv2Logger(
fun clearLogActions() = capturedLogActions.clear()
}
override fun logClick(divView: Div2View, view: View, action: DivActionInfo) {
override fun logClick(divView: Div2View, view: View, action: DivAction) {
log(TAG) {
"logClick(cardId = ${divView.logId}, id = ${action.logId})"
}
}
override fun logLongClick(divView: Div2View, view: View, action: DivActionInfo) {
override fun logLongClick(divView: Div2View, view: View, action: DivAction) {
log(TAG) {
"logLongClick(cardId = ${divView.logId}, id = ${action.logId})"
}
}
override fun logDoubleClick(divView: Div2View, view: View, action: DivActionInfo) {
override fun logDoubleClick(divView: Div2View, view: View, action: DivAction) {
log(TAG) {
"logDoubleClick(cardId = ${divView.logId}, id = ${action.logId})"
}
}
override fun logFocusChanged(divView: Div2View, view: View, action: DivActionInfo, haveFocus: Boolean) {
override fun logFocusChanged(divView: Div2View, view: View, action: DivAction, haveFocus: Boolean) {
log(TAG) {
"logFocusChanged(cardId = ${divView.logId}, id = ${action.logId}, haveFocus = $haveFocus)"
}
@@ -119,7 +119,7 @@ class DemoDiv2Logger(
}
}
override fun logTrigger(divView: Div2View, action: DivActionInfo) {
override fun logTrigger(divView: Div2View, action: DivAction) {
log(TAG) {
"logTrigger(cardId = ${divView.logId}, id = ${action.logId})"
}
@@ -24,7 +24,6 @@ import com.google.zxing.integration.android.IntentResult
import com.yandex.div.DivDataTag
import com.yandex.div.core.DivDataChangeListener
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.state.DivStateChangeListener
import com.yandex.div.core.state.DivStateTransition
import com.yandex.div.core.util.SafeAlertDialogBuilder
@@ -37,6 +36,7 @@ import com.yandex.div.lottie.DivLottieExtensionHandler
import com.yandex.div.shimmer.DivShimmerExtensionHandler
import com.yandex.div.zoom.DivPinchToZoomConfiguration
import com.yandex.div.zoom.DivPinchToZoomExtensionHandler
import com.yandex.div2.DivAction
import com.yandex.div2.DivData
import com.yandex.divkit.demo.Container
import com.yandex.divkit.demo.R
@@ -170,9 +170,9 @@ class Div2Activity : AppCompatActivity() {
uriHandler: DivkitDemoUriHandler
) : DemoDivActionHandler(uriHandler) {
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val url = info.url ?: return false
return handleDemoActionUrl(url) || super.handleAction(info, view)
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
val url = action.url?.evaluate(view.expressionResolver) ?: return false
return handleDemoActionUrl(url) || super.handleAction(action, view)
}
private fun handleDemoActionUrl(uri: Uri): Boolean {
@@ -19,7 +19,6 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.yandex.div.core.Div2Context
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.experiments.Experiment
import com.yandex.div.core.util.SafeAlertDialogBuilder
import com.yandex.div.core.view2.Div2View
@@ -31,6 +30,7 @@ import com.yandex.div.lottie.DivLottieExtensionHandler
import com.yandex.div.shimmer.DivShimmerExtensionHandler
import com.yandex.div.zoom.DivPinchToZoomConfiguration
import com.yandex.div.zoom.DivPinchToZoomExtensionHandler
import com.yandex.div2.DivAction
import com.yandex.div2.DivPatch
import com.yandex.divkit.demo.Container
import com.yandex.divkit.demo.R
@@ -343,14 +343,14 @@ class Div2ScenarioActivity : AppCompatActivity(), Div2MetadataBottomSheet.Metada
uriHandler: DivkitDemoUriHandler
) : DemoDivActionHandler(uriHandler) {
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val url = info.url ?: return false
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
val url = action.url?.evaluate(view.expressionResolver) ?: return false
if (url.scheme == "div-demo-action" && url.host == "set_data") {
val assetName = url.getQueryParameter("path")
editorPresenter.readAsset("asset:///regression_test_data/$assetName")
return true
}
return super.handleAction(info, view)
return super.handleAction(action, view)
}
}
@@ -8,7 +8,6 @@ import com.yandex.div.core.Div2Context
import com.yandex.div.core.DivActionHandler
import com.yandex.div.core.DivConfiguration
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.experiments.Experiment
import com.yandex.div.data.DivParsingEnvironment
import com.yandex.div.font.YandexSansDisplayDivTypefaceProvider
@@ -23,6 +22,7 @@ import com.yandex.div.json.templates.InMemoryTemplateProvider
import com.yandex.div.json.templates.TemplateProvider
import com.yandex.div.sizeprovider.DivSizeProviderExtensionHandler
import com.yandex.div.video.ExoDivPlayerFactory
import com.yandex.div2.DivAction
import com.yandex.div2.DivData
import com.yandex.div2.DivPatch
import com.yandex.divkit.demo.Container
@@ -101,9 +101,9 @@ open class DemoDivActionHandler(private val uriHandlerDivkit: DivkitDemoUriHandl
return uriHandlerDivkit.handleUri(uri)
}
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val url = info.url
return super.handleAction(info, view) || url != null && handleUri(url, view)
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
return super.handleAction(action, view) || action.url != null &&
handleUri(action.url!!.evaluate(view.expressionResolver), view)
}
private companion object {
@@ -3,8 +3,8 @@ package com.yandex.divkit.demo.regression
import android.net.Uri
import com.yandex.div.DivDataTag
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div.core.view2.Div2View
import com.yandex.div2.DivAction
import com.yandex.div2.DivData
import com.yandex.divkit.demo.div.DemoDivActionHandler
import com.yandex.divkit.demo.div.parseToDiv2
@@ -20,13 +20,13 @@ class RegressionDivActionHandler(
uriHandlerDivkit: DivkitDemoUriHandler,
private val divAssetReader: DivAssetReader
) : DemoDivActionHandler(uriHandlerDivkit) {
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val url = info.url ?: return false
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
val url = action.url?.evaluate(view.expressionResolver) ?: return false
if (url.scheme == DIV_DEMO_ACTION_SCHEME) {
handleDemoActionUrl(url, view)
return true
}
return super.handleAction(info, view)
return super.handleAction(action, view)
}
private fun handleDemoActionUrl(url: Uri, view: DivViewFacade) {
@@ -11,7 +11,6 @@ import com.yandex.div.core.experiments.Experiment
import com.yandex.div.core.view2.Div2View
import com.yandex.div.json.expressions.Expression
import com.yandex.div2.DivAction
import com.yandex.div2.DivActionDefault
import com.yandex.divkit.demo.BuildConfig
import com.yandex.divkit.demo.Container
import com.yandex.divkit.demo.R
@@ -106,11 +105,9 @@ class SettingsActivity : AppCompatActivity() {
val state = if (value) "active" else "inactive"
val url = "$ACTION_SET_SWITCHER_STATE$name/$state"
div2View.handleActionWithResult(
DivAction.Default(
DivActionDefault(
logId = "init preferences",
url = Expression.constant(Uri.parse(url))
)
DivAction(
logId = "init preferences",
url = Expression.constant(Uri.parse(url))
)
)
}
@@ -6,7 +6,6 @@ import android.content.Intent
import android.net.Uri
import androidx.core.content.ContextCompat.startActivity
import com.yandex.div.core.DivViewFacade
import com.yandex.div.core.action.DivActionInfo
import com.yandex.div2.DivAction
import com.yandex.divkit.demo.div.DemoDivActionHandler
import com.yandex.divkit.demo.div.Div2Activity
@@ -32,10 +31,11 @@ class UIDiv2ActionHandler(
private val context: Context
) : DemoDivActionHandler(uriHandler) {
override fun handleAction(info: DivActionInfo, view: DivViewFacade): Boolean {
val uri = info.url ?: return false
override fun handleAction(action: DivAction, view: DivViewFacade): Boolean {
if (action.url == null) return false
val uri = action.url!!.evaluate(view.expressionResolver)
return (handleActivityActionUrl(uri) || SettingsActionHandler.handleActionUrl(uri)
|| super.handleAction(info, view))
|| super.handleAction(action, view))
}
private fun handleActivityActionUrl(uri: Uri): Boolean {
-76
View File
@@ -1,76 +0,0 @@
{
"definitions": {
"menu_item": {
"type": "object",
"properties": {
"text": {
"$ref": "common.json#/non_empty_string",
"$description": "translations.json#/div_action_menu_item_text"
},
"action": {
"$ref": "div-action.json",
"$description": "translations.json#/div_action_menu_item_action"
},
"actions": {
"type": "array",
"items": {
"$ref": "div-action.json"
},
"minItems": 1,
"$description": "translations.json#/div_action_menu_item_actions"
}
},
"required": [
"text"
]
}
},
"allOf": [
{
"$ref": "div-action-base.json"
},
{
"type": "object",
"$description": "translations.json#/div_action",
"properties": {
"type": {
"type": "string",
"enum": [
"default"
]
},
"menu_items": {
"type": "array",
"items": {
"$ref": "#/definitions/menu_item"
},
"$description": "translations.json#/div_action_menu_items",
"platforms": [
"android",
"ios"
]
},
"log_url": {
"$ref": "common.json#/url",
"$description": "translations.json#/div_action_log_url"
},
"target": {
"type": "string",
"enum": [
"_self",
"_blank"
],
"force_enum_field": true,
"$description": "translations.json#/div_action_target",
"platforms": [
"web"
],
"code_generation_disabled_swift": true
}
},
"required": [
"log_id"
]
}
]
}
+66 -3
View File
@@ -1,7 +1,70 @@
{
"anyOf": [
"definitions": {
"menu_item": {
"type": "object",
"properties": {
"text": {
"$ref": "common.json#/non_empty_string",
"$description": "translations.json#/div_action_menu_item_text"
},
"action": {
"$ref": "div-action.json",
"$description": "translations.json#/div_action_menu_item_action"
},
"actions": {
"type": "array",
"items": {
"$ref": "div-action.json"
},
"minItems": 1,
"$description": "translations.json#/div_action_menu_item_actions"
}
},
"required": [
"text"
]
}
},
"allOf": [
{
"$ref": "div-action-default.json"
"$ref": "div-action-base.json"
},
{
"type": "object",
"$description": "translations.json#/div_action",
"properties": {
"menu_items": {
"type": "array",
"items": {
"$ref": "#/definitions/menu_item"
},
"$description": "translations.json#/div_action_menu_items",
"platforms": [
"android",
"ios"
]
},
"log_url": {
"$ref": "common.json#/url",
"$description": "translations.json#/div_action_log_url"
},
"target": {
"type": "string",
"enum": [
"_self",
"_blank"
],
"force_enum_field": true,
"$description": "translations.json#/div_action_target",
"platforms": [
"web"
],
"code_generation_disabled_swift": true
}
},
"required": [
"log_id"
]
}
]
}
}