mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add light context menu theme
This commit is contained in:
parent
d7546f6751
commit
5452f275b4
@ -458,7 +458,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
self.highlightBackgroundNode.clipsToBounds = true
|
||||
self.highlightBackgroundNode.cornerRadius = 14.0
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: presentationData.theme.contextMenu.primaryColor.withAlphaComponent(0.15), knob: presentationData.theme.contextMenu.primaryColor, knobDiameter: 8.0), strings: presentationData.strings, textNode: self.textNode.textNode, updateIsActive: { _ in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: presentationData.theme.contextMenu.primaryColor.withAlphaComponent(0.15), knob: presentationData.theme.contextMenu.primaryColor, knobDiameter: 8.0, isDark: presentationData.theme.overallDarkAppearance), strings: presentationData.strings, textNode: self.textNode.textNode, updateIsActive: { _ in
|
||||
}, present: { _, _ in
|
||||
}, rootNode: { [weak self] in
|
||||
return self
|
||||
|
@ -17,22 +17,32 @@ private final class ContextMenuContainerMaskView: UIView {
|
||||
public final class ContextMenuContainerNode: ASDisplayNode {
|
||||
private var cachedMaskParams: CachedMaskParams?
|
||||
private let maskView = ContextMenuContainerMaskView()
|
||||
public let containerNode: ASDisplayNode
|
||||
|
||||
public var relativeArrowPosition: (CGFloat, Bool)?
|
||||
|
||||
private var effectView: UIVisualEffectView?
|
||||
|
||||
public init(blurred: Bool) {
|
||||
public init(isBlurred: Bool, isDark: Bool) {
|
||||
self.containerNode = ASDisplayNode()
|
||||
|
||||
super.init()
|
||||
|
||||
if blurred {
|
||||
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
|
||||
self.view.addSubview(effectView)
|
||||
if isBlurred {
|
||||
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: isDark ? .dark : .light))
|
||||
self.containerNode.view.addSubview(effectView)
|
||||
self.effectView = effectView
|
||||
} else {
|
||||
self.backgroundColor = UIColor(rgb: 0x8c8e8e)
|
||||
self.containerNode.backgroundColor = isDark ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0xF8F8F6)
|
||||
}
|
||||
self.view.mask = self.maskView
|
||||
|
||||
self.layer.shadowColor = UIColor.black.cgColor
|
||||
self.layer.shadowRadius = 10.0
|
||||
self.layer.shadowOpacity = 0.2
|
||||
self.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
|
||||
|
||||
self.containerNode.view.mask = self.maskView
|
||||
self.addSubnode(self.containerNode)
|
||||
}
|
||||
|
||||
override public func didLoad() {
|
||||
@ -48,6 +58,8 @@ public final class ContextMenuContainerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
public func updateLayout(transition: ContainedViewLayoutTransition) {
|
||||
transition.updateFrame(node: self.containerNode, frame: self.bounds)
|
||||
|
||||
self.effectView?.frame = self.bounds
|
||||
|
||||
let maskParams = CachedMaskParams(size: self.bounds.size, relativeArrowPosition: self.relativeArrowPosition?.0 ?? self.bounds.size.width / 2.0, arrowOnBottom: self.relativeArrowPosition?.1 ?? true)
|
||||
@ -87,6 +99,13 @@ public final class ContextMenuContainerNode: ASDisplayNode {
|
||||
}
|
||||
layer.path = path.cgPath
|
||||
}
|
||||
|
||||
if case let .animated(duration, curve) = transition, let previousPath = self.layer.shadowPath {
|
||||
self.layer.shadowPath = path.cgPath
|
||||
self.layer.animate(from: previousPath, to: path.cgPath, keyPath: "shadowPath", timingFunction: curve.timingFunction, duration: duration)
|
||||
} else {
|
||||
self.layer.shadowPath = path.cgPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,15 @@ public struct ContextMenuControllerArguments {
|
||||
public var hasHapticFeedback: Bool
|
||||
public var blurred: Bool
|
||||
public var skipCoordnateConversion: Bool
|
||||
public var isDark: Bool
|
||||
|
||||
public init(actions: [ContextMenuAction], catchTapsOutside: Bool, hasHapticFeedback: Bool, blurred: Bool, skipCoordnateConversion: Bool) {
|
||||
public init(actions: [ContextMenuAction], catchTapsOutside: Bool, hasHapticFeedback: Bool, blurred: Bool, skipCoordnateConversion: Bool, isDark: Bool) {
|
||||
self.actions = actions
|
||||
self.catchTapsOutside = catchTapsOutside
|
||||
self.hasHapticFeedback = hasHapticFeedback
|
||||
self.blurred = blurred
|
||||
self.skipCoordnateConversion = skipCoordnateConversion
|
||||
self.isDark = isDark
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +42,7 @@ public func setContextMenuControllerProvider(_ f: @escaping (ContextMenuControll
|
||||
contextMenuControllerProvider = f
|
||||
}
|
||||
|
||||
public func makeContextMenuController(actions: [ContextMenuAction], catchTapsOutside: Bool = false, hasHapticFeedback: Bool = false, blurred: Bool = false, skipCoordnateConversion: Bool = false) -> ContextMenuController {
|
||||
public func makeContextMenuController(actions: [ContextMenuAction], catchTapsOutside: Bool = false, hasHapticFeedback: Bool = false, blurred: Bool = false, isDark: Bool = true, skipCoordnateConversion: Bool = false) -> ContextMenuController {
|
||||
guard let contextMenuControllerProvider = contextMenuControllerProvider else {
|
||||
preconditionFailure()
|
||||
}
|
||||
@ -49,6 +51,7 @@ public func makeContextMenuController(actions: [ContextMenuAction], catchTapsOut
|
||||
catchTapsOutside: catchTapsOutside,
|
||||
hasHapticFeedback: hasHapticFeedback,
|
||||
blurred: blurred,
|
||||
skipCoordnateConversion: skipCoordnateConversion
|
||||
skipCoordnateConversion: skipCoordnateConversion,
|
||||
isDark: isDark
|
||||
))
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
self.dismissByTapOutside = dismissByTapOutside
|
||||
self.dismissByTapOutsideSource = dismissByTapOutsideSource
|
||||
|
||||
self.containerNode = ContextMenuContainerNode(blurred: false)
|
||||
self.containerNode.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
|
||||
self.containerNode = ContextMenuContainerNode(isBlurred: false, isDark: true)
|
||||
self.containerNode.containerNode.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
|
||||
|
||||
self.imageNode = ASImageNode()
|
||||
self.imageNode.image = content.image
|
||||
@ -57,9 +57,9 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.containerNode.addSubnode(self.imageNode)
|
||||
self.containerNode.addSubnode(self.textNode)
|
||||
self.contentNode.flatMap { self.containerNode.addSubnode($0) }
|
||||
self.containerNode.containerNode.addSubnode(self.imageNode)
|
||||
self.containerNode.containerNode.addSubnode(self.textNode)
|
||||
self.contentNode.flatMap { self.containerNode.containerNode.addSubnode($0) }
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
)
|
||||
self.textNode.visibility = true
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: defaultDarkPresentationTheme.list.itemAccentColor.withMultipliedAlpha(0.5), knob: defaultDarkPresentationTheme.list.itemAccentColor), strings: presentationData.strings, textNode: self.textNode, updateIsActive: { [weak self] value in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: defaultDarkPresentationTheme.list.itemAccentColor.withMultipliedAlpha(0.5), knob: defaultDarkPresentationTheme.list.itemAccentColor, isDark: true), strings: presentationData.strings, textNode: self.textNode, updateIsActive: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0)
|
||||
|
||||
self.tooltipContainerNode = ContextMenuContainerNode(blurred: false)
|
||||
self.tooltipContainerNode.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
|
||||
self.tooltipContainerNode = ContextMenuContainerNode(isBlurred: false, isDark: true)
|
||||
self.tooltipContainerNode.containerNode.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
@ -119,7 +119,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
|
||||
self.tooltipContainerNode.addSubnode(self.textNode)
|
||||
self.tooltipContainerNode.containerNode.addSubnode(self.textNode)
|
||||
|
||||
self.addSubnode(self.tooltipContainerNode)
|
||||
}
|
||||
|
@ -3486,23 +3486,28 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
})
|
||||
strongSelf.setAnimationForKey("contentNode\(contentNodeIndex)Frame", animation: animation)
|
||||
} else {
|
||||
if let animateTextAndWebpagePositionSwap, let contentNode = contentNode as? ChatMessageTextBubbleContentNode, let snapshotLayer = contentNode.layer.snapshotContentTree() {
|
||||
let clippingLayer = SimpleLayer()
|
||||
clippingLayer.masksToBounds = true
|
||||
clippingLayer.frame = contentNode.frame
|
||||
var useExpensiveSnapshot = false
|
||||
if case .messageOptions = item.associatedData.subject {
|
||||
useExpensiveSnapshot = true
|
||||
}
|
||||
|
||||
if let animateTextAndWebpagePositionSwap, let contentNode = contentNode as? ChatMessageTextBubbleContentNode, let snapshotView = useExpensiveSnapshot ? contentNode.view.snapshotView(afterScreenUpdates: false) : contentNode.layer.snapshotContentTreeAsView() {
|
||||
let clippingView = UIView()
|
||||
clippingView.clipsToBounds = true
|
||||
clippingView.frame = contentNode.frame
|
||||
|
||||
clippingLayer.addSublayer(snapshotLayer)
|
||||
snapshotLayer.frame = CGRect(origin: CGPoint(), size: contentNode.bounds.size)
|
||||
clippingView.addSubview(snapshotView)
|
||||
snapshotView.frame = CGRect(origin: CGPoint(), size: contentNode.bounds.size)
|
||||
|
||||
contentNode.layer.superlayer?.insertSublayer(clippingLayer, below: contentNode.layer)
|
||||
contentNode.view.superview?.insertSubview(clippingView, belowSubview: contentNode.view)
|
||||
|
||||
animation.animator.updateAlpha(layer: clippingLayer, alpha: 0.0, completion: { [weak clippingLayer] _ in
|
||||
clippingLayer?.removeFromSuperlayer()
|
||||
animation.animator.updateAlpha(layer: clippingView.layer, alpha: 0.0, completion: { [weak clippingView] _ in
|
||||
clippingView?.removeFromSuperview()
|
||||
})
|
||||
|
||||
let positionOffset: CGFloat = animateTextAndWebpagePositionSwap ? -1.0 : 1.0
|
||||
|
||||
animation.animator.updatePosition(layer: snapshotLayer, position: CGPoint(x: snapshotLayer.position.x, y: snapshotLayer.position.y + positionOffset * contentNode.frame.height), completion: nil)
|
||||
animation.animator.updatePosition(layer: snapshotView.layer, position: CGPoint(x: snapshotView.center.x, y: snapshotView.center.y + positionOffset * contentNode.frame.height), completion: nil)
|
||||
|
||||
contentNode.frame = contentNodeFrame
|
||||
|
||||
|
@ -1796,7 +1796,7 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
knobColor = item.presentationData.theme.theme.chat.message.outgoing.textSelectionKnobColor
|
||||
}
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: knobColor), strings: item.presentationData.strings, textNode: self.textNode, updateIsActive: { [weak self] value in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: knobColor, isDark: item.presentationData.theme.theme.overallDarkAppearance), strings: item.presentationData.strings, textNode: self.textNode, updateIsActive: { [weak self] value in
|
||||
self?.updateIsTextSelectionActive?(value)
|
||||
}, present: { [weak self] c, a in
|
||||
self?.arguments?.controllerInteraction.presentGlobalOverlayController(c, a)
|
||||
|
@ -1104,7 +1104,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
knobColor = item.presentationData.theme.theme.chat.message.outgoing.textSelectionKnobColor
|
||||
}
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: knobColor), strings: item.presentationData.strings, textNode: self.textNode.textNode, updateIsActive: { [weak self] value in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: knobColor, isDark: item.presentationData.theme.theme.overallDarkAppearance), strings: item.presentationData.strings, textNode: self.textNode.textNode, updateIsActive: { [weak self] value in
|
||||
self?.updateIsTextSelectionActive?(value)
|
||||
}, present: { [weak self] c, a in
|
||||
guard let self, let item = self.item else {
|
||||
|
@ -607,14 +607,14 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
||||
}
|
||||
|
||||
let placements: [Placement] = [
|
||||
Placement(CGPoint(x: 176.0, y: 13.0), 38.0),
|
||||
Placement(CGPoint(x: 51.0, y: 45.0), 58.0),
|
||||
Placement(CGPoint(x: 349.0, y: 36.0), 58.0),
|
||||
Placement(CGPoint(x: 132.0, y: 64.0), 46.0),
|
||||
Placement(CGPoint(x: 241.0, y: 64.0), 54.0),
|
||||
Placement(CGPoint(x: 68.0, y: 121.0), 44.0),
|
||||
Placement(CGPoint(x: 178.0, y: 122.0), 47.0),
|
||||
Placement(CGPoint(x: 315.0, y: 122.0), 47.0),
|
||||
Placement(CGPoint(x: 180.0, y: 13.0), 38.0),
|
||||
Placement(CGPoint(x: 55.0, y: 47.0), 58.0),
|
||||
Placement(CGPoint(x: 364.0, y: 26.0), 58.0),
|
||||
Placement(CGPoint(x: 133.0, y: 74.0), 46.0),
|
||||
Placement(CGPoint(x: 262.0, y: 67.0), 54.0),
|
||||
Placement(CGPoint(x: 62.0, y: 125.0), 44.0),
|
||||
Placement(CGPoint(x: 171.0, y: 135.0), 47.0),
|
||||
Placement(CGPoint(x: 320.0, y: 124.0), 47.0),
|
||||
]
|
||||
|
||||
for placement in placements {
|
||||
@ -631,7 +631,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
||||
|
||||
let itemSize = CGSize(width: placement.size / 3.0, height: placement.size / 3.0)
|
||||
patternContentLayer.frame = CGRect(origin: CGPoint(x: size.width - placement.position.x / 3.0 - itemSize.width * 0.5, y: placement.position.y / 3.0 - itemSize.height * 0.5), size: itemSize)
|
||||
var alphaFraction = abs(placement.position.x) / 400.0
|
||||
var alphaFraction = abs(placement.position.x) / 500.0
|
||||
alphaFraction = min(1.0, max(0.0, alphaFraction))
|
||||
patternContentLayer.opacity = 0.3 * Float(1.0 - alphaFraction)
|
||||
|
||||
|
@ -16,14 +16,14 @@ final private class ContextMenuActionButton: HighlightTrackingButton {
|
||||
final class ContextMenuActionNode: ASDisplayNode {
|
||||
private let textNode: ImmediateTextNode?
|
||||
private var textSize: CGSize?
|
||||
private let iconNode: ASImageNode?
|
||||
private let iconView: UIImageView?
|
||||
private let action: () -> Void
|
||||
private let button: ContextMenuActionButton
|
||||
private let actionArea: AccessibilityAreaNode
|
||||
|
||||
var dismiss: (() -> Void)?
|
||||
|
||||
init(action: ContextMenuAction, blurred: Bool) {
|
||||
init(action: ContextMenuAction, blurred: Bool, isDark: Bool) {
|
||||
self.actionArea = AccessibilityAreaNode()
|
||||
self.actionArea.accessibilityTraits = .button
|
||||
|
||||
@ -34,30 +34,30 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
let textNode = ImmediateTextNode()
|
||||
textNode.isUserInteractionEnabled = false
|
||||
textNode.displaysAsynchronously = false
|
||||
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: UIColor.white)
|
||||
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: isDark ? .white : .black)
|
||||
textNode.isAccessibilityElement = false
|
||||
|
||||
self.textNode = textNode
|
||||
self.iconNode = nil
|
||||
self.iconView = nil
|
||||
case let .textWithIcon(title, icon):
|
||||
let textNode = ImmediateTextNode()
|
||||
textNode.isUserInteractionEnabled = false
|
||||
textNode.displaysAsynchronously = false
|
||||
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: UIColor.white)
|
||||
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: isDark ? .white : .black)
|
||||
textNode.isAccessibilityElement = false
|
||||
|
||||
let iconNode = ASImageNode()
|
||||
iconNode.displaysAsynchronously = false
|
||||
iconNode.image = icon
|
||||
let iconView = UIImageView()
|
||||
iconView.tintColor = isDark ? .white : .black
|
||||
iconView.image = icon
|
||||
|
||||
self.textNode = textNode
|
||||
self.iconNode = iconNode
|
||||
self.iconView = iconView
|
||||
case let .icon(image):
|
||||
let iconNode = ASImageNode()
|
||||
iconNode.displaysAsynchronously = false
|
||||
iconNode.image = image
|
||||
let iconView = UIImageView()
|
||||
iconView.tintColor = isDark ? .white : .black
|
||||
iconView.image = image
|
||||
|
||||
self.iconNode = iconNode
|
||||
self.iconView = iconView
|
||||
self.textNode = nil
|
||||
}
|
||||
self.action = action.action
|
||||
@ -68,21 +68,25 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
super.init()
|
||||
|
||||
if !blurred {
|
||||
self.backgroundColor = UIColor(rgb: 0x2f2f2f)
|
||||
self.backgroundColor = isDark ? UIColor(rgb: 0x2f2f2f) : nil
|
||||
}
|
||||
|
||||
if let textNode = self.textNode {
|
||||
self.addSubnode(textNode)
|
||||
}
|
||||
if let iconNode = self.iconNode {
|
||||
self.addSubnode(iconNode)
|
||||
if let iconView = self.iconView {
|
||||
self.view.addSubview(iconView)
|
||||
}
|
||||
|
||||
self.button.highligthedChanged = { [weak self] highlighted in
|
||||
if blurred {
|
||||
self?.backgroundColor = highlighted ? UIColor(rgb: 0xffffff, alpha: 0.5) : .clear
|
||||
if isDark {
|
||||
if blurred {
|
||||
self?.backgroundColor = highlighted ? UIColor(rgb: 0xffffff, alpha: 0.5) : .clear
|
||||
} else {
|
||||
self?.backgroundColor = highlighted ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0x2f2f2f)
|
||||
}
|
||||
} else {
|
||||
self?.backgroundColor = highlighted ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0x2f2f2f)
|
||||
self?.backgroundColor = highlighted ? UIColor(rgb: 0xDCE3DC) : .clear
|
||||
}
|
||||
}
|
||||
self.view.addSubview(self.button)
|
||||
@ -116,7 +120,7 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
|
||||
var totalWidth = 0.0
|
||||
totalWidth += textSize.width
|
||||
if let image = self.iconNode?.image {
|
||||
if let image = self.iconView?.image {
|
||||
if totalWidth > 0.0 {
|
||||
totalWidth += 11.0
|
||||
}
|
||||
@ -127,7 +131,7 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
return CGSize(width: totalWidth, height: 54.0)
|
||||
} else if let iconNode = self.iconNode, let image = iconNode.image {
|
||||
} else if let iconView = self.iconView, let image = iconView.image {
|
||||
return CGSize(width: image.size.width + 36.0, height: 54.0)
|
||||
} else {
|
||||
return CGSize(width: 36.0, height: 54.0)
|
||||
@ -144,7 +148,7 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
if let textSize = self.textSize {
|
||||
totalWidth += textSize.width
|
||||
}
|
||||
if let image = self.iconNode?.image {
|
||||
if let image = self.iconView?.image {
|
||||
if totalWidth > 0.0 {
|
||||
totalWidth += 11.0
|
||||
}
|
||||
@ -154,9 +158,9 @@ final class ContextMenuActionNode: ASDisplayNode {
|
||||
if let textNode = self.textNode, let textSize = self.textSize {
|
||||
textNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0), y: floor((self.bounds.size.height - textSize.height) / 2.0)), size: textSize)
|
||||
}
|
||||
if let iconNode = self.iconNode, let image = iconNode.image {
|
||||
if let iconView = self.iconView, let image = iconView.image {
|
||||
let iconSize = image.size
|
||||
iconNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0) + totalWidth - iconSize.width, y: floorToScreenPixels((self.bounds.size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
iconView.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0) + totalWidth - iconSize.width, y: floorToScreenPixels((self.bounds.size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ public final class ContextMenuControllerImpl: ViewController, KeyShortcutRespond
|
||||
private let hasHapticFeedback: Bool
|
||||
private let blurred: Bool
|
||||
private let skipCoordnateConversion: Bool
|
||||
private let isDark: Bool
|
||||
|
||||
private var layout: ContainerViewLayout?
|
||||
|
||||
@ -33,6 +34,7 @@ public final class ContextMenuControllerImpl: ViewController, KeyShortcutRespond
|
||||
self.hasHapticFeedback = arguments.hasHapticFeedback
|
||||
self.blurred = arguments.blurred
|
||||
self.skipCoordnateConversion = arguments.skipCoordnateConversion
|
||||
self.isDark = arguments.isDark
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
@ -54,7 +56,7 @@ public final class ContextMenuControllerImpl: ViewController, KeyShortcutRespond
|
||||
return false
|
||||
}
|
||||
return dismissOnTap(view, point)
|
||||
}, catchTapsOutside: self.catchTapsOutside, hasHapticFeedback: self.hasHapticFeedback, blurred: self.blurred)
|
||||
}, catchTapsOutside: self.catchTapsOutside, hasHapticFeedback: self.hasHapticFeedback, blurred: self.blurred, isDark: self.isDark)
|
||||
self.displayNodeDidLoad()
|
||||
}
|
||||
|
||||
|
@ -5,15 +5,6 @@ import AppBundle
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
|
||||
private func generateShadowImage() -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 1.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setShadow(offset: CGSize(), blur: 10.0, color: UIColor(white: 0.18, alpha: 1.0).cgColor)
|
||||
context.setFillColor(UIColor(white: 0.18, alpha: 1.0).cgColor)
|
||||
context.fill(CGRect(origin: CGPoint(x: -15.0, y: 0.0), size: CGSize(width: 30.0, height: 1.0)))
|
||||
})
|
||||
}
|
||||
|
||||
private final class ArrowNode: HighlightTrackingButtonNode {
|
||||
private let isLeft: Bool
|
||||
|
||||
@ -21,7 +12,7 @@ private final class ArrowNode: HighlightTrackingButtonNode {
|
||||
private let separatorLayer: SimpleLayer
|
||||
var action: (() -> Void)?
|
||||
|
||||
init(isLeft: Bool) {
|
||||
init(isLeft: Bool, isDark: Bool) {
|
||||
self.isLeft = isLeft
|
||||
|
||||
self.iconView = UIImageView()
|
||||
@ -39,12 +30,15 @@ private final class ArrowNode: HighlightTrackingButtonNode {
|
||||
|
||||
self.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.backgroundColor = UIColor(rgb: 0x2f2f2f)
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.backgroundColor = highlighted ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0x2f2f2f)
|
||||
if isDark {
|
||||
self.backgroundColor = highlighted ? UIColor(rgb: 0x8c8e8e) : nil
|
||||
} else {
|
||||
self.backgroundColor = highlighted ? UIColor(rgb: 0xDCE3DC) : nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +64,8 @@ private final class ArrowNode: HighlightTrackingButtonNode {
|
||||
}
|
||||
|
||||
final class ContextMenuNode: ASDisplayNode {
|
||||
private let isDark: Bool
|
||||
|
||||
private let actions: [ContextMenuAction]
|
||||
private let dismiss: () -> Void
|
||||
private let dismissOnTap: (UIView, CGPoint) -> Bool
|
||||
@ -96,22 +92,24 @@ final class ContextMenuNode: ASDisplayNode {
|
||||
|
||||
private let feedback: HapticFeedback?
|
||||
|
||||
init(actions: [ContextMenuAction], dismiss: @escaping () -> Void, dismissOnTap: @escaping (UIView, CGPoint) -> Bool, catchTapsOutside: Bool, hasHapticFeedback: Bool, blurred: Bool = false) {
|
||||
init(actions: [ContextMenuAction], dismiss: @escaping () -> Void, dismissOnTap: @escaping (UIView, CGPoint) -> Bool, catchTapsOutside: Bool, hasHapticFeedback: Bool, blurred: Bool = false, isDark: Bool = true) {
|
||||
self.isDark = isDark
|
||||
|
||||
self.actions = actions
|
||||
self.dismiss = dismiss
|
||||
self.dismissOnTap = dismissOnTap
|
||||
self.catchTapsOutside = catchTapsOutside
|
||||
|
||||
self.containerNode = ContextMenuContainerNode(blurred: blurred)
|
||||
self.containerNode = ContextMenuContainerNode(isBlurred: blurred, isDark: isDark)
|
||||
self.contentNode = ASDisplayNode()
|
||||
self.contentNode.clipsToBounds = true
|
||||
|
||||
self.actionNodes = actions.map { action in
|
||||
return ContextMenuActionNode(action: action, blurred: blurred)
|
||||
return ContextMenuActionNode(action: action, blurred: blurred, isDark: isDark)
|
||||
}
|
||||
|
||||
self.pageLeftNode = ArrowNode(isLeft: true)
|
||||
self.pageRightNode = ArrowNode(isLeft: false)
|
||||
self.pageLeftNode = ArrowNode(isLeft: true, isDark: isDark)
|
||||
self.pageRightNode = ArrowNode(isLeft: false, isDark: isDark)
|
||||
|
||||
if hasHapticFeedback {
|
||||
self.feedback = HapticFeedback()
|
||||
@ -122,7 +120,7 @@ final class ContextMenuNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.containerNode.addSubnode(self.contentNode)
|
||||
self.containerNode.containerNode.addSubnode(self.contentNode)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
let dismissNode = {
|
||||
@ -133,8 +131,8 @@ final class ContextMenuNode: ASDisplayNode {
|
||||
self.contentNode.addSubnode(actionNode)
|
||||
}
|
||||
|
||||
self.containerNode.addSubnode(self.pageLeftNode)
|
||||
self.containerNode.addSubnode(self.pageRightNode)
|
||||
self.containerNode.containerNode.addSubnode(self.pageLeftNode)
|
||||
self.containerNode.containerNode.addSubnode(self.pageRightNode)
|
||||
|
||||
let navigatePage: (Bool) -> Void = { [weak self] isLeft in
|
||||
guard let self else {
|
||||
@ -173,12 +171,12 @@ final class ContextMenuNode: ASDisplayNode {
|
||||
var offsetX: CGFloat
|
||||
}
|
||||
|
||||
let separatorColor = UIColor(rgb: 0x8c8e8e)
|
||||
let separatorColor = self.isDark ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0xDCE3DC)
|
||||
|
||||
let height: CGFloat = 54.0
|
||||
|
||||
let pageLeftSize = self.pageLeftNode.update(color: .white, separatorColor: separatorColor, height: height)
|
||||
let pageRightSize = self.pageRightNode.update(color: .white, separatorColor: separatorColor, height: height)
|
||||
let pageLeftSize = self.pageLeftNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
|
||||
let pageRightSize = self.pageRightNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
|
||||
|
||||
let maxPageWidth = layout.size.width - 20.0 - pageLeftSize.width - pageRightSize.width
|
||||
var absoluteActionOffsetX: CGFloat = 0.0
|
||||
|
@ -729,7 +729,7 @@ final class StoryContentCaptionComponent: Component {
|
||||
self.textSelectionKnobContainer.addSubview(textSelectionKnobSurface)
|
||||
}
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: component.theme.list.itemAccentColor), strings: component.strings, textNode: textNode, updateIsActive: { [weak self] value in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: component.theme.list.itemAccentColor, isDark: true), strings: component.strings, textNode: textNode, updateIsActive: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
@ -61,11 +61,13 @@ public final class TextSelectionTheme {
|
||||
public let selection: UIColor
|
||||
public let knob: UIColor
|
||||
public let knobDiameter: CGFloat
|
||||
public let isDark: Bool
|
||||
|
||||
public init(selection: UIColor, knob: UIColor, knobDiameter: CGFloat = 12.0) {
|
||||
public init(selection: UIColor, knob: UIColor, knobDiameter: CGFloat = 12.0, isDark: Bool) {
|
||||
self.selection = selection
|
||||
self.knob = knob
|
||||
self.knobDiameter = knobDiameter
|
||||
self.isDark = isDark
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,7 +757,7 @@ public final class TextSelectionNode: ASDisplayNode {
|
||||
|
||||
self.contextMenu?.dismiss()
|
||||
|
||||
let contextMenu = makeContextMenuController(actions: actions, catchTapsOutside: false, hasHapticFeedback: false, skipCoordnateConversion: self.menuSkipCoordnateConversion)
|
||||
let contextMenu = makeContextMenuController(actions: actions, catchTapsOutside: false, hasHapticFeedback: false, isDark: self.theme.isDark, skipCoordnateConversion: self.menuSkipCoordnateConversion)
|
||||
contextMenu.dismissOnTap = { [weak self] view, point in
|
||||
guard let self else {
|
||||
return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user