mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various Improvements
This commit is contained in:
parent
e5f15bf084
commit
39fad9b0d1
Binary file not shown.
Binary file not shown.
@ -6796,3 +6796,6 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Conversation.ContextMenuSeen_1" = "1 Seen";
|
||||
"Conversation.ContextMenuSeen_any" = "%@ Seen";
|
||||
|
||||
"VideoChat.RecordingSaved" = "Video chat recording saved to **Saved Messages**.";
|
||||
"LiveStream.RecordingSaved" = "Live stream recording saved to **Saved Messages**.";
|
||||
|
@ -703,7 +703,11 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
let maximumNumberOfColors: Int
|
||||
switch self.state.section {
|
||||
case .accent:
|
||||
maximumNumberOfColors = 2
|
||||
if [.classic, .day].contains(self.theme.referenceTheme.baseTheme) {
|
||||
maximumNumberOfColors = 2
|
||||
} else {
|
||||
maximumNumberOfColors = 1
|
||||
}
|
||||
case .background:
|
||||
maximumNumberOfColors = 4
|
||||
case .messages:
|
||||
|
@ -2613,7 +2613,15 @@ public final class VoiceChatController: ViewController {
|
||||
if let strongSelf = self {
|
||||
strongSelf.call.setShouldBeRecording(false, title: nil, videoOrientation: nil)
|
||||
|
||||
strongSelf.presentUndoOverlay(content: .forward(savedMessages: true, text: strongSelf.presentationData.strings.VoiceChat_RecordingSaved), action: { [weak self] value in
|
||||
|
||||
let text: String
|
||||
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
text = strongSelf.presentationData.strings.LiveStream_RecordingSaved
|
||||
} else {
|
||||
text = strongSelf.presentationData.strings.VideoChat_RecordingSaved
|
||||
}
|
||||
|
||||
strongSelf.presentUndoOverlay(content: .forward(savedMessages: true, text: text), action: { [weak self] value in
|
||||
if case .info = value, let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||
let context = strongSelf.context
|
||||
strongSelf.controller?.dismiss(completion: {
|
||||
|
@ -34,18 +34,8 @@ public func customizePresentationTheme(_ theme: PresentationTheme, specialMode:
|
||||
}
|
||||
|
||||
public func makePresentationTheme(settings: TelegramThemeSettings, specialMode: Bool = false, title: String? = nil, serviceBackgroundColor: UIColor? = nil) -> PresentationTheme? {
|
||||
var baseTheme: TelegramBaseTheme = settings.baseTheme
|
||||
var chatWallpaper = settings.wallpaper
|
||||
if specialMode && baseTheme == .tinted {
|
||||
baseTheme = .night
|
||||
|
||||
if let wallpaper = settings.wallpaper {
|
||||
let colors = (wallpaper.settings?.colors ?? []).map { UIColor(rgb: $0).withMultiplied(hue: 1.0, saturation: 1.0, brightness: 2.25).rgb }
|
||||
chatWallpaper = settings.wallpaper?.withUpdatedSettings(WallpaperSettings(blur: wallpaper.settings?.blur ?? false, motion: wallpaper.settings?.blur ?? false, colors: colors, intensity: wallpaper.settings?.intensity.flatMap({ -(max(55, $0)) }), rotation: wallpaper.settings?.rotation))
|
||||
}
|
||||
}
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: baseTheme), extendingThemeReference: nil, serviceBackgroundColor: serviceBackgroundColor, preview: false)
|
||||
return customizePresentationTheme(defaultTheme, specialMode: specialMode, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), outgoingAccentColor: settings.outgoingAccentColor.flatMap { UIColor(argb: $0) }, backgroundColors: [], bubbleColors: settings.messageColors, animateBubbleColors: settings.animateMessageColors, wallpaper: chatWallpaper)
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: settings.baseTheme), extendingThemeReference: nil, serviceBackgroundColor: serviceBackgroundColor, preview: false)
|
||||
return customizePresentationTheme(defaultTheme, specialMode: specialMode, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), outgoingAccentColor: settings.outgoingAccentColor.flatMap { UIColor(argb: $0) }, backgroundColors: [], bubbleColors: settings.messageColors, animateBubbleColors: settings.animateMessageColors, wallpaper: settings.wallpaper)
|
||||
}
|
||||
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, outgoingAccentColor: UIColor? = nil, backgroundColors: [UInt32] = [], bubbleColors: [UInt32] = [], animateBubbleColors: Bool? = nil, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil, serviceBackgroundColor: UIColor? = nil, specialMode: Bool = false, preview: Bool = false) -> PresentationTheme? {
|
||||
|
@ -159,8 +159,11 @@ public enum PresentationResourceKey: Int32 {
|
||||
|
||||
case chatInputTextFieldBackgroundImage
|
||||
case chatInputTextFieldClearImage
|
||||
case chatInputPanelSendIconImage
|
||||
case chatInputPanelSendButtonImage
|
||||
case chatInputPanelApplyIconImage
|
||||
case chatInputPanelApplyButtonImage
|
||||
case chatInputPanelScheduleIconImage
|
||||
case chatInputPanelScheduleButtonImage
|
||||
case chatInputPanelVoiceButtonImage
|
||||
case chatInputPanelVideoButtonImage
|
||||
|
@ -428,6 +428,27 @@ public struct PresentationResourcesChat {
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelSendIconImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelSendIconImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
let color: UIColor
|
||||
if theme.referenceTheme.baseTheme == .night, theme.chat.message.outgoing.bubble.withWallpaper.fill.count > 1 {
|
||||
color = .white
|
||||
} else {
|
||||
color = theme.chat.inputPanel.actionControlForegroundColor
|
||||
}
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setFillColor(color.cgColor)
|
||||
context.setLineWidth(2.0)
|
||||
context.setLineCap(.round)
|
||||
context.setLineJoin(.round)
|
||||
let _ = try? drawSvgPath(context, path: "M11,14.6666667 L16.4310816,9.40016333 L16.4310816,9.40016333 C16.4694824,9.36292619 16.5305176,9.36292619 16.5689184,9.40016333 L22,14.6666667 S ")
|
||||
let _ = try? drawSvgPath(context, path: "M16.5,9.33333333 C17.0522847,9.33333333 17.5,9.78104858 17.5,10.3333333 L17.5,24 C17.5,24.5522847 17.0522847,25 16.5,25 C15.9477153,25 15.5,24.5522847 15.5,24 L15.5,10.3333333 C15.5,9.78104858 15.9477153,9.33333333 16.5,9.33333333 Z ")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelApplyButtonImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelApplyButtonImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
@ -444,6 +465,26 @@ public struct PresentationResourcesChat {
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelApplyIconImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelApplyIconImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
let color: UIColor
|
||||
if theme.referenceTheme.baseTheme == .night, theme.chat.message.outgoing.bubble.withWallpaper.fill.count > 1 {
|
||||
color = .white
|
||||
} else {
|
||||
color = theme.chat.inputPanel.actionControlForegroundColor
|
||||
}
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setFillColor(color.cgColor)
|
||||
context.setLineWidth(2.0)
|
||||
context.setLineCap(.round)
|
||||
context.setLineJoin(.round)
|
||||
let _ = try? drawSvgPath(context, path: "M9.33333333,17.2686567 L14.1849216,22.120245 L14.1849216,22.120245 C14.2235835,22.1589069 14.2862668,22.1589069 14.3249287,22.120245 C14.3261558,22.1190179 14.3273504,22.1177588 14.3285113,22.1164689 L24.3333333,11 S ")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelScheduleButtonImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelScheduleButtonImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
@ -463,6 +504,30 @@ public struct PresentationResourcesChat {
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelScheduleIconImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelScheduleIconImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let imageRect = CGRect(origin: CGPoint(), size: size)
|
||||
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
||||
context.scaleBy(x: 1.0, y: -1.0)
|
||||
context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
|
||||
|
||||
let color: UIColor
|
||||
if theme.referenceTheme.baseTheme == .night, theme.chat.message.outgoing.bubble.withWallpaper.fill.count > 1 {
|
||||
color = .white
|
||||
} else {
|
||||
color = theme.chat.inputPanel.actionControlForegroundColor
|
||||
}
|
||||
|
||||
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/ScheduleIcon"), color: color) {
|
||||
context.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) / 2.0), y: floorToScreenPixels((size.height - image.size.height) / 2.0)), size: image.size))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatInputPanelVoiceButtonImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelVoiceButtonImage.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: theme.chat.inputPanel.panelControlColor)
|
||||
|
@ -417,6 +417,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
private weak var sendMessageActionsController: ChatSendMessageActionSheetController?
|
||||
private var searchResultsController: ChatSearchResultsController?
|
||||
|
||||
private weak var themeSceen: ChatThemeScreen?
|
||||
|
||||
private weak var currentPinchController: PinchController?
|
||||
private weak var currentPinchSourceItemNode: ListViewItemNode?
|
||||
|
||||
@ -3995,6 +3997,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
controllerInteraction.updatedPresentationData = strongSelf.updatedPresentationData
|
||||
strongSelf.presentationDataPromise.set(.single(strongSelf.presentationData))
|
||||
|
||||
if !isFirstTime && previousTheme !== presentationData.theme {
|
||||
strongSelf.presentCrossfadeSnapshot(delay: 0.2)
|
||||
}
|
||||
}
|
||||
strongSelf.presentationReady.set(.single(true))
|
||||
}
|
||||
@ -8009,6 +8015,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.dismissAllTooltips()
|
||||
|
||||
self.sendMessageActionsController?.dismiss()
|
||||
self.themeSceen?.dismiss()
|
||||
|
||||
if let _ = self.peekData {
|
||||
self.peekTimerDisposable.set(nil)
|
||||
@ -13303,13 +13310,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.push(controller)
|
||||
}
|
||||
|
||||
private var crossfading = false
|
||||
private func presentCrossfadeSnapshot(delay: Double) {
|
||||
guard let snapshotView = self.view.snapshotView(afterScreenUpdates: false) else {
|
||||
guard !self.crossfading, let snapshotView = self.view.snapshotView(afterScreenUpdates: false) else {
|
||||
return
|
||||
}
|
||||
self.crossfading = true
|
||||
self.view.addSubview(snapshotView)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: delay, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: delay, removeOnCompletion: false, completion: { [weak self, weak snapshotView] _ in
|
||||
self?.crossfading = false
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
@ -13375,6 +13385,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
strongSelf.themeSceen = controller
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -492,7 +492,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
self.historyNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
||||
|
||||
self.textInputPanelNode = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentController: { [weak self] controller in
|
||||
self.textInputPanelNode = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentationContext: ChatPresentationContext(backgroundNode: backgroundNode), presentController: { [weak self] controller in
|
||||
self?.interfaceInteraction?.presentController(controller, nil)
|
||||
})
|
||||
self.textInputPanelNode?.storedInputLanguage = chatPresentationInterfaceState.interfaceState.inputLanguage
|
||||
@ -1446,9 +1446,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
if inputPanelNodeHandlesTransition {
|
||||
inputPanelNode.updateAbsoluteRect(apparentInputPanelFrame, within: layout.size, transition: .immediate)
|
||||
inputPanelNode.frame = apparentInputPanelFrame
|
||||
inputPanelNode.alpha = 1.0
|
||||
} else {
|
||||
inputPanelNode.updateAbsoluteRect(apparentInputPanelFrame, within: layout.size, transition: transition)
|
||||
transition.updateFrame(node: inputPanelNode, frame: apparentInputPanelFrame)
|
||||
transition.updateAlpha(node: inputPanelNode, alpha: 1.0)
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ class ChatInputPanelNode: ASDisplayNode {
|
||||
var interfaceInteraction: ChatPanelInterfaceInteraction?
|
||||
var prevInputPanelNode: ChatInputPanelNode?
|
||||
|
||||
func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
}
|
||||
|
||||
func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||
return 0.0
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
||||
textInputPanelNode.context = context
|
||||
return (textInputPanelNode, nil)
|
||||
} else {
|
||||
let panel = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentController: { [weak interfaceInteraction] controller in
|
||||
let panel = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentationContext: nil, presentController: { [weak interfaceInteraction] controller in
|
||||
interfaceInteraction?.presentController(controller, nil)
|
||||
})
|
||||
|
||||
|
@ -1308,8 +1308,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self?.additionalAnimationNodes.removeAll(where: { $0 === additionalAnimationNode })
|
||||
additionalAnimationNode?.removeFromSupernode()
|
||||
}
|
||||
additionalAnimationNode.frame = animationNode.frame.insetBy(dx: -animationNode.frame.width, dy: -animationNode.frame.height)
|
||||
var animationFrame = animationNode.frame.insetBy(dx: -animationNode.frame.width, dy: -animationNode.frame.height)
|
||||
.offsetBy(dx: incoming ? animationNode.frame.width - 10.0 : -animationNode.frame.width + 10.0, dy: 0.0)
|
||||
animationFrame = animationFrame.offsetBy(dx: CGFloat.random(in: -30.0 ... 30.0), dy: CGFloat.random(in: -30.0 ... 30.0))
|
||||
additionalAnimationNode.frame = animationFrame
|
||||
if incoming {
|
||||
additionalAnimationNode.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
|
||||
}
|
||||
|
@ -188,13 +188,13 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
func update(rect: CGRect, within containerSize: CGSize) {
|
||||
func update(rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition = .immediate) {
|
||||
self.absolutePosition = (rect, containerSize)
|
||||
if let backgroundContent = self.backgroundContent {
|
||||
var backgroundFrame = backgroundContent.frame
|
||||
backgroundFrame.origin.x += rect.minX
|
||||
backgroundFrame.origin.y += rect.minY
|
||||
backgroundContent.update(rect: backgroundFrame, within: containerSize)
|
||||
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ final class ChatRecentActionsController: TelegramBaseController {
|
||||
return (self.presentationData, self.presentationDataPromise.get())
|
||||
}
|
||||
private var presentationDataDisposable: Disposable?
|
||||
private var didSetPresentationData = false
|
||||
|
||||
private var interaction: ChatRecentActionsInteraction!
|
||||
private var panelInteraction: ChatPanelInterfaceInteraction!
|
||||
@ -185,10 +186,12 @@ final class ChatRecentActionsController: TelegramBaseController {
|
||||
}
|
||||
}
|
||||
|
||||
let isFirstTime = !strongSelf.didSetPresentationData
|
||||
strongSelf.presentationData = presentationData
|
||||
strongSelf.presentationDataPromise.set(.single(presentationData))
|
||||
strongSelf.didSetPresentationData = true
|
||||
|
||||
if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings {
|
||||
if isFirstTime || previousTheme !== presentationData.theme || previousStrings !== presentationData.strings {
|
||||
strongSelf.updateThemeAndStrings()
|
||||
}
|
||||
}
|
||||
|
@ -246,9 +246,9 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
self.contentNodes = contentNodes
|
||||
|
||||
super.init()
|
||||
|
||||
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
||||
self.sendButtonNode.addTarget(self, action: #selector(sendButtonPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
// self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
||||
self.sendButtonNode.addTarget(self, action: #selector(self.sendButtonPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
if let attributedText = textInputNode.attributedText, !attributedText.string.isEmpty {
|
||||
self.fromMessageTextNode.attributedText = attributedText
|
||||
@ -341,6 +341,10 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
|
||||
self.scrollNode.view.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
|
||||
if let snapshotView = self.sourceSendButton.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.sendButtonNode.view.addSubview(snapshotView)
|
||||
}
|
||||
}
|
||||
|
||||
func updatePresentationData(_ presentationData: PresentationData) {
|
||||
@ -361,7 +365,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
self.dimNode.backgroundColor = presentationData.theme.contextMenu.dimColor
|
||||
|
||||
self.contentContainerNode.backgroundColor = self.presentationData.theme.contextMenu.backgroundColor
|
||||
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
||||
// self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
||||
|
||||
if let toAttributedText = self.textInputNode.attributedText?.mutableCopy() as? NSMutableAttributedString {
|
||||
toAttributedText.addAttribute(NSAttributedString.Key.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length))
|
||||
|
@ -2,13 +2,18 @@ import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import ContextUI
|
||||
|
||||
final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
private let presentationContext: ChatPresentationContext?
|
||||
private let strings: PresentationStrings
|
||||
|
||||
let micButton: ChatTextInputMediaRecordingButton
|
||||
let sendContainerNode: ASDisplayNode
|
||||
let backdropNode: ChatMessageBubbleBackdrop
|
||||
let backgroundNode: ASDisplayNode
|
||||
let sendButton: HighlightTrackingButtonNode
|
||||
var sendButtonRadialStatusNode: ChatSendButtonRadialStatusNode?
|
||||
var sendButtonHasApplyIcon = false
|
||||
@ -26,10 +31,21 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
|
||||
var micButtonPointerInteraction: PointerInteraction?
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, presentController: @escaping (ViewController) -> Void) {
|
||||
private var validLayout: CGSize?
|
||||
|
||||
init(presentationInterfaceState: ChatPresentationInterfaceState, presentationContext: ChatPresentationContext?, presentController: @escaping (ViewController) -> Void) {
|
||||
self.presentationContext = presentationContext
|
||||
let theme = presentationInterfaceState.theme
|
||||
let strings = presentationInterfaceState.strings
|
||||
self.strings = strings
|
||||
|
||||
|
||||
self.micButton = ChatTextInputMediaRecordingButton(theme: theme, strings: strings, presentController: presentController)
|
||||
|
||||
self.sendContainerNode = ASDisplayNode()
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.backgroundNode.backgroundColor = theme.chat.inputPanel.actionControlFillColor
|
||||
self.backgroundNode.clipsToBounds = true
|
||||
self.backdropNode = ChatMessageBubbleBackdrop()
|
||||
self.sendButton = HighlightTrackingButtonNode(pointerStyle: .lift)
|
||||
|
||||
self.expandMediaInputButton = HighlightableButtonNode(pointerStyle: .default)
|
||||
@ -43,24 +59,32 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
if let strongSelf = self {
|
||||
if strongSelf.sendButtonHasApplyIcon || !strongSelf.sendButtonLongPressEnabled {
|
||||
if highlighted {
|
||||
strongSelf.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.alpha = 0.4
|
||||
strongSelf.sendContainerNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.sendContainerNode.alpha = 0.4
|
||||
} else {
|
||||
strongSelf.alpha = 1.0
|
||||
strongSelf.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
strongSelf.sendContainerNode.alpha = 1.0
|
||||
strongSelf.sendContainerNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
} else {
|
||||
if highlighted {
|
||||
strongSelf.sendButton.layer.animateScale(from: 1.0, to: 0.75, duration: 0.4, removeOnCompletion: false)
|
||||
strongSelf.sendContainerNode.layer.animateScale(from: 1.0, to: 0.75, duration: 0.4, removeOnCompletion: false)
|
||||
} else if let presentationLayer = strongSelf.sendButton.layer.presentation() {
|
||||
strongSelf.sendButton.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
|
||||
strongSelf.sendContainerNode.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.view.addSubview(self.micButton)
|
||||
self.addSubnode(self.sendButton)
|
||||
|
||||
self.addSubnode(self.sendContainerNode)
|
||||
self.sendContainerNode.addSubnode(self.backgroundNode)
|
||||
if let presentationContext = presentationContext {
|
||||
let graphics = PresentationResourcesChat.principalGraphics(theme: theme, wallpaper: presentationInterfaceState.chatWallpaper, bubbleCorners: presentationInterfaceState.bubbleCorners)
|
||||
self.backdropNode.setType(type: .outgoing(.None), theme: ChatPresentationThemeData(theme: theme, wallpaper: presentationInterfaceState.chatWallpaper), essentialGraphics: graphics, maskMode: true, backgroundNode: presentationContext.backgroundNode)
|
||||
self.backgroundNode.addSubnode(self.backdropNode)
|
||||
}
|
||||
self.sendContainerNode.addSubnode(self.sendButton)
|
||||
self.addSubnode(self.expandMediaInputButton)
|
||||
}
|
||||
|
||||
@ -75,23 +99,51 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
return
|
||||
}
|
||||
if !strongSelf.sendButtonHasApplyIcon {
|
||||
strongSelf.sendButtonLongPressed?(strongSelf.sendButton, recognizer)
|
||||
strongSelf.sendButtonLongPressed?(strongSelf.sendContainerNode, recognizer)
|
||||
}
|
||||
}
|
||||
|
||||
self.micButtonPointerInteraction = PointerInteraction(view: self.micButton, style: .circle)
|
||||
}
|
||||
|
||||
func updateTheme(theme: PresentationTheme) {
|
||||
func updateTheme(theme: PresentationTheme, wallpaper: TelegramWallpaper) {
|
||||
self.micButton.updateTheme(theme: theme)
|
||||
self.expandMediaInputButton.setImage(PresentationResourcesChat.chatInputPanelExpandButtonImage(theme), for: [])
|
||||
|
||||
self.backgroundNode.backgroundColor = theme.chat.inputPanel.actionControlFillColor
|
||||
|
||||
if theme.referenceTheme.baseTheme == .night, theme.chat.message.outgoing.bubble.withWallpaper.fill.count > 1 {
|
||||
self.backdropNode.isHidden = false
|
||||
} else {
|
||||
self.backdropNode.isHidden = true
|
||||
}
|
||||
|
||||
let graphics = PresentationResourcesChat.principalGraphics(theme: theme, wallpaper: wallpaper, bubbleCorners: .init(mainRadius: 1, auxiliaryRadius: 1, mergeBubbleCorners: false))
|
||||
self.backdropNode.setType(type: .outgoing(.None), theme: ChatPresentationThemeData(theme: theme, wallpaper: wallpaper), essentialGraphics: graphics, maskMode: true, backgroundNode: self.presentationContext?.backgroundNode)
|
||||
}
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
self.absoluteRect = (rect, containerSize)
|
||||
self.backdropNode.update(rect: rect, within: containerSize, transition: transition)
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) {
|
||||
self.validLayout = size
|
||||
transition.updateFrame(layer: self.micButton.layer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.micButton.layoutItems()
|
||||
|
||||
transition.updateFrame(layer: self.sendButton.layer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.updateFrame(node: self.sendContainerNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let backgroundSize = CGSize(width: 33.0, height: 33.0)
|
||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - backgroundSize.width) / 2.0), y: floorToScreenPixels((size.height - backgroundSize.height) / 2.0)), size: backgroundSize))
|
||||
self.backgroundNode.cornerRadius = backgroundSize.width / 2.0
|
||||
|
||||
transition.updateFrame(node: self.backdropNode, frame: CGRect(origin: CGPoint(x: -2.0, y: -2.0), size: CGSize(width: size.width + 12.0, height: size.height + 2.0)))
|
||||
if let (rect, containerSize) = self.absoluteRect {
|
||||
self.backdropNode.update(rect: rect, within: containerSize)
|
||||
}
|
||||
|
||||
var isScheduledMessages = false
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
@ -104,12 +156,12 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
sendButtonRadialStatusNode = current
|
||||
} else {
|
||||
sendButtonRadialStatusNode = ChatSendButtonRadialStatusNode(color: interfaceState.theme.chat.inputPanel.panelControlAccentColor)
|
||||
sendButtonRadialStatusNode.alpha = self.sendButton.alpha
|
||||
sendButtonRadialStatusNode.alpha = self.sendContainerNode.alpha
|
||||
self.sendButtonRadialStatusNode = sendButtonRadialStatusNode
|
||||
self.addSubnode(sendButtonRadialStatusNode)
|
||||
}
|
||||
|
||||
transition.updateSublayerTransformScale(layer: self.sendButton.layer, scale: CGPoint(x: 0.7575, y: 0.7575))
|
||||
transition.updateSublayerTransformScale(layer: self.sendContainerNode.layer, scale: CGPoint(x: 0.7575, y: 0.7575))
|
||||
|
||||
let defaultSendButtonSize: CGFloat = 25.0
|
||||
let defaultOriginX = floorToScreenPixels((self.sendButton.bounds.width - defaultSendButtonSize) / 2.0)
|
||||
@ -123,7 +175,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
self.sendButtonRadialStatusNode = nil
|
||||
sendButtonRadialStatusNode.removeFromSupernode()
|
||||
}
|
||||
transition.updateSublayerTransformScale(layer: self.sendButton.layer, scale: CGPoint(x: 1.0, y: 1.0))
|
||||
transition.updateSublayerTransformScale(layer: self.sendContainerNode.layer, scale: CGPoint(x: 1.0, y: 1.0))
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.expandMediaInputButton, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
@ -432,7 +432,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
private let accessoryButtonSpacing: CGFloat = 0.0
|
||||
private let accessoryButtonInset: CGFloat = 2.0
|
||||
|
||||
init(presentationInterfaceState: ChatPresentationInterfaceState, presentController: @escaping (ViewController) -> Void) {
|
||||
init(presentationInterfaceState: ChatPresentationInterfaceState, presentationContext: ChatPresentationContext?, presentController: @escaping (ViewController) -> Void) {
|
||||
self.presentationInterfaceState = presentationInterfaceState
|
||||
|
||||
self.clippingNode = ASDisplayNode()
|
||||
@ -474,7 +474,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.searchLayoutClearImageNode.isUserInteractionEnabled = false
|
||||
self.searchLayoutClearButton.addSubnode(self.searchLayoutClearImageNode)
|
||||
|
||||
self.actionButtons = ChatTextInputActionButtonsNode(theme: presentationInterfaceState.theme, strings: presentationInterfaceState.strings, presentController: presentController)
|
||||
self.actionButtons = ChatTextInputActionButtonsNode(presentationInterfaceState: presentationInterfaceState, presentationContext: presentationContext, presentController: presentController)
|
||||
self.counterTextNode = ImmediateTextNode()
|
||||
self.counterTextNode.textAlignment = .center
|
||||
|
||||
@ -562,7 +562,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
self.actionButtons.sendButton.addTarget(self, action: #selector(self.sendButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.actionButtons.sendButton.alpha = 0.0
|
||||
self.actionButtons.sendContainerNode.alpha = 0.0
|
||||
self.actionButtons.updateAccessibility()
|
||||
|
||||
self.actionButtons.expandMediaInputButton.addTarget(self, action: #selector(self.expandButtonPressed), forControlEvents: .touchUpInside)
|
||||
@ -757,6 +757,15 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return minimalHeight
|
||||
}
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
self.absoluteRect = (rect, containerSize)
|
||||
|
||||
if !self.actionButtons.frame.width.isZero {
|
||||
self.actionButtons.updateAbsoluteRect(CGRect(origin: rect.origin.offsetBy(dx: self.actionButtons.frame.minX, dy: self.actionButtons.frame.minY), size: self.actionButtons.frame.size), within: containerSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||
let previousAdditionalSideInsets = self.validLayout?.3
|
||||
self.validLayout = (width, leftInset, rightInset, additionalSideInsets, maxHeight, metrics, isSecondary)
|
||||
@ -865,7 +874,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.attachmentButton.setImage(PresentationResourcesChat.chatInputPanelAttachmentButtonImage(interfaceState.theme), for: [])
|
||||
}
|
||||
|
||||
self.actionButtons.updateTheme(theme: interfaceState.theme)
|
||||
self.actionButtons.updateTheme(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper)
|
||||
|
||||
let textFieldMinHeight = calclulateTextFieldMinHeight(interfaceState, metrics: metrics)
|
||||
let minimalInputHeight: CGFloat = 2.0 + textFieldMinHeight
|
||||
@ -967,7 +976,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
if !self.actionButtons.animatingSendButton {
|
||||
let imageNode = self.actionButtons.sendButton.imageNode
|
||||
|
||||
if transition.isAnimated && !self.actionButtons.sendButton.alpha.isZero && self.actionButtons.sendButton.layer.animation(forKey: "opacity") == nil, let previousImage = imageNode.image {
|
||||
if transition.isAnimated && !self.actionButtons.sendContainerNode.alpha.isZero && self.actionButtons.sendButton.layer.animation(forKey: "opacity") == nil, let previousImage = imageNode.image {
|
||||
let tempView = UIImageView(image: previousImage)
|
||||
self.actionButtons.sendButton.view.addSubview(tempView)
|
||||
tempView.frame = imageNode.frame
|
||||
@ -981,12 +990,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
self.actionButtons.sendButtonHasApplyIcon = sendButtonHasApplyIcon
|
||||
if self.actionButtons.sendButtonHasApplyIcon {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelApplyButtonImage(interfaceState.theme), for: [])
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelApplyIconImage(interfaceState.theme), for: [])
|
||||
} else {
|
||||
if isScheduledMessages {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelScheduleButtonImage(interfaceState.theme), for: [])
|
||||
} else {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(interfaceState.theme), for: [])
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelSendIconImage(interfaceState.theme), for: [])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1400,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
let actionButtonsFrame = CGRect(origin: CGPoint(x: width - rightInset - 43.0 - UIScreenPixel + composeButtonsOffset, y: panelHeight - minimalHeight), size: CGSize(width: 44.0, height: minimalHeight))
|
||||
transition.updateFrame(node: self.actionButtons, frame: actionButtonsFrame)
|
||||
if let (rect, containerSize) = self.absoluteRect {
|
||||
self.actionButtons.updateAbsoluteRect(CGRect(x: rect.origin.x + actionButtonsFrame.origin.x, y: rect.origin.y + actionButtonsFrame.origin.y, width: actionButtonsFrame.width, height: actionButtonsFrame.height), within: containerSize, transition: transition)
|
||||
}
|
||||
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, interfaceState: presentationInterfaceState)
|
||||
@ -1646,9 +1658,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.menuButton.transform = CATransform3DIdentity
|
||||
self.menuButton.layer.animateScale(from: 0.3, to: 1.0, duration: 0.15, delay: 0, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
prevPreviewInputPanelNode.sendButton.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, removeOnCompletion: false)
|
||||
prevPreviewInputPanelNode.sendButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
var clippingDelta: CGFloat = 0.0
|
||||
@ -1760,23 +1769,22 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
if self.extendedSearchLayout {
|
||||
hideMicButton = true
|
||||
|
||||
if !self.actionButtons.sendButton.alpha.isZero {
|
||||
self.actionButtons.sendButton.alpha = 0.0
|
||||
if !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
self.actionButtons.sendContainerNode.alpha = 0.0
|
||||
self.actionButtons.sendButtonRadialStatusNode?.alpha = 0.0
|
||||
self.actionButtons.updateAccessibility()
|
||||
if animated {
|
||||
self.actionButtons.animatingSendButton = true
|
||||
self.actionButtons.sendButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||
self.actionButtons.sendContainerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actionButtons.animatingSendButton = false
|
||||
strongSelf.applyUpdateSendButtonIcon()
|
||||
}
|
||||
})
|
||||
self.actionButtons.sendButton.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
|
||||
|
||||
self.actionButtons.sendButtonRadialStatusNode?.alpha = 0.0
|
||||
self.actionButtons.sendContainerNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
|
||||
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
|
||||
}
|
||||
}
|
||||
if self.searchLayoutClearButton.alpha.isZero {
|
||||
@ -1799,30 +1807,30 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
if (hasText || self.keepSendButtonEnabled && !mediaInputIsActive) {
|
||||
hideMicButton = true
|
||||
if self.actionButtons.sendButton.alpha.isZero {
|
||||
self.actionButtons.sendButton.alpha = 1.0
|
||||
if self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
self.actionButtons.sendContainerNode.alpha = 1.0
|
||||
self.actionButtons.sendButtonRadialStatusNode?.alpha = 1.0
|
||||
self.actionButtons.updateAccessibility()
|
||||
if animated {
|
||||
self.actionButtons.sendButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
self.actionButtons.sendContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
if animateWithBounce {
|
||||
self.actionButtons.sendButton.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6)
|
||||
self.actionButtons.sendContainerNode.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6)
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6)
|
||||
} else {
|
||||
self.actionButtons.sendButton.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25)
|
||||
self.actionButtons.sendContainerNode.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25)
|
||||
self.actionButtons.sendButtonRadialStatusNode?.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !self.actionButtons.sendButton.alpha.isZero {
|
||||
self.actionButtons.sendButton.alpha = 0.0
|
||||
if !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
self.actionButtons.sendContainerNode.alpha = 0.0
|
||||
self.actionButtons.sendButtonRadialStatusNode?.alpha = 0.0
|
||||
self.actionButtons.updateAccessibility()
|
||||
if animated {
|
||||
self.actionButtons.animatingSendButton = true
|
||||
self.actionButtons.sendButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||
self.actionButtons.sendContainerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actionButtons.animatingSendButton = false
|
||||
strongSelf.applyUpdateSendButtonIcon()
|
||||
@ -1914,7 +1922,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldReturn(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
if self.actionButtons.sendButton.supernode != nil && !self.actionButtons.sendButton.isHidden && !self.actionButtons.sendButton.alpha.isZero {
|
||||
if self.actionButtons.sendButton.supernode != nil && !self.actionButtons.sendButton.isHidden && !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
self.sendButtonPressed()
|
||||
}
|
||||
return false
|
||||
@ -1927,12 +1935,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
if sendButtonHasApplyIcon != self.actionButtons.sendButtonHasApplyIcon {
|
||||
self.actionButtons.sendButtonHasApplyIcon = sendButtonHasApplyIcon
|
||||
if self.actionButtons.sendButtonHasApplyIcon {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelApplyButtonImage(interfaceState.theme), for: [])
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelApplyIconImage(interfaceState.theme), for: [])
|
||||
} else {
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelScheduleButtonImage(interfaceState.theme), for: [])
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelScheduleIconImage(interfaceState.theme), for: [])
|
||||
} else {
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(interfaceState.theme), for: [])
|
||||
self.actionButtons.sendButton.setImage(PresentationResourcesChat.chatInputPanelSendIconImage(interfaceState.theme), for: [])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -855,16 +855,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
if animateBackground, let snapshotView = self.cancelButton.view.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.frame = self.cancelButton.frame
|
||||
self.cancelButton.view.superview?.insertSubview(snapshotView, aboveSubview: self.cancelButton.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: delay, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
self.listNode.forEachVisibleItemNode { node in
|
||||
if let node = node as? ThemeSettingsThemeItemIconNode {
|
||||
node.crossfade()
|
||||
|
@ -1492,6 +1492,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
|
||||
private var presentationData: PresentationData
|
||||
|
||||
fileprivate let cachedDataPromise = Promise<CachedPeerData?>()
|
||||
|
||||
let scrollNode: ASScrollNode
|
||||
|
||||
let headerNode: PeerInfoHeaderNode
|
||||
@ -2849,6 +2851,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
return
|
||||
}
|
||||
strongSelf.updateData(data)
|
||||
strongSelf.cachedDataPromise.set(.single(data.cachedData))
|
||||
})
|
||||
|
||||
if let _ = nearbyPeerDistance {
|
||||
@ -6509,6 +6512,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
||||
|
||||
fileprivate var presentationData: PresentationData
|
||||
private var presentationDataDisposable: Disposable?
|
||||
private let cachedDataPromise = Promise<CachedPeerData?>()
|
||||
|
||||
private let accountsAndPeers = Promise<((AccountContext, Peer)?, [(AccountContext, Peer, Int32)])>()
|
||||
private var accountsAndPeersValue: ((AccountContext, Peer)?, [(AccountContext, Peer, Int32)])?
|
||||
@ -6763,6 +6767,38 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
||||
self?.controllerNode.scrollToTop()
|
||||
}
|
||||
|
||||
let presentationDataSignal: Signal<PresentationData, NoError>
|
||||
if let updatedPresentationData = updatedPresentationData {
|
||||
presentationDataSignal = updatedPresentationData.signal
|
||||
} else {
|
||||
let themeEmoticon: Signal<String?, NoError> = self.cachedDataPromise.get()
|
||||
|> map { cachedData -> String? in
|
||||
if let cachedData = cachedData as? CachedUserData {
|
||||
return cachedData.themeEmoticon
|
||||
} else if let cachedData = cachedData as? CachedGroupData {
|
||||
return cachedData.themeEmoticon
|
||||
} else if let cachedData = cachedData as? CachedChannelData {
|
||||
return cachedData.themeEmoticon
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
presentationDataSignal = combineLatest(queue: Queue.mainQueue(), context.sharedContext.presentationData, context.engine.themes.getChatThemes(accountManager: context.sharedContext.accountManager, onlyCached: false), themeEmoticon)
|
||||
|> map { presentationData, chatThemes, themeEmoticon -> PresentationData in
|
||||
var presentationData = presentationData
|
||||
if let themeEmoticon = themeEmoticon, let theme = chatThemes.first(where: { $0.emoji == themeEmoticon }) {
|
||||
let customTheme = presentationData.theme.overallDarkAppearance ? theme.darkTheme : theme.theme
|
||||
if let settings = customTheme.settings, let theme = makePresentationTheme(settings: settings) {
|
||||
presentationData = presentationData.withUpdated(theme: theme)
|
||||
presentationData = presentationData.withUpdated(chatWallpaper: theme.chat.defaultWallpaper)
|
||||
}
|
||||
}
|
||||
return presentationData
|
||||
}
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
@ -6796,6 +6832,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, callMessages: self.callMessages, isSettings: self.isSettings, ignoreGroupInCommon: self.ignoreGroupInCommon)
|
||||
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
|
||||
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
|
||||
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())
|
||||
self._ready.set(self.controllerNode.ready.get())
|
||||
|
||||
super.displayNodeDidLoad()
|
||||
|
@ -227,7 +227,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel
|
||||
self.textPlaceholderNode.maximumNumberOfLines = 1
|
||||
self.textPlaceholderNode.isUserInteractionEnabled = false
|
||||
|
||||
self.actionButtons = ChatTextInputActionButtonsNode(theme: presentationInterfaceState.theme, strings: presentationInterfaceState.strings, presentController: presentController)
|
||||
self.actionButtons = ChatTextInputActionButtonsNode(presentationInterfaceState: presentationInterfaceState, presentationContext: nil, presentController: presentController)
|
||||
self.counterTextNode = ImmediateTextNode()
|
||||
self.counterTextNode.textAlignment = .center
|
||||
|
||||
@ -439,7 +439,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel
|
||||
|
||||
self.theme = interfaceState.theme
|
||||
|
||||
self.actionButtons.updateTheme(theme: interfaceState.theme)
|
||||
self.actionButtons.updateTheme(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper)
|
||||
|
||||
let textFieldMinHeight = calclulateTextFieldMinHeight(interfaceState, metrics: metrics)
|
||||
let minimalInputHeight: CGFloat = 2.0 + textFieldMinHeight
|
||||
|
Loading…
x
Reference in New Issue
Block a user