added divview implementation for tooltips

This commit is contained in:
yaanvar
2023-08-18 14:51:57 +03:00
parent 80422bfa32
commit d06a747849
8 changed files with 120 additions and 58 deletions
+2
View File
@@ -8722,6 +8722,7 @@
"client/ios/DivKit/Extensions/DivInputExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivInputExtensions.swift",
"client/ios/DivKit/Extensions/DivPagerExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivPagerExtensions.swift",
"client/ios/DivKit/Extensions/DivPivotExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivPivotExtensions.swift",
"client/ios/DivKit/Extensions/DivPointExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivPointExtensions.swift",
"client/ios/DivKit/Extensions/DivSelectExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSelectExtensions.swift",
"client/ios/DivKit/Extensions/DivSeparatorExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSeparatorExtensions.swift",
"client/ios/DivKit/Extensions/DivSizeExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSizeExtensions.swift",
@@ -8730,6 +8731,7 @@
"client/ios/DivKit/Extensions/DivStateExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivStateExtensions.swift",
"client/ios/DivKit/Extensions/DivTabsExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTabsExtensions.swift",
"client/ios/DivKit/Extensions/DivTextExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTextExtensions.swift",
"client/ios/DivKit/Extensions/DivTooltipExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTooltipExtensions.swift",
"client/ios/DivKit/Extensions/DivTransformExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTransformExtensions.swift",
"client/ios/DivKit/Extensions/DivVideoExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivVideoExtensions.swift",
"client/ios/DivKit/Extensions/DivVisibilityActionExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivVisibilityActionExtensions.swift",
@@ -2,6 +2,7 @@ import CoreGraphics
import BasePublic
import BaseUIPublic
import CommonCorePublic
import LayoutKit
import NetworkingPublic
import Serialization
@@ -38,6 +39,7 @@ public struct DivBlockModelingContext {
public let errorsStorage: DivErrorsStorage
internal let variableTracker: DivVariableTracker?
private let persistentValuesStorage: DivPersistentValuesStorage
public let tooltipViewFactory: DivTooltipViewFactory?
var overridenWidth: DivOverridenSize?
var overridenHeight: DivOverridenSize?
@@ -80,7 +82,8 @@ public struct DivBlockModelingContext {
errorsStorage: DivErrorsStorage = DivErrorsStorage(errors: []),
layoutDirection: UserInterfaceLayoutDirection = .leftToRight,
variableTracker: DivVariableTracker? = nil,
persistentValuesStorage: DivPersistentValuesStorage = DivPersistentValuesStorage()
persistentValuesStorage: DivPersistentValuesStorage = DivPersistentValuesStorage(),
tooltipViewFactory: DivTooltipViewFactory? = nil
) {
self.cardId = cardId
self.cardLogId = cardLogId
@@ -105,6 +108,7 @@ public struct DivBlockModelingContext {
self.layoutDirection = layoutDirection
self.variableTracker = variableTracker
self.persistentValuesStorage = persistentValuesStorage
self.tooltipViewFactory = tooltipViewFactory
var extensionsHandlersDictionary = [String: DivExtensionHandler]()
extensionHandlers.forEach {
+2 -1
View File
@@ -278,7 +278,8 @@ public final class DivKitComponents {
parentScrollView: parentScrollView,
layoutDirection: layoutDirection,
variableTracker: variableTracker,
persistentValuesStorage: persistentValuesStorage
persistentValuesStorage: persistentValuesStorage,
tooltipViewFactory: makeTooltipViewFactory(divKitComponents: self, cardId: cardId)
)
}
@@ -84,7 +84,7 @@ extension DivBase {
}
),
scheduler: context.scheduler,
tooltips: try makeTooltips(context: context)
tooltips: try tooltips.makeTooltips(context: context)
)
.addingTransform(
transform: transform.resolveRotation(expressionResolver)
@@ -178,15 +178,6 @@ extension DivBase {
return nil
}
private func makeTooltips(context: DivBlockModelingContext) throws -> [BlockTooltip] {
try tooltips?.iterativeFlatMap { div, index in
let tooltipContext = modified(context) {
$0.parentPath = $0.parentPath + "tooltip" + index
}
return try div.makeTooltip(context: tooltipContext)
} ?? []
}
private func applyTransitioningAnimations(
to block: Block,
context: DivBlockModelingContext,
@@ -368,46 +359,3 @@ extension DivBorder {
)
}
}
extension DivTooltip {
fileprivate func makeTooltip(context: DivBlockModelingContext) throws
-> BlockTooltip? {
let expressionResolver = context.expressionResolver
guard let position = resolvePosition(expressionResolver)?.cast() else {
return nil
}
let block = try div.value.makeBlock(context: context)
return BlockTooltip(
id: id,
block: block,
duration: Duration(milliseconds: resolveDuration(expressionResolver)),
offset: offset?.cast(with: expressionResolver) ?? .zero,
position: position
)
}
}
extension DivTooltip.Position {
fileprivate func cast() -> BlockTooltip.Position {
switch self {
case .left: return .left
case .topLeft: return .topLeft
case .top: return .top
case .topRight: return .topRight
case .right: return .right
case .bottomRight: return .bottomRight
case .bottom: return .bottom
case .bottomLeft: return .bottomLeft
case .center: return .center
}
}
}
extension DivPoint {
fileprivate func cast(with expressionResolver: ExpressionResolver) -> CGPoint {
CGPoint(
x: x.resolveUnit(expressionResolver).makeScaledValue(x.resolveValue(expressionResolver) ?? 0),
y: y.resolveUnit(expressionResolver).makeScaledValue(y.resolveValue(expressionResolver) ?? 0)
)
}
}
@@ -0,0 +1,10 @@
import Foundation
extension DivPoint {
internal func cast(with expressionResolver: ExpressionResolver) -> CGPoint {
CGPoint(
x: x.resolveUnit(expressionResolver).makeScaledValue(x.resolveValue(expressionResolver) ?? 0),
y: y.resolveUnit(expressionResolver).makeScaledValue(y.resolveValue(expressionResolver) ?? 0)
)
}
}
@@ -0,0 +1,85 @@
import BasePublic
import CommonCorePublic
import Foundation
import LayoutKit
#if os(iOS)
public typealias DivTooltipViewFactory = (Div) -> VisibleBoundsTrackingView
#else
public typealias DivTooltipViewFactory = (Div) -> ViewType
#endif
extension DivTooltip {
fileprivate func makeTooltip(context: DivBlockModelingContext) throws
-> BlockTooltip? {
let expressionResolver = context.expressionResolver
guard let position = resolvePosition(expressionResolver)?.cast() else {
return nil
}
let block = try div.value.makeBlock(context: context)
let tooltipViewFactory: TooltipViewFactory =
Variable { [tooltipViewFactory = context.tooltipViewFactory, div = self.div] in
guard let tooltipViewFactory = tooltipViewFactory else { return nil }
return tooltipViewFactory(div)
}
return BlockTooltip(
id: id,
block: block,
duration: Duration(milliseconds: resolveDuration(expressionResolver)),
offset: offset?.cast(with: expressionResolver) ?? .zero,
position: position,
tooltipViewFactory: tooltipViewFactory
)
}
}
extension DivTooltip.Position {
fileprivate func cast() -> BlockTooltip.Position {
switch self {
case .left: return .left
case .topLeft: return .topLeft
case .top: return .top
case .topRight: return .topRight
case .right: return .right
case .bottomRight: return .bottomRight
case .bottom: return .bottom
case .bottomLeft: return .bottomLeft
case .center: return .center
}
}
}
extension Optional where Wrapped == [DivTooltip] {
func makeTooltips(
context: DivBlockModelingContext
) throws -> [BlockTooltip] {
try self?.iterativeFlatMap { div, index in
let tooltipContext = modified(context) {
$0.parentPath = $0.parentPath + "tooltip" + index
}
return try div.makeTooltip(context: tooltipContext)
} ?? []
}
}
public func makeTooltipViewFactory(
divKitComponents: DivKitComponents,
cardId: DivCardID
) -> DivTooltipViewFactory {
{ (div: Div) in
let view = DivView(divKitComponents: divKitComponents)
let divData = DivData(
logId: cardId.rawValue,
states: [.init(div: div, stateId: 0)],
timers: nil,
transitionAnimationSelector: nil,
variableTriggers: nil,
variables: nil
)
view.setSource(.init(kind: .divData(divData), cardId: cardId))
return view
}
}
@@ -1,6 +1,11 @@
import CommonCorePublic
import CoreGraphics
import CommonCorePublic
#if os(iOS)
public typealias TooltipViewFactory = Variable<VisibleBoundsTrackingView?>
#else
public typealias TooltipViewFactory = Variable<ViewType?>
#endif
public struct BlockTooltip: Equatable {
public enum Position: String, CaseIterable {
@@ -20,19 +25,22 @@ public struct BlockTooltip: Equatable {
public let duration: Duration
public let offset: CGPoint
public let position: Position
public let tooltipViewFactory: TooltipViewFactory?
public init(
id: String,
block: Block,
duration: Duration,
offset: CGPoint,
position: BlockTooltip.Position
position: BlockTooltip.Position,
tooltipViewFactory: TooltipViewFactory? = nil
) {
self.id = id
self.block = block
self.duration = duration
self.offset = offset
self.position = position
self.tooltipViewFactory = tooltipViewFactory
}
public static func ==(lhs: BlockTooltip, rhs: BlockTooltip) -> Bool {
@@ -129,7 +129,11 @@ extension TooltipAnchorView {
id: tooltip.id,
duration: tooltip.duration,
view: {
let tooltipView = tooltip.block.makeBlockView()
var tooltipView: VisibleBoundsTrackingView = tooltip.block.makeBlockView()
if let tooltipViewFactory = tooltip.tooltipViewFactory,
let view = tooltipViewFactory.value {
tooltipView = view
}
let frame = tooltip.calculateFrame(targeting: bounds)
tooltipView.frame = convert(frame, to: nil)
return tooltipView