mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-01 04:08:07 +00:00
Temp
This commit is contained in:
parent
e0d511165c
commit
5a8bd1d98d
@ -14,7 +14,7 @@ open class PagerExternalTopPanelContainer: SparseContainerView {
|
||||
}
|
||||
|
||||
public protocol PagerContentViewWithBackground: UIView {
|
||||
func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, transition: ComponentTransition)
|
||||
func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, externalTintMaskContainer: UIView?, transition: ComponentTransition)
|
||||
}
|
||||
|
||||
public final class PagerComponentChildEnvironment: Equatable {
|
||||
@ -206,6 +206,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
public let externalTopPanelContainer: PagerExternalTopPanelContainer?
|
||||
public let bottomPanel: AnyComponent<PagerComponentPanelEnvironment<TopPanelEnvironment>>?
|
||||
public let externalBottomPanelContainer: PagerExternalTopPanelContainer?
|
||||
public let externalTintMaskContainer: UIView?
|
||||
public let panelStateUpdated: ((PagerComponentPanelState, ComponentTransition) -> Void)?
|
||||
public let isTopPanelExpandedUpdated: (Bool, ComponentTransition) -> Void
|
||||
public let isTopPanelHiddenUpdated: (Bool, ComponentTransition) -> Void
|
||||
@ -228,6 +229,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
externalTopPanelContainer: PagerExternalTopPanelContainer?,
|
||||
bottomPanel: AnyComponent<PagerComponentPanelEnvironment<TopPanelEnvironment>>?,
|
||||
externalBottomPanelContainer: PagerExternalTopPanelContainer?,
|
||||
externalTintMaskContainer: UIView?,
|
||||
panelStateUpdated: ((PagerComponentPanelState, ComponentTransition) -> Void)?,
|
||||
isTopPanelExpandedUpdated: @escaping (Bool, ComponentTransition) -> Void,
|
||||
isTopPanelHiddenUpdated: @escaping (Bool, ComponentTransition) -> Void,
|
||||
@ -249,6 +251,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
self.externalTopPanelContainer = externalTopPanelContainer
|
||||
self.bottomPanel = bottomPanel
|
||||
self.externalBottomPanelContainer = externalBottomPanelContainer
|
||||
self.externalTintMaskContainer = externalTintMaskContainer
|
||||
self.panelStateUpdated = panelStateUpdated
|
||||
self.isTopPanelExpandedUpdated = isTopPanelExpandedUpdated
|
||||
self.isTopPanelHiddenUpdated = isTopPanelHiddenUpdated
|
||||
@ -292,6 +295,9 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
if lhs.externalBottomPanelContainer !== rhs.externalBottomPanelContainer {
|
||||
return false
|
||||
}
|
||||
if lhs.externalTintMaskContainer !== rhs.externalTintMaskContainer {
|
||||
return false
|
||||
}
|
||||
if lhs.panelHideBehavior != rhs.panelHideBehavior {
|
||||
return false
|
||||
}
|
||||
@ -307,6 +313,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
public final class View: UIView, ComponentTaggedView {
|
||||
private final class ContentView {
|
||||
let view: ComponentHostView<(ChildEnvironmentType, PagerComponentChildEnvironment)>
|
||||
let tintMaskContainer: UIView
|
||||
var scrollingPanelOffsetToTopEdge: CGFloat = 0.0
|
||||
var scrollingPanelOffsetToBottomEdge: CGFloat = .greatestFiniteMagnitude
|
||||
var scrollingPanelOffsetFraction: CGFloat = 0.0
|
||||
@ -315,6 +322,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
|
||||
init(view: ComponentHostView<(ChildEnvironmentType, PagerComponentChildEnvironment)>) {
|
||||
self.view = view
|
||||
self.tintMaskContainer = UIView()
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,6 +855,9 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
} else {
|
||||
self.contentClippingView.insertSubview(contentView.view, at: 0)
|
||||
}
|
||||
if let externalTintMaskContainer = component.externalTintMaskContainer {
|
||||
externalTintMaskContainer.addSubview(contentView.tintMaskContainer)
|
||||
}
|
||||
}
|
||||
|
||||
let childContentInsets = contentInsets
|
||||
@ -890,6 +901,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
if wasAdded {
|
||||
if case .none = transition.animation {
|
||||
contentView.view.frame = contentFrame
|
||||
contentView.tintMaskContainer.frame = contentFrame
|
||||
} else {
|
||||
var referenceDirectionIsRight: Bool?
|
||||
for (previousId, previousFrame) in referenceFrames {
|
||||
@ -906,6 +918,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
}
|
||||
if let referenceDirectionIsRight = referenceDirectionIsRight {
|
||||
contentView.view.frame = contentFrame.offsetBy(dx: referenceDirectionIsRight ? contentFrame.width : (-contentFrame.width), dy: 0.0)
|
||||
contentView.tintMaskContainer.frame = contentView.view.frame
|
||||
transition.setFrame(view: contentView.view, frame: contentFrame, completion: { [weak self] completed in
|
||||
if completed && !isInBounds && isPartOfTransition {
|
||||
DispatchQueue.main.async {
|
||||
@ -913,6 +926,7 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
}
|
||||
}
|
||||
})
|
||||
transition.setFrame(view: contentView.tintMaskContainer, frame: contentFrame)
|
||||
} else {
|
||||
contentView.view.frame = contentFrame
|
||||
}
|
||||
@ -925,10 +939,11 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
}
|
||||
}
|
||||
})
|
||||
transition.setFrame(view: contentView.tintMaskContainer, frame: contentFrame)
|
||||
}
|
||||
|
||||
if let contentViewWithBackground = contentView.view.componentView as? PagerContentViewWithBackground {
|
||||
contentViewWithBackground.pagerUpdateBackground(backgroundFrame: backgroundFrame, topPanelHeight: topPanelHeight, transition: contentTransition)
|
||||
contentViewWithBackground.pagerUpdateBackground(backgroundFrame: backgroundFrame, topPanelHeight: topPanelHeight, externalTintMaskContainer: component.externalTintMaskContainer == nil ? nil : contentView.tintMaskContainer, transition: contentTransition)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -941,7 +956,10 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
}
|
||||
}
|
||||
for id in removedIds {
|
||||
self.contentViews.removeValue(forKey: id)?.view.removeFromSuperview()
|
||||
if let contentView = self.contentViews.removeValue(forKey: id) {
|
||||
contentView.view.removeFromSuperview()
|
||||
contentView.tintMaskContainer.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
if let panelStateUpdated = component.panelStateUpdated {
|
||||
|
||||
@ -707,6 +707,7 @@ final class ComposePollScreenComponent: Component {
|
||||
hasStickers: false,
|
||||
hasGifs: false,
|
||||
hideBackground: true,
|
||||
maskEdge: true,
|
||||
sendGif: nil
|
||||
)
|
||||
)
|
||||
|
||||
@ -237,7 +237,11 @@ public enum DeviceMetrics: CaseIterable, Equatable {
|
||||
public func onScreenNavigationHeight(inLandscape: Bool, systemOnScreenNavigationHeight: CGFloat?) -> CGFloat? {
|
||||
switch self {
|
||||
case .iPhoneX, .iPhoneXSMax, .iPhoneXr, .iPhone12Mini, .iPhone12, .iPhone12ProMax, .iPhone13Mini, .iPhone13, .iPhone13Pro, .iPhone13ProMax, .iPhone14Pro, .iPhone14ProMax, .iPhone16Pro, .iPhone16ProMax:
|
||||
return inLandscape ? 21.0 : 34.0
|
||||
if #available(iOS 26.0, *) {
|
||||
return 20.0
|
||||
} else {
|
||||
return inLandscape ? 21.0 : 34.0
|
||||
}
|
||||
case .iPhone14ProZoomed:
|
||||
return inLandscape ? 21.0 : 28.0
|
||||
case .iPhone14ProMaxZoomed:
|
||||
|
||||
@ -312,6 +312,7 @@ open class BlurredBackgroundView: UIView {
|
||||
private var _color: UIColor?
|
||||
|
||||
private var enableBlur: Bool
|
||||
private var customBlurRadius: CGFloat?
|
||||
|
||||
public private(set) var effectView: UIVisualEffectView?
|
||||
private let backgroundView: UIView
|
||||
@ -326,9 +327,10 @@ open class BlurredBackgroundView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
public init(color: UIColor?, enableBlur: Bool = true) {
|
||||
public init(color: UIColor?, enableBlur: Bool = true, customBlurRadius: CGFloat? = nil) {
|
||||
self._color = nil
|
||||
self.enableBlur = enableBlur
|
||||
self.customBlurRadius = customBlurRadius
|
||||
|
||||
self.backgroundView = UIView()
|
||||
|
||||
@ -349,7 +351,6 @@ open class BlurredBackgroundView: UIView {
|
||||
if let color = self._color, self.enableBlur && !sharedIsReduceTransparencyEnabled && ((color.alpha > .ulpOfOne && color.alpha < 0.95) || forceKeepBlur) {
|
||||
if self.effectView == nil {
|
||||
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
|
||||
//effectView.isHidden = true
|
||||
|
||||
for subview in effectView.subviews {
|
||||
if subview.description.contains("VisualEffectSubview") {
|
||||
@ -373,6 +374,9 @@ open class BlurredBackgroundView: UIView {
|
||||
if !allowedKeys.contains(filterName) {
|
||||
return false
|
||||
}
|
||||
if let customBlurRadius = self.customBlurRadius, filterName == "gaussianBlur" {
|
||||
filter.setValue(customBlurRadius as NSNumber, forKey: "inputRadius")
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,9 +179,9 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
if bottomInset == 0.0 {
|
||||
bottomInset = 8.0
|
||||
} else {
|
||||
bottomInset = max(bottomInset - 13.0, 8.0)
|
||||
bottomInset = max(bottomInset, 8.0)
|
||||
}
|
||||
let sideInset: CGFloat = 21.0
|
||||
let sideInset: CGFloat = 20.0
|
||||
|
||||
var selectedId: AnyHashable?
|
||||
if self.selectedIndex < self.tabBarItems.count {
|
||||
|
||||
@ -941,7 +941,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
||||
let inputPanel = PresentationThemeChatInputPanel(
|
||||
panelBackgroundColor: rootNavigationBar.blurredBackgroundColor,
|
||||
panelBackgroundColorNoWallpaper: UIColor(rgb: 0xffffff),
|
||||
panelSeparatorColor: UIColor(rgb: 0xb2b2b2),
|
||||
panelSeparatorColor: UIColor(white: 1.0, alpha: 0.5),
|
||||
panelControlAccentColor: defaultDayAccentColor,
|
||||
panelControlColor: UIColor(rgb: 0x858e99),
|
||||
panelControlDisabledColor: UIColor(rgb: 0x727b87, alpha: 0.5),
|
||||
|
||||
@ -1219,6 +1219,7 @@ final class AvatarEditorScreenComponent: Component {
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -99,7 +99,7 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(size.width / 2.0 - innerSize.width / 2.0), y: floorToScreenPixels(size.height / 2.0 - innerSize.height / 2.0)), size: innerSize)
|
||||
self.backgroundView.frame = backgroundFrame
|
||||
self.backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: .immediate)
|
||||
self.backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate)
|
||||
|
||||
if let iconImage = self.iconNode.image {
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(size.width / 2.0 - iconImage.size.width / 2.0), y: floorToScreenPixels(size.height / 2.0 - iconImage.size.height / 2.0)), size: iconImage.size)
|
||||
|
||||
@ -334,7 +334,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.micButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.micButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: ComponentTransition(transition))
|
||||
self.micButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
|
||||
transition.updateFrame(layer: self.micButton.layer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.micButton.layoutItems()
|
||||
@ -349,7 +349,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
|
||||
transition.updateFrame(view: self.expandMediaInputButton, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.updateFrame(view: self.expandMediaInputButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: ComponentTransition(transition))
|
||||
self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
if let image = self.expandMediaInputButtonIcon.image {
|
||||
let expandIconFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size)
|
||||
transition.updatePosition(layer: self.expandMediaInputButtonIcon.layer, position: expandIconFrame.center)
|
||||
|
||||
@ -2213,7 +2213,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
let alphaTransitionIn: ContainedViewLayoutTransition = transition.isAnimated ? ContainedViewLayoutTransition.animated(duration: 0.15, curve: .easeInOut) : .immediate
|
||||
let alphaTransitionOut: ContainedViewLayoutTransition = transition.isAnimated ? ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut) : .immediate
|
||||
|
||||
let accessoryPanelAnimationBlurRadius: CGFloat = 10.0
|
||||
let accessoryPanelAnimationBlurRadius: CGFloat = 20.0
|
||||
var removedAccessoryPanelView: UIView?
|
||||
|
||||
if let currentAccessoryPanel = self.accessoryPanel, currentAccessoryPanel.component.id != accessoryPanel?.id {
|
||||
@ -2334,7 +2334,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
transition.updateFrame(node: self.textInputContainer, frame: textInputContainerBackgroundFrame)
|
||||
transition.updateFrame(view: self.textInputContainerBackgroundView, frame: CGRect(origin: CGPoint(), size: textInputContainerBackgroundFrame.size))
|
||||
|
||||
self.textInputContainerBackgroundView.update(size: textInputContainerBackgroundFrame.size, cornerRadius: floor(minimalInputHeight * 0.5), isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: ComponentTransition(transition))
|
||||
self.textInputContainerBackgroundView.update(size: textInputContainerBackgroundFrame.size, cornerRadius: floor(minimalInputHeight * 0.5), isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
|
||||
if let removedAccessoryPanelView {
|
||||
if let removedAccessoryPanelView = removedAccessoryPanelView as? ChatInputAccessoryPanelView {
|
||||
@ -2625,7 +2625,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
let attachmentButtonFrame = CGRect(origin: CGPoint(x: attachmentButtonX, y: textInputFrame.maxY - 40.0), size: CGSize(width: 40.0, height: 40.0))
|
||||
self.attachmentButtonBackground.frame = CGRect(origin: CGPoint(), size: attachmentButtonFrame.size)
|
||||
self.attachmentButtonBackground.update(size: attachmentButtonFrame.size, cornerRadius: attachmentButtonFrame.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: isEditingMedia ? .init(kind: .custom, color: interfaceState.theme.chat.inputPanel.actionControlFillColor) : .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: ComponentTransition(transition))
|
||||
self.attachmentButtonBackground.update(size: attachmentButtonFrame.size, cornerRadius: attachmentButtonFrame.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: isEditingMedia ? .init(kind: .custom, color: interfaceState.theme.chat.inputPanel.actionControlFillColor) : .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
|
||||
transition.updateFrame(layer: self.attachmentButton.layer, frame: attachmentButtonFrame)
|
||||
transition.updateFrame(node: self.attachmentButtonDisabledNode, frame: self.attachmentButton.frame)
|
||||
|
||||
@ -41,6 +41,7 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/LegacyMessageInputPanelInputView:LegacyMessageInputPanelInputView",
|
||||
"//submodules/AttachmentTextInputPanelNode",
|
||||
"//submodules/TelegramUI/Components/BatchVideoRendering",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -31,6 +31,7 @@ import Pasteboard
|
||||
import EntityKeyboardGifContent
|
||||
import LegacyMessageInputPanelInputView
|
||||
import AttachmentTextInputPanelNode
|
||||
import GlassBackgroundComponent
|
||||
|
||||
public final class EmptyInputView: UIView, UIInputViewAudioFeedback {
|
||||
public var enableInputClicksWhenVisible: Bool {
|
||||
@ -168,6 +169,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
hasStickers: Bool = true,
|
||||
hasGifs: Bool = true,
|
||||
hideBackground: Bool = false,
|
||||
maskEdge: Bool = false,
|
||||
forceHasPremium: Bool = false,
|
||||
sendGif: ((FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool)?
|
||||
) -> Signal<InputData, NoError> {
|
||||
@ -187,7 +189,8 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
chatPeerId: chatPeerId,
|
||||
hasSearch: hasSearch,
|
||||
forceHasPremium: forceHasPremium,
|
||||
hideBackground: hideBackground
|
||||
hideBackground: hideBackground,
|
||||
maskEdge: maskEdge
|
||||
)
|
||||
|
||||
let stickerNamespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks]
|
||||
@ -414,6 +417,14 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
return self.externalTopPanelContainerImpl
|
||||
}
|
||||
|
||||
private let clippingView: UIView
|
||||
private var backgroundView: BlurredBackgroundView?
|
||||
private var backgroundTintView: UIImageView?
|
||||
private var backgroundChromeView: UIImageView?
|
||||
private var backgroundTintMaskView: UIView?
|
||||
private var backgroundTintMaskContentView: UIView?
|
||||
private var externalBackground: EmojiPagerContentComponent.ExternalBackground?
|
||||
|
||||
public var switchToTextInput: (() -> Void)?
|
||||
|
||||
private var currentState: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool)?
|
||||
@ -476,6 +487,10 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
self.interaction = interaction
|
||||
|
||||
self.clippingView = UIView()
|
||||
self.clippingView.clipsToBounds = true
|
||||
self.clippingView.layer.cornerRadius = 20.0
|
||||
|
||||
self.entityKeyboardView = ComponentHostView<Empty>()
|
||||
|
||||
super.init()
|
||||
@ -485,7 +500,41 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
self.topBackgroundExtension = 34.0
|
||||
self.followsDefaultHeight = true
|
||||
|
||||
self.view.addSubview(self.entityKeyboardView)
|
||||
if "".isEmpty {
|
||||
let backgroundView = BlurredBackgroundView(color: .black, enableBlur: true)
|
||||
self.backgroundView = backgroundView
|
||||
self.view.addSubview(backgroundView)
|
||||
|
||||
let backgroundTintView = UIImageView()
|
||||
self.backgroundTintView = backgroundTintView
|
||||
self.view.addSubview(backgroundTintView)
|
||||
|
||||
let backgroundTintMaskView = UIView()
|
||||
backgroundTintMaskView.backgroundColor = .white
|
||||
self.backgroundTintMaskView = backgroundTintMaskView
|
||||
if let filter = CALayer.luminanceToAlpha() {
|
||||
backgroundTintMaskView.layer.filters = [filter]
|
||||
}
|
||||
backgroundTintView.mask = backgroundTintMaskView
|
||||
|
||||
let backgroundTintMaskContentView = UIView()
|
||||
backgroundTintMaskView.addSubview(backgroundTintMaskContentView)
|
||||
self.backgroundTintMaskContentView = backgroundTintMaskContentView
|
||||
|
||||
let backgroundChromeView = UIImageView()
|
||||
self.backgroundChromeView = backgroundChromeView
|
||||
|
||||
self.externalBackground = EmojiPagerContentComponent.ExternalBackground(
|
||||
effectContainerView: backgroundTintMaskContentView
|
||||
)
|
||||
}
|
||||
|
||||
self.clippingView.addSubview(self.entityKeyboardView)
|
||||
self.view.addSubview(self.clippingView)
|
||||
|
||||
if let backgroundChromeView = self.backgroundChromeView {
|
||||
self.view.addSubview(backgroundChromeView)
|
||||
}
|
||||
|
||||
self.externalTopPanelContainerImpl = PagerExternalTopPanelContainer()
|
||||
|
||||
@ -1162,7 +1211,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
chatPeerId: chatPeerId,
|
||||
peekBehavior: stickerPeekBehavior,
|
||||
customLayout: nil,
|
||||
externalBackground: nil,
|
||||
externalBackground: self.externalBackground,
|
||||
externalExpansionView: nil,
|
||||
customContentView: nil,
|
||||
useOpaqueTheme: self.useOpaqueTheme,
|
||||
@ -1509,7 +1558,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
chatPeerId: chatPeerId,
|
||||
peekBehavior: stickerPeekBehavior,
|
||||
customLayout: nil,
|
||||
externalBackground: nil,
|
||||
externalBackground: self.externalBackground,
|
||||
externalExpansionView: nil,
|
||||
customContentView: nil,
|
||||
useOpaqueTheme: self.useOpaqueTheme,
|
||||
@ -1739,6 +1788,22 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
|
||||
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if let result = super.hitTest(point, with: event) {
|
||||
return result
|
||||
}
|
||||
|
||||
if let backgroundView = self.backgroundView, backgroundView.frame.contains(point) {
|
||||
for subview in self.view.subviews.reversed() {
|
||||
if let result = subview.hitTest(self.view.convert(point, to: subview), with: event) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
public override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
self.currentState = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded)
|
||||
|
||||
@ -1849,7 +1914,8 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
defaultToEmojiTab: self.defaultToEmojiTab,
|
||||
externalTopPanelContainer: self.externalTopPanelContainerImpl,
|
||||
externalBottomPanelContainer: nil,
|
||||
displayTopPanelBackground: self.opaqueTopPanelBackground ? .opaque : .none,
|
||||
externalTintMaskContainer: self.backgroundTintMaskContentView,
|
||||
displayTopPanelBackground: self.opaqueTopPanelBackground ? .opaque : .blur,
|
||||
topPanelExtensionUpdated: { [weak self] topPanelExtension, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -1939,7 +2005,52 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
environment: {},
|
||||
containerSize: CGSize(width: width, height: expandedHeight)
|
||||
)
|
||||
transition.updateFrame(view: self.entityKeyboardView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: entityKeyboardSize))
|
||||
|
||||
var clippingFrame = CGRect(origin: CGPoint(), size: entityKeyboardSize)
|
||||
clippingFrame.size.height += 32.0
|
||||
|
||||
var entityKeyboardSizeFrame = CGRect(origin: CGPoint(), size: entityKeyboardSize)
|
||||
if self.hideInput {
|
||||
clippingFrame.size.height += self.topBackgroundExtension
|
||||
clippingFrame.origin.y -= self.topBackgroundExtension
|
||||
entityKeyboardSizeFrame.origin.y += self.topBackgroundExtension
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.entityKeyboardView, frame: entityKeyboardSizeFrame)
|
||||
|
||||
transition.updateFrame(view: self.clippingView, frame: clippingFrame)
|
||||
|
||||
if let backgroundView = self.backgroundView, let backgroundTintView = self.backgroundTintView, let backgroundTintMaskView = self.backgroundTintMaskView, let backgroundTintMaskContentView = self.backgroundTintMaskContentView, let backgroundChromeView = self.backgroundChromeView {
|
||||
var backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: entityKeyboardSize)
|
||||
if self.hideInput {
|
||||
backgroundFrame.size.height += self.topBackgroundExtension
|
||||
backgroundFrame.origin.y -= self.topBackgroundExtension
|
||||
}
|
||||
backgroundFrame.size.height += 32.0
|
||||
|
||||
if backgroundChromeView.image == nil {
|
||||
backgroundChromeView.image = GlassBackgroundView.generateForegroundImage(size: CGSize(width: 20.0 * 2.0, height: 20.0 * 2.0), isDark: interfaceState.theme.overallDarkAppearance, fillColor: .clear)
|
||||
}
|
||||
if backgroundTintView.image == nil {
|
||||
backgroundTintView.image = generateStretchableFilledCircleImage(diameter: 20.0 * 2.0, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
backgroundTintView.tintColor = interfaceState.theme.chat.inputMediaPanel.backgroundColor
|
||||
|
||||
transition.updateFrame(view: backgroundView, frame: backgroundFrame)
|
||||
backgroundView.updateColor(color: .clear, forceKeepBlur: true, transition: .immediate)
|
||||
backgroundView.update(size: backgroundFrame.size, cornerRadius: 20.0, maskedCorners: [.layerMinXMinYCorner, .layerMaxXMinYCorner], transition: transition)
|
||||
|
||||
transition.updateFrame(view: backgroundChromeView, frame: backgroundFrame.insetBy(dx: -1.0, dy: 0.0))
|
||||
|
||||
var backgroundTintMaskContentFrame = CGRect(origin: CGPoint(), size: backgroundFrame.size)
|
||||
if self.hideInput {
|
||||
backgroundTintMaskContentFrame.origin.y += self.topBackgroundExtension
|
||||
}
|
||||
transition.updateFrame(view: backgroundTintView, frame: backgroundFrame)
|
||||
|
||||
transition.updateFrame(view: backgroundTintMaskView, frame: CGRect(origin: CGPoint(), size: backgroundFrame.size))
|
||||
transition.updateFrame(view: backgroundTintMaskContentView, frame: backgroundTintMaskContentFrame)
|
||||
}
|
||||
|
||||
let layoutTime = CFAbsoluteTimeGetCurrent() - startTime
|
||||
if layoutTime > 0.1 {
|
||||
|
||||
@ -467,7 +467,7 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
|
||||
tintColor = UIColor(white: 0.0, alpha: 0.5)
|
||||
} else {
|
||||
isDark = self.theme.overallDarkAppearance
|
||||
tintColor = self.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)
|
||||
tintColor = self.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)
|
||||
}
|
||||
|
||||
let view = WrapperBlurrredBackgroundView(size: CGSize(width: 40.0, height: 72.0), isDark: isDark, tintColor: tintColor)
|
||||
|
||||
@ -187,6 +187,7 @@ public final class EmojiStatusSelectionComponent: Component {
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -623,6 +623,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
public let searchState: SearchState
|
||||
public let warpContentsOnEdges: Bool
|
||||
public let hideBackground: Bool
|
||||
public let maskEdge: Bool
|
||||
public let displaySearchWithPlaceholder: String?
|
||||
public let searchCategories: EmojiSearchCategories?
|
||||
public let searchInitiallyHidden: Bool
|
||||
@ -648,6 +649,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
searchState: SearchState,
|
||||
warpContentsOnEdges: Bool,
|
||||
hideBackground: Bool,
|
||||
maskEdge: Bool,
|
||||
displaySearchWithPlaceholder: String?,
|
||||
searchCategories: EmojiSearchCategories?,
|
||||
searchInitiallyHidden: Bool,
|
||||
@ -672,6 +674,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
self.searchState = searchState
|
||||
self.warpContentsOnEdges = warpContentsOnEdges
|
||||
self.hideBackground = hideBackground
|
||||
self.maskEdge = maskEdge
|
||||
self.displaySearchWithPlaceholder = displaySearchWithPlaceholder
|
||||
self.searchCategories = searchCategories
|
||||
self.searchInitiallyHidden = searchInitiallyHidden
|
||||
@ -699,6 +702,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
searchState: searchState,
|
||||
warpContentsOnEdges: self.warpContentsOnEdges,
|
||||
hideBackground: self.hideBackground,
|
||||
maskEdge: self.maskEdge,
|
||||
displaySearchWithPlaceholder: self.displaySearchWithPlaceholder,
|
||||
searchCategories: self.searchCategories,
|
||||
searchInitiallyHidden: self.searchInitiallyHidden,
|
||||
@ -727,6 +731,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
searchState: searchState,
|
||||
warpContentsOnEdges: self.warpContentsOnEdges,
|
||||
hideBackground: self.hideBackground,
|
||||
maskEdge: self.maskEdge,
|
||||
displaySearchWithPlaceholder: self.displaySearchWithPlaceholder,
|
||||
searchCategories: self.searchCategories,
|
||||
searchInitiallyHidden: self.searchInitiallyHidden,
|
||||
@ -755,6 +760,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
searchState: searchState,
|
||||
warpContentsOnEdges: self.warpContentsOnEdges,
|
||||
hideBackground: self.hideBackground,
|
||||
maskEdge: self.maskEdge,
|
||||
displaySearchWithPlaceholder: self.displaySearchWithPlaceholder,
|
||||
searchCategories: self.searchCategories,
|
||||
searchInitiallyHidden: self.searchInitiallyHidden,
|
||||
@ -811,6 +817,9 @@ public final class EmojiPagerContentComponent: Component {
|
||||
if lhs.hideBackground != rhs.hideBackground {
|
||||
return false
|
||||
}
|
||||
if lhs.maskEdge != rhs.maskEdge {
|
||||
return false
|
||||
}
|
||||
if lhs.displaySearchWithPlaceholder != rhs.displaySearchWithPlaceholder {
|
||||
return false
|
||||
}
|
||||
@ -4016,12 +4025,12 @@ public final class EmojiPagerContentComponent: Component {
|
||||
self.state?.updated(transition: ComponentTransition(animation: .curve(duration: 0.4, curve: .spring)).withUserData(ContentAnimation(type: .groupExpanded(id: groupId))))
|
||||
}
|
||||
|
||||
public func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, transition: ComponentTransition) {
|
||||
public func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, externalTintMaskContainer: UIView?, transition: ComponentTransition) {
|
||||
guard let component = self.component, let keyboardChildEnvironment = self.keyboardChildEnvironment, let pagerEnvironment = self.pagerEnvironment else {
|
||||
return
|
||||
}
|
||||
|
||||
if let externalBackground = component.inputInteractionHolder.inputInteraction?.externalBackground, let effectContainerView = externalBackground.effectContainerView {
|
||||
if let effectContainerView = externalTintMaskContainer {
|
||||
let mirrorContentClippingView: UIView
|
||||
if let current = self.mirrorContentClippingView {
|
||||
mirrorContentClippingView = current
|
||||
@ -4066,17 +4075,19 @@ public final class EmojiPagerContentComponent: Component {
|
||||
if component.hideBackground {
|
||||
self.backgroundView.isHidden = true
|
||||
|
||||
let maskLayer: FadingMaskLayer
|
||||
if let current = self.fadingMaskLayer {
|
||||
maskLayer = current
|
||||
} else {
|
||||
maskLayer = FadingMaskLayer()
|
||||
self.fadingMaskLayer = maskLayer
|
||||
if component.maskEdge {
|
||||
let maskLayer: FadingMaskLayer
|
||||
if let current = self.fadingMaskLayer {
|
||||
maskLayer = current
|
||||
} else {
|
||||
maskLayer = FadingMaskLayer()
|
||||
self.fadingMaskLayer = maskLayer
|
||||
}
|
||||
if self.layer.mask == nil {
|
||||
self.layer.mask = maskLayer
|
||||
}
|
||||
maskLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: floorToScreenPixels((topPanelHeight - 34.0) * 0.75)), size: backgroundFrame.size)
|
||||
}
|
||||
if self.layer.mask == nil {
|
||||
self.layer.mask = maskLayer
|
||||
}
|
||||
maskLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: floorToScreenPixels((topPanelHeight - 34.0) * 0.75)), size: backgroundFrame.size)
|
||||
} else if component.warpContentsOnEdges {
|
||||
self.backgroundView.isHidden = true
|
||||
} else {
|
||||
|
||||
@ -65,7 +65,8 @@ public extension EmojiPagerContentComponent {
|
||||
hasRecent: Bool = true,
|
||||
forceHasPremium: Bool = false,
|
||||
premiumIfSavedMessages: Bool = true,
|
||||
hideBackground: Bool = false
|
||||
hideBackground: Bool = false,
|
||||
maskEdge: Bool = false
|
||||
) -> Signal<EmojiPagerContentComponent, NoError> {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let isPremiumDisabled = premiumConfiguration.isPremiumDisabled
|
||||
@ -1596,6 +1597,7 @@ public extension EmojiPagerContentComponent {
|
||||
searchState: .empty(hasResults: false),
|
||||
warpContentsOnEdges: warpContentsOnEdges,
|
||||
hideBackground: hideBackground,
|
||||
maskEdge: maskEdge,
|
||||
displaySearchWithPlaceholder: displaySearchWithPlaceholder,
|
||||
searchCategories: searchCategories,
|
||||
searchInitiallyHidden: searchInitiallyHidden,
|
||||
@ -1632,7 +1634,8 @@ public extension EmojiPagerContentComponent {
|
||||
hasAdd: Bool = false,
|
||||
searchIsPlaceholderOnly: Bool = true,
|
||||
subject: StickersSubject = .chatStickers,
|
||||
hideBackground: Bool = false
|
||||
hideBackground: Bool = false,
|
||||
maskEdge: Bool = false
|
||||
) -> Signal<EmojiPagerContentComponent, NoError> {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let isPremiumDisabled = premiumConfiguration.isPremiumDisabled
|
||||
@ -2178,6 +2181,7 @@ public extension EmojiPagerContentComponent {
|
||||
searchState: .empty(hasResults: false),
|
||||
warpContentsOnEdges: warpContentsOnEdges,
|
||||
hideBackground: hideBackground,
|
||||
maskEdge: maskEdge,
|
||||
displaySearchWithPlaceholder: hasSearch ? strings.StickersSearch_SearchStickersPlaceholder : nil,
|
||||
searchCategories: searchCategories,
|
||||
searchInitiallyHidden: true,
|
||||
@ -2197,7 +2201,8 @@ public extension EmojiPagerContentComponent {
|
||||
animationCache: AnimationCache,
|
||||
animationRenderer: MultiAnimationRenderer,
|
||||
hasSearch: Bool,
|
||||
hideBackground: Bool = false
|
||||
hideBackground: Bool = false,
|
||||
maskEdge: Bool = false
|
||||
) -> Signal<EmojiPagerContentComponent, NoError> {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let isPremiumDisabled = premiumConfiguration.isPremiumDisabled
|
||||
@ -2330,6 +2335,7 @@ public extension EmojiPagerContentComponent {
|
||||
searchState: .empty(hasResults: false),
|
||||
warpContentsOnEdges: warpContentsOnEdges,
|
||||
hideBackground: hideBackground,
|
||||
maskEdge: maskEdge,
|
||||
displaySearchWithPlaceholder: hasSearch ? strings.StickersSearch_SearchStickersPlaceholder : nil,
|
||||
searchCategories: searchCategories,
|
||||
searchInitiallyHidden: true,
|
||||
|
||||
@ -469,6 +469,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
||||
searchState: .empty(hasResults: false),
|
||||
warpContentsOnEdges: false,
|
||||
hideBackground: false,
|
||||
maskEdge: false,
|
||||
displaySearchWithPlaceholder: self.presentationData.strings.EmojiSearch_SearchEmojiPlaceholder,
|
||||
searchCategories: nil,
|
||||
searchInitiallyHidden: false,
|
||||
@ -509,6 +510,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -106,6 +106,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
public let defaultToEmojiTab: Bool
|
||||
public let externalTopPanelContainer: PagerExternalTopPanelContainer?
|
||||
public let externalBottomPanelContainer: PagerExternalTopPanelContainer?
|
||||
public let externalTintMaskContainer: UIView?
|
||||
public let displayTopPanelBackground: DisplayTopPanelBackground
|
||||
public let topPanelExtensionUpdated: (CGFloat, ComponentTransition) -> Void
|
||||
public let topPanelScrollingOffset: (CGFloat, ComponentTransition) -> Void
|
||||
@ -141,6 +142,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
defaultToEmojiTab: Bool,
|
||||
externalTopPanelContainer: PagerExternalTopPanelContainer?,
|
||||
externalBottomPanelContainer: PagerExternalTopPanelContainer?,
|
||||
externalTintMaskContainer: UIView?,
|
||||
displayTopPanelBackground: DisplayTopPanelBackground,
|
||||
topPanelExtensionUpdated: @escaping (CGFloat, ComponentTransition) -> Void,
|
||||
topPanelScrollingOffset: @escaping (CGFloat, ComponentTransition) -> Void,
|
||||
@ -175,6 +177,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
self.defaultToEmojiTab = defaultToEmojiTab
|
||||
self.externalTopPanelContainer = externalTopPanelContainer
|
||||
self.externalBottomPanelContainer = externalBottomPanelContainer
|
||||
self.externalTintMaskContainer = externalTintMaskContainer
|
||||
self.displayTopPanelBackground = displayTopPanelBackground
|
||||
self.topPanelExtensionUpdated = topPanelExtensionUpdated
|
||||
self.topPanelScrollingOffset = topPanelScrollingOffset
|
||||
@ -716,6 +719,12 @@ public final class EntityKeyboardComponent: Component {
|
||||
forceUpdate = true
|
||||
}
|
||||
|
||||
var bottomPanelContainerInsets = component.containerInsets
|
||||
if bottomPanelContainerInsets.left == 0.0 && bottomPanelContainerInsets.bottom != 0.0 {
|
||||
bottomPanelContainerInsets.left += 16.0
|
||||
bottomPanelContainerInsets.right += 16.0
|
||||
}
|
||||
|
||||
let isContentInFocus = component.isContentInFocus && self.searchComponent == nil
|
||||
let pagerSize = self.pagerView.update(
|
||||
transition: transition,
|
||||
@ -732,19 +741,20 @@ public final class EntityKeyboardComponent: Component {
|
||||
topPanel: AnyComponent(EntityKeyboardTopContainerPanelComponent(
|
||||
theme: component.theme,
|
||||
overflowHeight: component.hiddenInputHeight,
|
||||
topInset: 12.0,
|
||||
topInset: 6.0,
|
||||
displayBackground: component.externalTopPanelContainer != nil ? .none : component.displayTopPanelBackground
|
||||
)),
|
||||
externalTopPanelContainer: component.externalTopPanelContainer,
|
||||
bottomPanel: component.displayBottomPanel ? AnyComponent(EntityKeyboardBottomPanelComponent(
|
||||
theme: component.theme,
|
||||
containerInsets: component.containerInsets,
|
||||
containerInsets: bottomPanelContainerInsets,
|
||||
deleteBackwards: { [weak self] in
|
||||
self?.component?.emojiContent?.inputInteractionHolder.inputInteraction?.deleteBackwards?()
|
||||
AudioServicesPlaySystemSound(0x451)
|
||||
}
|
||||
)) : nil,
|
||||
externalBottomPanelContainer: component.externalBottomPanelContainer,
|
||||
externalTintMaskContainer: component.externalTintMaskContainer,
|
||||
panelStateUpdated: { [weak self] panelState, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
||||
@ -163,7 +163,7 @@ final class EntityKeyboardBottomPanelComponent: Component {
|
||||
private var component: EntityKeyboardBottomPanelComponent?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.backgroundView = BlurredBackgroundView(color: .clear, enableBlur: true)
|
||||
self.backgroundView = BlurredBackgroundView(color: .clear, enableBlur: true, customBlurRadius: 5.0)
|
||||
|
||||
self.separatorView = UIView()
|
||||
self.separatorView.isUserInteractionEnabled = false
|
||||
@ -186,8 +186,8 @@ final class EntityKeyboardBottomPanelComponent: Component {
|
||||
|
||||
func update(component: EntityKeyboardBottomPanelComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
if self.component?.theme !== component.theme {
|
||||
self.separatorView.backgroundColor = component.theme.chat.inputMediaPanel.panelSeparatorColor
|
||||
self.backgroundView.updateColor(color: component.theme.chat.inputPanel.panelBackgroundColor.withMultipliedAlpha(1.0), transition: .immediate)
|
||||
self.separatorView.backgroundColor = component.theme.chat.inputPanel.panelSeparatorColor
|
||||
self.backgroundView.updateColor(color: component.theme.chat.inputPanel.panelBackgroundColor.withMultipliedAlpha(0.65), transition: .immediate)
|
||||
self.highlightedIconBackgroundView.backgroundColor = component.theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor
|
||||
}
|
||||
|
||||
|
||||
@ -206,7 +206,8 @@ final class EntityKeyboardTopContainerPanelComponent: Component {
|
||||
if let current = self.backgroundView {
|
||||
backgroundView = current
|
||||
} else {
|
||||
backgroundView = BlurredBackgroundView(color: .clear, enableBlur: true)
|
||||
backgroundView = BlurredBackgroundView(color: .clear, enableBlur: true, customBlurRadius: 5.0)
|
||||
self.backgroundView = backgroundView
|
||||
self.insertSubview(backgroundView, at: 0)
|
||||
}
|
||||
|
||||
@ -218,12 +219,12 @@ final class EntityKeyboardTopContainerPanelComponent: Component {
|
||||
self.insertSubview(backgroundSeparatorView, aboveSubview: backgroundView)
|
||||
}
|
||||
|
||||
backgroundView.updateColor(color: component.theme.chat.inputPanel.panelBackgroundColor.withMultipliedAlpha(1.0), transition: .immediate)
|
||||
backgroundView.update(size: CGSize(width: availableSize.width, height: height), transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: backgroundView, frame: CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: height)))
|
||||
backgroundView.updateColor(color: component.theme.chat.inputPanel.panelBackgroundColor.withMultipliedAlpha(0.65), transition: .immediate)
|
||||
backgroundView.update(size: CGSize(width: availableSize.width, height: height + component.overflowHeight), transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: backgroundView, frame: CGRect(origin: CGPoint(x: 0.0, y: -component.overflowHeight), size: CGSize(width: availableSize.width, height: height + component.overflowHeight)))
|
||||
|
||||
backgroundSeparatorView.backgroundColor = component.theme.chat.inputPanel.panelSeparatorColor
|
||||
transition.setFrame(view: backgroundSeparatorView, frame: CGRect(origin: CGPoint(x: 0.0, y: height), size: CGSize(width: availableSize.width, height: UIScreenPixel)))
|
||||
transition.setFrame(view: backgroundSeparatorView, frame: CGRect(origin: CGPoint(x: 0.0, y: height - UIScreenPixel), size: CGSize(width: availableSize.width, height: UIScreenPixel)))
|
||||
} else if case .none = component.displayBackground {
|
||||
self.backgroundColor = nil
|
||||
|
||||
|
||||
@ -876,7 +876,7 @@ public final class GifPagerContentComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
public func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, transition: ComponentTransition) {
|
||||
public func pagerUpdateBackground(backgroundFrame: CGRect, topPanelHeight: CGFloat, externalTintMaskContainer: UIView?, transition: ComponentTransition) {
|
||||
guard let theme = self.theme else {
|
||||
return
|
||||
}
|
||||
@ -912,6 +912,8 @@ public final class GifPagerContentComponent: Component {
|
||||
transition.setFrame(view: self.backgroundView, frame: backgroundFrame)
|
||||
self.backgroundView.update(size: backgroundFrame.size, transition: transition.containedViewLayoutTransition)
|
||||
|
||||
self.backgroundView.isHidden = hideBackground
|
||||
|
||||
if let vibrancyEffectView = self.vibrancyEffectView {
|
||||
transition.setFrame(view: vibrancyEffectView, frame: CGRect(origin: CGPoint(x: 0.0, y: -backgroundFrame.minY), size: CGSize(width: backgroundFrame.width, height: backgroundFrame.height + backgroundFrame.minY)))
|
||||
}
|
||||
|
||||
@ -350,6 +350,7 @@ private final class TopicIconSelectionComponent: Component {
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -4,86 +4,6 @@ import Display
|
||||
import ComponentFlow
|
||||
import ComponentDisplayAdapters
|
||||
|
||||
private func generateForegroundImage(size: CGSize, isDark: Bool, fillColor: UIColor) -> UIImage {
|
||||
var size = size
|
||||
if size == .zero {
|
||||
size = CGSize(width: 1.0, height: 1.0)
|
||||
}
|
||||
|
||||
return generateImage(size, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let maxColor = UIColor(white: 1.0, alpha: isDark ? 0.67 : 0.9)
|
||||
let minColor = UIColor(white: 1.0, alpha: 0.0)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let lineWidth: CGFloat = isDark ? 0.66 : 0.66
|
||||
|
||||
context.saveGState()
|
||||
|
||||
let darkShadeColor = UIColor(white: isDark ? 1.0 : 0.0, alpha: 0.035)
|
||||
let lightShadeColor = UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.035)
|
||||
let innerShadowBlur: CGFloat = 24.0
|
||||
|
||||
context.resetClip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.clip()
|
||||
context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.setShadow(offset: CGSize(width: 10.0, height: -10.0), blur: innerShadowBlur, color: darkShadeColor.cgColor)
|
||||
context.fillPath(using: .evenOdd)
|
||||
|
||||
context.resetClip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.clip()
|
||||
context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.setShadow(offset: CGSize(width: -10.0, height: 10.0), blur: innerShadowBlur, color: lightShadeColor.cgColor)
|
||||
context.fillPath(using: .evenOdd)
|
||||
|
||||
context.restoreGState()
|
||||
|
||||
context.setLineWidth(lineWidth)
|
||||
|
||||
context.addRect(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
|
||||
context.clip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.replacePathWithStrokedPath()
|
||||
context.clip()
|
||||
|
||||
do {
|
||||
var locations: [CGFloat] = [0.0, 0.5, 0.5 + 0.2, 1.0 - 0.1, 1.0]
|
||||
let colors: [CGColor] = [maxColor.cgColor, maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor]
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
}
|
||||
|
||||
context.resetClip()
|
||||
context.addRect(CGRect(origin: CGPoint(x: size.width - size.width * 0.5, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
|
||||
context.clip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.replacePathWithStrokedPath()
|
||||
context.clip()
|
||||
|
||||
do {
|
||||
var locations: [CGFloat] = [0.0, 0.1, 0.5 - 0.2, 0.5, 1.0]
|
||||
let colors: [CGColor] = [maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor, maxColor.cgColor]
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
}
|
||||
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}
|
||||
|
||||
private final class ContentContainer: UIView {
|
||||
private let maskContentView: UIView
|
||||
|
||||
@ -345,7 +265,6 @@ public final class GlassBackgroundView: UIView {
|
||||
|
||||
private let foregroundView: UIImageView?
|
||||
private let shadowView: UIImageView?
|
||||
private let shadowMaskView: UIImageView?
|
||||
|
||||
public let maskContentView: UIView
|
||||
private let contentContainer: ContentContainer
|
||||
@ -371,14 +290,12 @@ public final class GlassBackgroundView: UIView {
|
||||
nativeView.traitOverrides.userInterfaceStyle = .light
|
||||
//self.foregroundView = UIImageView()
|
||||
self.foregroundView = nil
|
||||
self.shadowView = nil
|
||||
self.shadowMaskView = nil
|
||||
self.shadowView = UIImageView()
|
||||
} else {
|
||||
self.backgroundNode = NavigationBackgroundNode(color: .black, enableBlur: true, customBlurRadius: 5.0)
|
||||
self.nativeView = nil
|
||||
self.foregroundView = UIImageView()
|
||||
self.shadowView = UIImageView()
|
||||
self.shadowMaskView = UIImageView()
|
||||
}
|
||||
|
||||
self.maskContentView = UIView()
|
||||
@ -393,9 +310,6 @@ public final class GlassBackgroundView: UIView {
|
||||
|
||||
if let shadowView = self.shadowView {
|
||||
self.addSubview(shadowView)
|
||||
if let shadowMaskView = self.shadowMaskView {
|
||||
shadowView.mask = shadowMaskView
|
||||
}
|
||||
}
|
||||
if let nativeView = self.nativeView {
|
||||
self.addSubview(nativeView)
|
||||
@ -435,39 +349,36 @@ public final class GlassBackgroundView: UIView {
|
||||
transition.setFrame(view: backgroundNode.view, frame: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
|
||||
let shadowInset: CGFloat = 32.0
|
||||
|
||||
let params = Params(cornerRadius: cornerRadius, isDark: isDark, tintColor: tintColor)
|
||||
if self.params != params {
|
||||
self.params = params
|
||||
|
||||
if let shadowView = self.shadowView {
|
||||
shadowView.layer.shadowRadius = 10.0
|
||||
shadowView.layer.shadowColor = UIColor(white: 0.0, alpha: 1.0).cgColor
|
||||
shadowView.layer.shadowOpacity = 0.08
|
||||
shadowView.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
||||
|
||||
if let shadowMaskView = self.shadowMaskView {
|
||||
let shadowInset: CGFloat = 32.0
|
||||
let shadowInnerInset: CGFloat = 0.5
|
||||
shadowMaskView.image = generateImage(CGSize(width: shadowInset * 2.0 + cornerRadius * 2.0, height: shadowInset * 2.0 + cornerRadius * 2.0), rotatedContext: { size, context in
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
context.setBlendMode(.copy)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: shadowInset + shadowInnerInset, y: shadowInset + shadowInnerInset), size: CGSize(width: size.width - shadowInset * 2.0 - shadowInnerInset * 2.0, height: size.height - shadowInset * 2.0 - shadowInnerInset * 2.0)))
|
||||
})?.stretchableImage(withLeftCapWidth: Int(shadowInset + cornerRadius), topCapHeight: Int(shadowInset + cornerRadius))
|
||||
}
|
||||
let shadowInnerInset: CGFloat = 0.5
|
||||
shadowView.image = generateImage(CGSize(width: shadowInset * 2.0 + cornerRadius * 2.0, height: shadowInset * 2.0 + cornerRadius * 2.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.setShadow(offset: CGSize(width: 0.0, height: 1.0), blur: 30.0, color: UIColor(white: 0.0, alpha: 0.08).cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: shadowInset + shadowInnerInset, y: shadowInset + shadowInnerInset), size: CGSize(width: size.width - shadowInset * 2.0 - shadowInnerInset * 2.0, height: size.height - shadowInset * 2.0 - shadowInnerInset * 2.0)))
|
||||
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
context.setBlendMode(.copy)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: shadowInset + shadowInnerInset, y: shadowInset + shadowInnerInset), size: CGSize(width: size.width - shadowInset * 2.0 - shadowInnerInset * 2.0, height: size.height - shadowInset * 2.0 - shadowInnerInset * 2.0)))
|
||||
})?.stretchableImage(withLeftCapWidth: Int(shadowInset + cornerRadius), topCapHeight: Int(shadowInset + cornerRadius))
|
||||
}
|
||||
|
||||
if let foregroundView = self.foregroundView {
|
||||
foregroundView.image = generateForegroundImage(size: CGSize(width: cornerRadius * 2.0, height: cornerRadius * 2.0), isDark: isDark, fillColor: tintColor.color)
|
||||
foregroundView.image = GlassBackgroundView.generateForegroundImage(size: CGSize(width: cornerRadius * 2.0, height: cornerRadius * 2.0), isDark: isDark, fillColor: tintColor.color)
|
||||
} else {
|
||||
if let nativeView {
|
||||
if #available(iOS 26.0, *) {
|
||||
let glassEffect = UIGlassEffect(style: .regular)
|
||||
let glassEffect = UIGlassEffect(style: .clear)
|
||||
switch tintColor.kind {
|
||||
case .panel:
|
||||
glassEffect.tintColor = nil
|
||||
glassEffect.tintColor = tintColor.color
|
||||
case .custom:
|
||||
glassEffect.tintColor = tintColor.color
|
||||
}
|
||||
@ -484,14 +395,7 @@ public final class GlassBackgroundView: UIView {
|
||||
transition.setFrame(view: foregroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
if let shadowView = self.shadowView {
|
||||
if shadowView.bounds.size != size {
|
||||
shadowView.layer.shadowPath = UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: size), cornerRadius: size.height * 0.5).cgPath
|
||||
}
|
||||
transition.setFrame(view: shadowView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
if let shadowMaskView = self.shadowMaskView {
|
||||
transition.setFrame(view: shadowMaskView, frame: CGRect(origin: CGPoint(), size: size).insetBy(dx: -32.0, dy: -32.0))
|
||||
}
|
||||
transition.setFrame(view: shadowView, frame: CGRect(origin: CGPoint(), size: size).insetBy(dx: -shadowInset, dy: -shadowInset))
|
||||
}
|
||||
transition.setFrame(view: self.contentContainer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
@ -585,3 +489,85 @@ public final class VariableBlurView: UIVisualEffectView {
|
||||
backdropLayer?.filters = [variableBlur]
|
||||
}
|
||||
}
|
||||
|
||||
public extension GlassBackgroundView {
|
||||
static func generateForegroundImage(size: CGSize, isDark: Bool, fillColor: UIColor) -> UIImage {
|
||||
var size = size
|
||||
if size == .zero {
|
||||
size = CGSize(width: 1.0, height: 1.0)
|
||||
}
|
||||
|
||||
return generateImage(size, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let maxColor = UIColor(white: 1.0, alpha: isDark ? 0.25 : 0.9)
|
||||
let minColor = UIColor(white: 1.0, alpha: 0.0)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let lineWidth: CGFloat = isDark ? 0.66 : 0.66
|
||||
|
||||
context.saveGState()
|
||||
|
||||
let darkShadeColor = UIColor(white: isDark ? 1.0 : 0.0, alpha: 0.035)
|
||||
let lightShadeColor = UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.035)
|
||||
let innerShadowBlur: CGFloat = 24.0
|
||||
|
||||
context.resetClip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.clip()
|
||||
context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.setShadow(offset: CGSize(width: 10.0, height: -10.0), blur: innerShadowBlur, color: darkShadeColor.cgColor)
|
||||
context.fillPath(using: .evenOdd)
|
||||
|
||||
context.resetClip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.clip()
|
||||
context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.setShadow(offset: CGSize(width: -10.0, height: 10.0), blur: innerShadowBlur, color: lightShadeColor.cgColor)
|
||||
context.fillPath(using: .evenOdd)
|
||||
|
||||
context.restoreGState()
|
||||
|
||||
context.setLineWidth(lineWidth)
|
||||
|
||||
context.addRect(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
|
||||
context.clip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.replacePathWithStrokedPath()
|
||||
context.clip()
|
||||
|
||||
do {
|
||||
var locations: [CGFloat] = [0.0, 0.5, 0.5 + 0.2, 1.0 - 0.1, 1.0]
|
||||
let colors: [CGColor] = [maxColor.cgColor, maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor]
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
}
|
||||
|
||||
context.resetClip()
|
||||
context.addRect(CGRect(origin: CGPoint(x: size.width - size.width * 0.5, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
|
||||
context.clip()
|
||||
context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
|
||||
context.replacePathWithStrokedPath()
|
||||
context.clip()
|
||||
|
||||
do {
|
||||
var locations: [CGFloat] = [0.0, 0.1, 0.5 - 0.2, 0.5, 1.0]
|
||||
let colors: [CGColor] = [maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor, maxColor.cgColor]
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
}
|
||||
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,6 +407,7 @@ final class MediaEditorScreenComponent: Component {
|
||||
areCustomEmojiEnabled: true,
|
||||
hasSearch: true,
|
||||
hideBackground: true,
|
||||
maskEdge: true,
|
||||
sendGif: nil
|
||||
) |> map { inputData -> ChatEntityKeyboardInputNode.InputData in
|
||||
return ChatEntityKeyboardInputNode.InputData(
|
||||
|
||||
@ -257,6 +257,7 @@ public final class EmojiSelectionComponent: Component {
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -335,6 +335,7 @@ private final class EmojiSelectionComponent: Component {
|
||||
defaultToEmojiTab: true,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in },
|
||||
topPanelScrollingOffset: { _, _ in },
|
||||
|
||||
@ -283,6 +283,7 @@ private final class StickerSelectionComponent: Component {
|
||||
defaultToEmojiTab: defaultToEmoji,
|
||||
externalTopPanelContainer: self.panelHostView,
|
||||
externalBottomPanelContainer: nil,
|
||||
externalTintMaskContainer: nil,
|
||||
displayTopPanelBackground: .blur,
|
||||
topPanelExtensionUpdated: { _, _ in
|
||||
},
|
||||
|
||||
@ -1768,9 +1768,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
if let inputNode = inputNode as? ChatEntityKeyboardInputNode {
|
||||
inputNode.externalTopPanelContainerImpl = nil
|
||||
}
|
||||
inputNode.clipsToBounds = true
|
||||
inputNode.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
inputNode.layer.cornerRadius = 30.0
|
||||
|
||||
dismissedInputNode = self.inputNode
|
||||
dismissedInputNodeExternalTopPanelContainer = self.inputNode?.externalTopPanelContainer
|
||||
@ -2158,11 +2155,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
if self.dismissedAsOverlay {
|
||||
inputPanelFrame!.origin.y = layout.size.height
|
||||
}
|
||||
if let inputNode = self.inputNode, inputNode.hideInput, !inputNode.adjustLayoutForHiddenInput {
|
||||
inputPanelsHeight += inputPanelNodeBaseHeight
|
||||
} else {
|
||||
inputPanelsHeight += inputPanelSize!.height
|
||||
}
|
||||
inputPanelsHeight += inputPanelSize!.height
|
||||
}
|
||||
|
||||
if self.secondaryInputPanelNode != nil {
|
||||
@ -3942,6 +3935,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
chatPeerId: self.chatLocation.peerId,
|
||||
areCustomEmojiEnabled: self.chatPresentationInterfaceState.customEmojiAvailable,
|
||||
hasEdit: true,
|
||||
hideBackground: true,
|
||||
sendGif: { [weak self] fileReference, sourceView, sourceRect, silentPosting, schedule in
|
||||
if let self {
|
||||
return self.controllerInteraction.sendGif(fileReference, sourceView, sourceRect, silentPosting, schedule)
|
||||
@ -4235,15 +4229,20 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
}
|
||||
|
||||
var maybeDismissOverlayContent = true
|
||||
if let inputNode = self.inputNode, inputNode.bounds.contains(self.view.convert(point, to: inputNode.view)) {
|
||||
if let externalTopPanelContainer = inputNode.externalTopPanelContainer {
|
||||
if externalTopPanelContainer.hitTest(self.view.convert(point, to: externalTopPanelContainer), with: nil) != nil {
|
||||
maybeDismissOverlayContent = true
|
||||
if let inputNode = self.inputNode {
|
||||
if let result = inputNode.view.hitTest(self.view.convert(point, to: inputNode.view), with: event) {
|
||||
return result
|
||||
}
|
||||
if inputNode.bounds.contains(self.view.convert(point, to: inputNode.view)) {
|
||||
if let externalTopPanelContainer = inputNode.externalTopPanelContainer {
|
||||
if externalTopPanelContainer.hitTest(self.view.convert(point, to: externalTopPanelContainer), with: nil) != nil {
|
||||
maybeDismissOverlayContent = true
|
||||
} else {
|
||||
maybeDismissOverlayContent = false
|
||||
}
|
||||
} else {
|
||||
maybeDismissOverlayContent = false
|
||||
}
|
||||
} else {
|
||||
maybeDismissOverlayContent = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ class ChatHistoryNavigationButtonNode: ContextControllerSourceNode {
|
||||
|
||||
self.buttonNode.view.addSubview(self.backgroundView)
|
||||
self.backgroundView.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.backgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: .immediate)
|
||||
self.backgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate)
|
||||
self.imageView.tintColor = theme.chat.inputPanel.inputControlColor
|
||||
|
||||
self.backgroundView.contentView.addSubview(self.imageView)
|
||||
@ -110,7 +110,7 @@ class ChatHistoryNavigationButtonNode: ContextControllerSourceNode {
|
||||
if self.theme !== theme {
|
||||
self.theme = theme
|
||||
|
||||
self.backgroundView.update(size: self.backgroundView.bounds.size, cornerRadius: self.backgroundView.bounds.size.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.65)), transition: .immediate)
|
||||
self.backgroundView.update(size: self.backgroundView.bounds.size, cornerRadius: self.backgroundView.bounds.size.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate)
|
||||
self.imageView.tintColor = theme.chat.inputPanel.inputControlColor
|
||||
|
||||
switch self.type {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user