mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
206 lines
9.4 KiB
Swift
206 lines
9.4 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import AsyncDisplayKit
|
|
import SwiftSignalKit
|
|
import TelegramPresentationData
|
|
import AccountContext
|
|
import ContextUI
|
|
import TelegramCore
|
|
import TextFormat
|
|
import ReactionSelectionNode
|
|
import ViewControllerComponent
|
|
import ComponentFlow
|
|
import ComponentDisplayAdapters
|
|
import ChatMessageBackground
|
|
import WallpaperBackgroundNode
|
|
import AppBundle
|
|
import ActivityIndicator
|
|
import RadialStatusNode
|
|
|
|
final class SendButton: HighlightTrackingButton {
|
|
enum Kind {
|
|
case send
|
|
case edit
|
|
}
|
|
|
|
private let kind: Kind
|
|
|
|
private let containerView: UIView
|
|
private var backgroundContent: WallpaperBubbleBackgroundNode?
|
|
private let backgroundLayer: SimpleLayer
|
|
private let iconView: UIImageView
|
|
private var activityIndicator: RadialStatusNode?
|
|
|
|
private var previousIsAnimatedIn: Bool?
|
|
private var sourceCustomContentView: UIView?
|
|
|
|
init(kind: Kind) {
|
|
self.kind = kind
|
|
|
|
self.containerView = UIView()
|
|
self.containerView.isUserInteractionEnabled = false
|
|
|
|
self.backgroundLayer = SimpleLayer()
|
|
|
|
self.iconView = UIImageView()
|
|
self.iconView.isUserInteractionEnabled = false
|
|
|
|
super.init(frame: CGRect())
|
|
|
|
self.containerView.clipsToBounds = true
|
|
self.addSubview(self.containerView)
|
|
|
|
self.containerView.layer.addSublayer(self.backgroundLayer)
|
|
self.containerView.addSubview(self.iconView)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func update(
|
|
context: AccountContext,
|
|
presentationData: PresentationData,
|
|
backgroundNode: WallpaperBackgroundNode?,
|
|
sourceSendButton: ASDisplayNode,
|
|
isAnimatedIn: Bool,
|
|
isLoadingEffectAnimation: Bool,
|
|
size: CGSize,
|
|
transition: Transition
|
|
) {
|
|
let innerSize = CGSize(width: size.width - 5.5 * 2.0, height: 33.0)
|
|
let containerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - innerSize.width) * 0.5), y: floorToScreenPixels((size.height - innerSize.height) * 0.5)), size: innerSize)
|
|
transition.setFrame(view: self.containerView, frame: containerFrame)
|
|
transition.setCornerRadius(layer: self.containerView.layer, cornerRadius: innerSize.height * 0.5)
|
|
|
|
if self.window != nil {
|
|
if self.backgroundContent == nil, let backgroundNode = backgroundNode as? WallpaperBackgroundNodeImpl {
|
|
if let backgroundContent = backgroundNode.makeLegacyBubbleBackground(for: .outgoing) {
|
|
self.backgroundContent = backgroundContent
|
|
self.containerView.insertSubview(backgroundContent.view, at: 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
if let backgroundContent = self.backgroundContent {
|
|
transition.setFrame(view: backgroundContent.view, frame: CGRect(origin: CGPoint(), size: innerSize))
|
|
}
|
|
|
|
if backgroundNode != nil && [.day, .night].contains(presentationData.theme.referenceTheme.baseTheme) && !presentationData.theme.chat.message.outgoing.bubble.withWallpaper.hasSingleFillColor {
|
|
self.backgroundContent?.isHidden = false
|
|
self.backgroundLayer.isHidden = true
|
|
} else {
|
|
self.backgroundContent?.isHidden = true
|
|
self.backgroundLayer.isHidden = false
|
|
}
|
|
|
|
self.backgroundLayer.backgroundColor = presentationData.theme.chat.inputPanel.actionControlFillColor.cgColor
|
|
transition.setFrame(layer: self.backgroundLayer, frame: CGRect(origin: CGPoint(), size: innerSize))
|
|
|
|
if self.previousIsAnimatedIn != isAnimatedIn {
|
|
self.previousIsAnimatedIn = isAnimatedIn
|
|
|
|
var sourceCustomContentViewAlpha: CGFloat = 1.0
|
|
if let sourceCustomContentView = self.sourceCustomContentView {
|
|
sourceCustomContentViewAlpha = sourceCustomContentView.alpha
|
|
sourceCustomContentView.removeFromSuperview()
|
|
self.sourceCustomContentView = nil
|
|
}
|
|
|
|
if let sourceSendButton = sourceSendButton as? ChatSendMessageActionSheetControllerSourceSendButtonNode {
|
|
if let sourceCustomContentView = sourceSendButton.makeCustomContents() {
|
|
self.sourceCustomContentView = sourceCustomContentView
|
|
sourceCustomContentView.alpha = sourceCustomContentViewAlpha
|
|
self.addSubview(sourceCustomContentView)
|
|
}
|
|
}
|
|
}
|
|
|
|
if self.iconView.image == nil {
|
|
switch self.kind {
|
|
case .send:
|
|
self.iconView.image = PresentationResourcesChat.chatInputPanelSendIconImage(presentationData.theme)
|
|
case .edit:
|
|
self.iconView.image = PresentationResourcesChat.chatInputPanelApplyIconImage(presentationData.theme)
|
|
}
|
|
}
|
|
|
|
if let sourceCustomContentView = self.sourceCustomContentView {
|
|
var sourceCustomContentTransition = transition
|
|
if sourceCustomContentView.bounds.isEmpty {
|
|
sourceCustomContentTransition = .immediate
|
|
}
|
|
|
|
let sourceCustomContentSize = sourceCustomContentView.bounds.size
|
|
let sourceCustomContentFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((innerSize.width - sourceCustomContentSize.width) * 0.5) + UIScreenPixel, y: floorToScreenPixels((innerSize.height - sourceCustomContentSize.height) * 0.5)), size: sourceCustomContentSize).offsetBy(dx: containerFrame.minX, dy: containerFrame.minY)
|
|
sourceCustomContentTransition.setPosition(view: sourceCustomContentView, position: sourceCustomContentFrame.center)
|
|
sourceCustomContentTransition.setBounds(view: sourceCustomContentView, bounds: CGRect(origin: CGPoint(), size: sourceCustomContentFrame.size))
|
|
sourceCustomContentTransition.setAlpha(view: sourceCustomContentView, alpha: isAnimatedIn ? 0.0 : 1.0)
|
|
}
|
|
|
|
if let icon = self.iconView.image {
|
|
let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((innerSize.width - icon.size.width) * 0.5) - UIScreenPixel, y: floorToScreenPixels((innerSize.height - icon.size.height) * 0.5)), size: icon.size)
|
|
transition.setPosition(view: self.iconView, position: iconFrame.center)
|
|
transition.setBounds(view: self.iconView, bounds: CGRect(origin: CGPoint(), size: iconFrame.size))
|
|
|
|
let iconViewAlpha: CGFloat
|
|
if (self.sourceCustomContentView != nil && !isAnimatedIn) || isLoadingEffectAnimation {
|
|
iconViewAlpha = 0.0
|
|
} else {
|
|
iconViewAlpha = 1.0
|
|
}
|
|
transition.setAlpha(view: self.iconView, alpha: iconViewAlpha)
|
|
transition.setScale(view: self.iconView, scale: isLoadingEffectAnimation ? 0.001 : 1.0)
|
|
}
|
|
|
|
if isLoadingEffectAnimation {
|
|
var animateIn = false
|
|
let activityIndicator: RadialStatusNode
|
|
if let current = self.activityIndicator {
|
|
activityIndicator = current
|
|
} else {
|
|
animateIn = true
|
|
activityIndicator = RadialStatusNode(
|
|
backgroundNodeColor: .clear,
|
|
enableBlur: false,
|
|
isPreview: false
|
|
)
|
|
activityIndicator.transitionToState(.progress(
|
|
color: presentationData.theme.list.itemCheckColors.foregroundColor,
|
|
lineWidth: 2.0,
|
|
value: nil,
|
|
cancelEnabled: false,
|
|
animateRotation: true
|
|
))
|
|
self.activityIndicator = activityIndicator
|
|
self.containerView.addSubview(activityIndicator.view)
|
|
}
|
|
|
|
let activityIndicatorSize = CGSize(width: 18.0, height: 18.0)
|
|
let activityIndicatorFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((innerSize.width - activityIndicatorSize.width) * 0.5), y: floor((innerSize.height - activityIndicatorSize.height) * 0.5) + UIScreenPixel), size: activityIndicatorSize)
|
|
if animateIn {
|
|
activityIndicator.view.frame = activityIndicatorFrame
|
|
transition.animateAlpha(view: activityIndicator.view, from: 0.0, to: 1.0)
|
|
transition.animateScale(view: activityIndicator.view, from: 0.001, to: 1.0)
|
|
} else {
|
|
transition.setFrame(view: activityIndicator.view, frame: activityIndicatorFrame)
|
|
}
|
|
} else {
|
|
if let activityIndicator = self.activityIndicator {
|
|
self.activityIndicator = nil
|
|
transition.setAlpha(view: activityIndicator.view, alpha: 0.0, completion: { [weak activityIndicator] _ in
|
|
activityIndicator?.view.removeFromSuperview()
|
|
})
|
|
transition.setScale(view: activityIndicator.view, scale: 0.001)
|
|
}
|
|
}
|
|
}
|
|
|
|
func updateGlobalRect(rect: CGRect, within containerSize: CGSize, transition: Transition) {
|
|
if let backgroundContent = self.backgroundContent {
|
|
backgroundContent.update(rect: CGRect(origin: CGPoint(x: rect.minX + self.containerView.frame.minX, y: rect.minY + self.containerView.frame.minY), size: backgroundContent.bounds.size), within: containerSize, transition: transition.containedViewLayoutTransition)
|
|
}
|
|
}
|
|
}
|