Skip to content

Commit

Permalink
Release 25.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
robot-divkit committed May 16, 2023
1 parent a3c2f9f commit 8283519
Show file tree
Hide file tree
Showing 69 changed files with 2,218 additions and 289 deletions.
55 changes: 0 additions & 55 deletions Core/CommonCore/ImageViewBackgroundModel.swift

This file was deleted.

21 changes: 21 additions & 0 deletions DivKit/Actions/DivActionIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum DivActionIntent {
case setNextItem(id: String, overflow: OverflowMode)
case setPreviousItem(id: String, overflow: OverflowMode)
case timer(id: String, action: DivTimerAction)
case video(id: String, action: DivVideoAction)

public static let scheme = "div-action"

Expand Down Expand Up @@ -67,6 +68,11 @@ enum DivActionIntent {
return nil
}
self = .timer(id: id, action: action)
case "video":
guard let id = url.id, let action = url.videoAction else {
return nil
}
self = .video(id: id, action: action)
default:
return nil
}
Expand Down Expand Up @@ -130,6 +136,21 @@ extension URL {
}
}

fileprivate var videoAction: DivVideoAction? {
guard let action = queryParamValue(forName: "action") else {
return nil
}
switch action {
case "start":
return .play
case "pause":
return .pause
default:
DivKitLogger.failure("Unknown action '\(action)' for video.")
return nil
}
}

fileprivate var overflow: OverflowMode {
guard let overflow = queryParamValue(forName: "overflow") else {
return .clamp
Expand Down
6 changes: 6 additions & 0 deletions DivKit/Actions/DivActionURLHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ public final class DivActionURLHandler {
case let .setPreviousItem(id, overflow):
setPreviousItem(id: id, overflow: overflow)
updateCard(.state(cardId))
case let .video(id: id, action: action):
blockStateStorage.setState(
id: id,
state: VideoBlockViewState(state: action == .play ? .playing : .paused)
)
updateCard(.state(cardId))
case let .timer(timerId, action):
performTimerAction(cardId, timerId, action)
}
Expand Down
4 changes: 4 additions & 0 deletions DivKit/Actions/DivVideoAction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum DivVideoAction {
case play
case pause
}
3 changes: 3 additions & 0 deletions DivKit/DivBlockModelingContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public struct DivBlockModelingContext {
public let stateInterceptors: [String: DivStateInterceptor]
public let expressionResolver: ExpressionResolver
public let debugParams: DebugParams
public let playerFactory: PlayerFactory?
public var childrenA11yDescription: String?
public weak var parentScrollView: ScrollView?
public let errorsStorage: DivErrorsStorage
Expand All @@ -47,6 +48,7 @@ public struct DivBlockModelingContext {
extensionHandlers: [DivExtensionHandler] = [],
stateInterceptors: [DivStateInterceptor] = [],
variables: DivVariables = [:],
playerFactory: PlayerFactory? = nil,
debugParams: DebugParams = DebugParams(),
childrenA11yDescription: String? = nil,
parentScrollView: ScrollView? = nil,
Expand All @@ -65,6 +67,7 @@ public struct DivBlockModelingContext {
self.divCustomBlockFactory = divCustomBlockFactory
self.flagsInfo = flagsInfo
self.fontSpecifiers = fontSpecifiers
self.playerFactory = playerFactory
self.debugParams = debugParams
self.childrenA11yDescription = childrenA11yDescription
self.parentScrollView = parentScrollView
Expand Down
20 changes: 2 additions & 18 deletions DivKit/DivFlagsInfo.swift
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
public struct DivFlagsInfo {
public let isTextSelectingEnabled: Bool
public let appendVariablesEnabled: Bool
public let metalImageRenderingEnabled: Bool
public init() {}

public init(
isTextSelectingEnabled: Bool,
appendVariablesEnabled: Bool,
metalImageRenderingEnabled: Bool
) {
self.isTextSelectingEnabled = isTextSelectingEnabled
self.appendVariablesEnabled = appendVariablesEnabled
self.metalImageRenderingEnabled = metalImageRenderingEnabled
}

public static let `default` = DivFlagsInfo(
isTextSelectingEnabled: false,
appendVariablesEnabled: true,
metalImageRenderingEnabled: false
)
public static let `default` = DivFlagsInfo()
}
13 changes: 12 additions & 1 deletion DivKit/DivKitComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public final class DivKitComponents {
public let urlOpener: UrlOpener
public let variablesStorage: DivVariablesStorage
public let visibilityCounter = DivVisibilityCounter()
public let playerFactory: PlayerFactory?
private let timerStorage: DivTimerStorage
private let updateAggregator: RunLoopCardUpdateAggregator
private let disposePool = AutodisposePool()
Expand All @@ -37,6 +38,7 @@ public final class DivKitComponents {
stateManagement: DivStateManagement = DefaultDivStateManagement(),
trackVisibility: @escaping DivActionHandler.TrackVisibility = { _, _ in },
updateCardAction: UpdateCardAction?,
playerFactory: PlayerFactory? = nil,
urlOpener: @escaping UrlOpener,
variablesStorage: DivVariablesStorage = DivVariablesStorage()
) {
Expand All @@ -47,6 +49,7 @@ public final class DivKitComponents {
self.stateManagement = stateManagement
self.urlOpener = urlOpener
self.variablesStorage = variablesStorage
self.playerFactory = playerFactory ?? defaultPlayerFactory

let requestPerformer = requestPerformer ?? URLRequestPerformer(urlTransform: nil)

Expand All @@ -56,7 +59,8 @@ public final class DivKitComponents {
self.patchProvider = patchProvider
?? DivPatchDownloader(requestPerformer: requestPerformer)

let updateAggregator = RunLoopCardUpdateAggregator(updateCardAction: updateCardAction ?? { _ in })
let updateAggregator = RunLoopCardUpdateAggregator(updateCardAction: updateCardAction ?? { _ in
})
self.updateAggregator = updateAggregator
let updateCard: DivActionURLHandler.UpdateCardAction = updateAggregator.aggregate(_:)

Expand Down Expand Up @@ -171,6 +175,7 @@ public final class DivKitComponents {
flagsInfo: flagsInfo,
extensionHandlers: extensionHandlers,
variables: variablesStorage.makeVariables(for: cardId),
playerFactory: playerFactory,
debugParams: debugParams,
parentScrollView: parentScrollView
)
Expand Down Expand Up @@ -212,3 +217,9 @@ func makeImageHolderFactory(requestPerformer: URLRequestPerforming) -> ImageHold
)
)
}

#if os(iOS)
let defaultPlayerFactory: PlayerFactory? = DefaultPlayerFactory()
#else
let defaultPlayerFactory: PlayerFactory? = nil
#endif
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 = "24.3.0"
public static let version = "25.0.0"
}
15 changes: 9 additions & 6 deletions DivKit/Expressions/ExpressionResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,22 +247,25 @@ public final class ExpressionResolver {
initializer: initializer
)
}
}

extension ExpressionResolver: ConstantsProvider {
func getValue(_ name: String) -> Any? {
getVariableValue(name)
}
private lazy var supportedFunctions: [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] =
_supportedFunctions + ValueFunctions.allCases.map { $0.getDeclaration(resolver: self) }.flat()
}

private let supportedFunctions: [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] =
private let _supportedFunctions: [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] =
CastFunctions.allCases.map(\.declaration).flat()
+ StringFunctions.allCases.map(\.declaration).flat()
+ ColorFunctions.allCases.map(\.declaration).flat()
+ DatetimeFunctions.allCases.map(\.declaration).flat()
+ MathFunctions.allCases.map(\.declaration).flat()
+ IntervalFunctions.allCases.map(\.declaration).flat()

extension ExpressionResolver: ConstantsProvider {
func getValue(_ name: String) -> Any? {
getVariableValue(name)
}
}

extension Array where Element == [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] {
fileprivate func flat() -> [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] {
reduce([:], +)
Expand Down
117 changes: 117 additions & 0 deletions DivKit/Expressions/Functions/ValueFunctions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import BaseTinyPublic
import Foundation

fileprivate typealias GetOrDefaultWithTransform<U, T> = (String, U) throws -> T
fileprivate typealias GetOrDefault<T> = GetOrDefaultWithTransform<T, T>

enum ValueFunctions: String, CaseIterable {
case getIntegerValue
case getNumberValue
case getStringValue
case getUrlValue
case getColorValue
case getBooleanValue

func getDeclaration(resolver: ExpressionResolver)
-> [AnyCalcExpression.Symbol: AnyCalcExpression.SymbolEvaluator] {
[
.function(
rawValue,
arity: getFunction(resolver: resolver).arity
): getFunction(resolver: resolver)
.symbolEvaluator,
]
}

func getFunction(resolver: ExpressionResolver) -> Function {
switch self {
case .getIntegerValue:
let function: GetOrDefault<Int> = resolver.getValueFunction()
return FunctionBinary(impl: function)
case .getNumberValue:
let function: GetOrDefault<Double> = resolver.getValueFunction()
return FunctionBinary(impl: function)
case .getStringValue:
let function: GetOrDefault<String> = resolver.getValueFunction()
return FunctionBinary(impl: function)
case .getUrlValue:
let fromUrlFunction: GetOrDefault<URL> = resolver.getValueFunction()
let fromStringFunction: GetOrDefaultWithTransform<String, URL> = resolver
.getValueFunctionWithTransform {
guard let url = URL(string: $0) else {
throw AnyCalcExpression.Error.toURL($0)
}
return url
}
return OverloadedFunction(functions: [
FunctionBinary(impl: fromUrlFunction),
FunctionBinary(impl: fromStringFunction),
])
case .getColorValue:
let fromColorFunction: GetOrDefault<Color> = resolver.getValueFunction()
let fromStringFunction: GetOrDefaultWithTransform<String, Color> = resolver
.getValueFunctionWithTransform {
guard let color = Color.color(withHexString: $0) else {
throw AnyCalcExpression.Error.toColor($0)
}
return color
}
return OverloadedFunction(functions: [
FunctionBinary(impl: fromColorFunction),
FunctionBinary(impl: fromStringFunction),
])
case .getBooleanValue:
let function: GetOrDefault<Bool> = resolver.getValueFunction()
return FunctionBinary(impl: function)
}
}
}

extension ExpressionResolver {
fileprivate func getValueFunction<T>() -> GetOrDefault<T> {
{ name, fallbackValue in
guard let value = self.getValue(name) else {
return fallbackValue
}
let typpedValue: T? = value as? T
if typpedValue == nil {
DivKitLogger.warning("The type of the variable \(name) is not \(T.self)")
}
return typpedValue ?? fallbackValue
}
}

fileprivate func getValueFunctionWithTransform<
T,
U
>(transform: @escaping (U) throws -> T) -> GetOrDefaultWithTransform<U, T> {
{ name, fallbackValue in
guard let value = self.getValue(name) else {
return try transform(fallbackValue)
}
let typpedValue: T? = value as? T
if typpedValue == nil {
DivKitLogger.warning("The type of the variable \(name) is not \(T.self)")
}
return try typpedValue ?? transform(fallbackValue)
}
}
}

extension AnyCalcExpression.Error {
fileprivate static func toColor(_ value: Any?) -> AnyCalcExpression.Error {
.message(
"Failed to get Color from (\(formatValue(value))). Unable to convert value to Color."
)
}

fileprivate static func toURL(_ value: Any?) -> AnyCalcExpression.Error {
.message(
"Failed to get URL from (\(formatValue(value))). Unable to convert value to URL."
)
}

private static func formatValue(_ value: Any?) -> String {
(value as? CustomStringConvertible)?.description ?? ""
}
}
6 changes: 2 additions & 4 deletions DivKit/Extensions/DivBackgroundExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import NetworkingPublic
extension DivBackground {
func makeBlockBackground(
with imageHolderFactory: ImageHolderFactory,
expressionResolver: ExpressionResolver,
metalImageRenderingEnabled: Bool
expressionResolver: ExpressionResolver
) -> LayoutKit.Background? {
switch self {
case let .divLinearGradient(gradient):
Expand All @@ -32,8 +31,7 @@ extension DivBackground {
),
contentMode: imageBackground.resolveContentMode(expressionResolver),
alpha: imageBackground.resolveAlpha(expressionResolver),
effects: imageBackground.makeEffects(with: expressionResolver),
metalImageRenderingEnabled: metalImageRenderingEnabled
effects: imageBackground.makeEffects(with: expressionResolver)
)
return .image(image)
case let .divSolidBackground(solidBackground):
Expand Down
Loading

0 comments on commit 8283519

Please sign in to comment.