2024-05-10 20:57:12 +04:00

135 lines
6.2 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
final class SendButton: HighlightTrackingButton {
private let containerView: UIView
private var backgroundContent: WallpaperBubbleBackgroundNode?
private let backgroundLayer: SimpleLayer
private let iconView: UIImageView
private var activityIndicator: ActivityIndicator?
override init(frame: CGRect) {
self.containerView = UIView()
self.containerView.isUserInteractionEnabled = false
self.backgroundLayer = SimpleLayer()
self.iconView = UIImageView()
self.iconView.isUserInteractionEnabled = false
super.init(frame: frame)
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?,
isLoadingEffectAnimation: Bool,
size: CGSize,
transition: Transition
) {
let innerSize = CGSize(width: 33.0, height: 33.0)
transition.setFrame(view: self.containerView, frame: CGRect(origin: CGPoint(x: floor((size.width - innerSize.width) * 0.5), y: floor((size.height - innerSize.height) * 0.5)), size: innerSize))
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 [.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.list.itemAccentColor.cgColor
transition.setFrame(layer: self.backgroundLayer, frame: CGRect(origin: CGPoint(), size: innerSize))
if self.iconView.image == nil {
self.iconView.image = PresentationResourcesChat.chatInputPanelSendIconImage(presentationData.theme)
}
if let icon = self.iconView.image {
let iconFrame = CGRect(origin: CGPoint(x: floor((innerSize.width - icon.size.width) * 0.5), y: floor((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))
transition.setAlpha(view: self.iconView, alpha: isLoadingEffectAnimation ? 0.0 : 1.0)
transition.setScale(view: self.iconView, scale: isLoadingEffectAnimation ? 0.001 : 1.0)
}
if isLoadingEffectAnimation {
var animateIn = false
let activityIndicator: ActivityIndicator
if let current = self.activityIndicator {
activityIndicator = current
} else {
animateIn = true
activityIndicator = ActivityIndicator(type: .custom(presentationData.theme.list.itemCheckColors.foregroundColor, 18.0, 2.0, 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)
}
}
}