Skip to content

Commit

Permalink
Release 28.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
robot-divkit committed Sep 25, 2023
1 parent 09b9a55 commit 0144edd
Show file tree
Hide file tree
Showing 75 changed files with 3,845 additions and 190 deletions.
50 changes: 49 additions & 1 deletion .mapping.json

Large diffs are not rendered by default.

120 changes: 86 additions & 34 deletions DivKit/Actions/DivActionHandler.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

import BasePublic
import LayoutKit
import Serialization
Expand All @@ -14,6 +12,9 @@ public final class DivActionHandler {
private let trackDisappear: TrackVisibility
private let variablesStorage: DivVariablesStorage
private let persistentValuesStorage: DivPersistentValuesStorage
private let reporter: DivReporter

private let setVariableActionHandler: SetVariableActionHandler

init(
divActionURLHandler: DivActionURLHandler,
Expand All @@ -22,7 +23,8 @@ public final class DivActionHandler {
trackVisibility: @escaping TrackVisibility,
trackDisappear: @escaping TrackVisibility,
variablesStorage: DivVariablesStorage,
persistentValuesStorage: DivPersistentValuesStorage
persistentValuesStorage: DivPersistentValuesStorage,
reporter: DivReporter
) {
self.divActionURLHandler = divActionURLHandler
self.urlHandler = urlHandler
Expand All @@ -31,6 +33,11 @@ public final class DivActionHandler {
self.trackDisappear = trackDisappear
self.variablesStorage = variablesStorage
self.persistentValuesStorage = persistentValuesStorage
self.reporter = reporter

setVariableActionHandler = SetVariableActionHandler(
variableStorage: variablesStorage
)
}

public convenience init(
Expand All @@ -46,7 +53,8 @@ public final class DivActionHandler {
trackDisappear: @escaping TrackVisibility = { _, _ in },
performTimerAction: @escaping DivActionURLHandler.PerformTimerAction = { _, _, _ in },
urlHandler: DivUrlHandler,
persistentValuesStorage: DivPersistentValuesStorage = DivPersistentValuesStorage()
persistentValuesStorage: DivPersistentValuesStorage = DivPersistentValuesStorage(),
reporter: DivReporter? = nil
) {
self.init(
divActionURLHandler: DivActionURLHandler(
Expand All @@ -65,7 +73,8 @@ public final class DivActionHandler {
trackVisibility: trackVisibility,
trackDisappear: trackDisappear,
variablesStorage: variablesStorage,
persistentValuesStorage: persistentValuesStorage
persistentValuesStorage: persistentValuesStorage,
reporter: reporter ?? DefaultDivReporter()
)
}

Expand Down Expand Up @@ -100,49 +109,92 @@ public final class DivActionHandler {
source: UserInterfaceAction.DivActionSource,
sender: AnyObject?
) {
let variables = variablesStorage.makeVariables(for: cardId)
let expressionResolver = ExpressionResolver(variables: variables, persistentValuesStorage: persistentValuesStorage)
if let url = action.resolveUrl(expressionResolver) {
let isDivActionURLHandled = divActionURLHandler.handleURL(
url,
cardId: cardId,
completion: { [unowned self] result in
let callbackActions: [DivAction]
switch result {
case .success:
callbackActions = action.downloadCallbacks?.onSuccessActions ?? []
case .failure:
callbackActions = action.downloadCallbacks?.onFailActions ?? []
}
callbackActions.forEach {
self.handle($0, cardId: cardId, source: source, sender: sender)
}
}
)
if !isDivActionURLHandled {
switch source {
case .tap, .custom:
urlHandler.handle(url, sender: sender)
case .visibility, .disappear:
// For visibility actions url is treated as logUrl.
let referer = action.resolveReferer(expressionResolver)
logger.log(url: url, referer: referer, payload: action.payload)
}
}
let expressionResolver = makeExpressionResolver(cardId: cardId)
let context = DivActionHandlingContext(
cardId: cardId,
expressionResolver: expressionResolver
)

var isHandled = true
switch action.typed {
case let .divActionSetVariable(action):
setVariableActionHandler.handle(action, context: context)
case .none:
isHandled = false
default:
DivKitLogger.error("Action not supported")
isHandled = false
}

if !isHandled {
handleUrl(action, context: context, source: source, sender: sender)
}

if let logUrl = action.resolveLogUrl(expressionResolver) {
let referer = action.resolveReferer(expressionResolver)
logger.log(url: logUrl, referer: referer, payload: action.payload)
}

reporter.reportAction(cardId: cardId, info: DivActionInfo(logId: action.logId, source: source))

if source == .visibility {
trackVisibility(action.logId, cardId)
} else if source == .disappear {
trackDisappear(action.logId, cardId)
}
}

private func handleUrl(
_ action: DivActionBase,
context: DivActionHandlingContext,
source: UserInterfaceAction.DivActionSource,
sender: AnyObject?
) {
let expressionResolver = context.expressionResolver
guard let url = action.resolveUrl(expressionResolver) else {
return
}

let isDivActionURLHandled = divActionURLHandler.handleURL(
url,
cardId: context.cardId,
completion: { [weak self] result in
guard let self = self else {
return
}
let callbackActions: [DivAction]
switch result {
case .success:
callbackActions = action.downloadCallbacks?.onSuccessActions ?? []
case .failure:
callbackActions = action.downloadCallbacks?.onFailActions ?? []
}
callbackActions.forEach {
self.handle($0, cardId: context.cardId, source: source, sender: sender)
}
}
)

if !isDivActionURLHandled {
switch source {
case .tap, .custom:
urlHandler.handle(url, sender: sender)
case .visibility, .disappear:
// For visibility actions url is treated as logUrl.
let referer = action.resolveReferer(expressionResolver)
logger.log(url: url, referer: referer, payload: action.payload)
}
}
}

private func makeExpressionResolver(cardId: DivCardID) -> ExpressionResolver {
ExpressionResolver(
variables: variablesStorage.makeVariables(for: cardId),
persistentValuesStorage: persistentValuesStorage,
errorTracker: reporter.asExpressionErrorTracker(cardId: cardId)
)
}

private func parseAction<T: TemplateValue>(
type _: T.Type,
json: JSONObject
Expand Down
4 changes: 4 additions & 0 deletions DivKit/Actions/DivActionHandlingContext.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct DivActionHandlingContext {
let cardId: DivCardID
let expressionResolver: ExpressionResolver
}
76 changes: 76 additions & 0 deletions DivKit/Actions/SetVariableActionHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Foundation

final class SetVariableActionHandler {
private let variableStorage: DivVariablesStorage

init(variableStorage: DivVariablesStorage) {
self.variableStorage = variableStorage
}

func handle(_ action: DivActionSetVariable, context: DivActionHandlingContext) {
let expressionResolver = context.expressionResolver
guard let variableName = action.resolveVariableName(expressionResolver) else {
return
}

guard let variableValue = action.value.asVariableValue(expressionResolver: expressionResolver) else {
return
}

variableStorage.update(
cardId: context.cardId,
name: DivVariableName(rawValue: variableName),
value: variableValue
)
}
}


extension DivTypedValue {
fileprivate func asVariableValue(
expressionResolver: ExpressionResolver
) -> DivVariableValue? {
switch self {
case let .arrayValue(value):
if let arrayValue = value.value as? [AnyHashable] {
return .array(arrayValue)
}
return nil
case let .booleanValue(value):
if let boolValue = value.resolveValue(expressionResolver) {
return .bool(boolValue)
}
return nil
case let .colorValue(value):
if let colorValue = value.resolveValue(expressionResolver) {
return .color(colorValue)
}
return nil
case let .dictValue(value):
if let dictValue = value.value as? [String: AnyHashable] {
return .dict(dictValue)
}
return nil
case let .integerValue(value):
if let integerValue = value.resolveValue(expressionResolver) {
return .integer(integerValue)
}
return nil
case let .numberValue(value):
if let numberValue = value.resolveValue(expressionResolver) {
return .number(numberValue)
}
return nil
case let .stringValue(value):
if let stringValue = value.resolveValue(expressionResolver) {
return .string(stringValue)
}
return nil
case let .urlValue(value):
if let urlValue = value.resolveValue(expressionResolver) {
return .url(urlValue)
}
return nil
}
}
}
3 changes: 0 additions & 3 deletions DivKit/Debug/DebugParams.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ public struct DebugParams {
}

public let isDebugInfoEnabled: Bool
public let processErrors: ResultAction<(cardId: DivCardID, errors: [DivError])>
public let processMeasurements: ResultAction<(cardId: DivCardID, measurements: Measurements)>
public let showDebugInfo: (ViewType) -> Void
public let errorCounterInsets: EdgeInsets

public init(
isDebugInfoEnabled: Bool = false,
processDivKitError: @escaping ResultAction<(cardId: DivCardID, errors: [DivError])> = { _ in },
processMeasurements: @escaping ResultAction<(cardId: DivCardID, measurements: Measurements)> =
{ _ in },
showDebugInfo: @escaping (ViewType) -> Void = DebugParams.showDebugInfo(_:),
Expand All @@ -42,7 +40,6 @@ public struct DebugParams {
self.showDebugInfo = showDebugInfo
self.errorCounterInsets = errorCounterInsets
self.processMeasurements = processMeasurements
self.processErrors = processDivKitError
}
}

Expand Down
1 change: 0 additions & 1 deletion DivKit/DivError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ extension DivError {
extension DivError {
public var prettyMessage: String {
return "\(message)" +
"\nKind: \(kind)" +
"\nLevel: \(level)" +
"\nPath: \(path)" +
(
Expand Down
23 changes: 18 additions & 5 deletions DivKit/DivKitComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public final class DivKitComponents {
public let layoutDirection: UserInterfaceLayoutDirection
public let patchProvider: DivPatchProvider
public let playerFactory: PlayerFactory?
public let reporter: DivReporter
public let safeAreaManager: DivSafeAreaManager
public let stateManagement: DivStateManagement
public let showToolip: DivActionURLHandler.ShowTooltipAction?
Expand Down Expand Up @@ -68,13 +69,17 @@ public final class DivKitComponents {
/// patches.
/// - requestPerformer: An optional `URLRequestPerforming` object that performs URL requests for
/// data retrieval.
/// - reporter: An optional `DivReporter` object that allows you to learn about actions and
/// errors that occur in the layout.
/// - showTooltip: Deprecated. This parameter is deprecated, use ``tooltipManager`` instead.
/// - stateManagement: An optional ``DivStateManagement`` object responsible for managing card
/// states.
/// - tooltipManager: An optional `TooltipManager` object that manages the processing and
/// display of tooltips.
/// - trackVisibility: A closure that tracks the visibility of elements.
/// - trackDisappear: A closure that tracks the disappearance of elements.
/// - trackVisibility: A closure that tracks the visibility of elements. Deprecated. Use
/// ``reporter`` instead.
/// - trackDisappear: A closure that tracks the disappearance of elements. Deprecated. Use
/// ``reporter`` instead.
/// - updateCardAction: Deprecated. This parameter is deprecated, use ``updateCardSignal``
/// instead.
/// - playerFactory: An optional `PlayerFactory` object responsible for creating custom video
Expand All @@ -93,11 +98,14 @@ public final class DivKitComponents {
layoutDirection: UserInterfaceLayoutDirection = .leftToRight,
patchProvider: DivPatchProvider? = nil,
requestPerformer: URLRequestPerforming? = nil,
reporter: DivReporter? = nil,
showTooltip: DivActionURLHandler.ShowTooltipAction? = nil,
stateManagement: DivStateManagement = DefaultDivStateManagement(),
tooltipManager: TooltipManager? = nil,
trackVisibility: @escaping DivActionHandler.TrackVisibility = { _, _ in },
// remove in next major release
trackDisappear: @escaping DivActionHandler.TrackVisibility = { _, _ in },
// remove in next major release
updateCardAction: UpdateCardAction? = nil, // remove in next major release
playerFactory: PlayerFactory? = nil,
urlHandler: DivUrlHandler? = nil,
Expand All @@ -110,6 +118,8 @@ public final class DivKitComponents {
self.fontProvider = fontProvider ?? DefaultFontProvider()
self.layoutDirection = layoutDirection
self.playerFactory = playerFactory ?? defaultPlayerFactory
let reporter = reporter ?? DefaultDivReporter()
self.reporter = reporter
self.showToolip = showTooltip
self.stateManagement = stateManagement
let urlHandler = urlHandler ?? DivUrlHandlerDelegate(urlOpener)
Expand Down Expand Up @@ -171,20 +181,23 @@ public final class DivKitComponents {
trackDisappear: trackDisappear,
performTimerAction: { weakTimerStorage?.perform($0, $1, $2) },
urlHandler: urlHandler,
persistentValuesStorage: persistentValuesStorage
persistentValuesStorage: persistentValuesStorage,
reporter: reporter
)

triggersStorage = DivTriggersStorage(
variablesStorage: variablesStorage,
actionHandler: actionHandler,
persistentValuesStorage: persistentValuesStorage
persistentValuesStorage: persistentValuesStorage,
reporter: reporter
)

timerStorage = DivTimerStorage(
variablesStorage: variablesStorage,
actionHandler: actionHandler,
updateCard: updateCard,
persistentValuesStorage: persistentValuesStorage
persistentValuesStorage: persistentValuesStorage,
reporter: reporter
)

weakActionHandler = actionHandler
Expand Down
2 changes: 1 addition & 1 deletion DivKit/DivKitInfo.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
public enum DivKitInfo {
public static let version = "28.2.0"
public static let version = "28.3.0"
}
Loading

0 comments on commit 0144edd

Please sign in to comment.