mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
240 lines
10 KiB
Swift
240 lines
10 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import TelegramCore
|
|
import SwiftSignalKit
|
|
import Photos
|
|
import TelegramPresentationData
|
|
import TelegramUIPreferences
|
|
import TelegramStringFormatting
|
|
import AccountContext
|
|
import GalleryUI
|
|
import AppBundle
|
|
|
|
private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: .white)
|
|
private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: .white)
|
|
|
|
private let nameFont = Font.medium(15.0)
|
|
private let dateFont = Font.regular(14.0)
|
|
|
|
enum AvatarGalleryItemFooterContent {
|
|
case info
|
|
case own(Bool)
|
|
}
|
|
|
|
final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
|
|
private let context: AccountContext
|
|
private var presentationData: PresentationData
|
|
private var strings: PresentationStrings
|
|
private var dateTimeFormat: PresentationDateTimeFormat
|
|
|
|
private let deleteButton: UIButton
|
|
private let actionButton: UIButton
|
|
private let nameNode: ASTextNode
|
|
private let dateNode: ASTextNode
|
|
private let mainNode: ASTextNode
|
|
private let setMainButton: HighlightableButtonNode
|
|
|
|
private var currentNameText: String?
|
|
private var currentDateText: String?
|
|
private var currentTypeText: String?
|
|
|
|
private var validLayout: (CGSize, LayoutMetrics, CGFloat, CGFloat, CGFloat, CGFloat)?
|
|
|
|
var delete: (() -> Void)? {
|
|
didSet {
|
|
self.deleteButton.isHidden = self.delete == nil
|
|
}
|
|
}
|
|
|
|
var share: ((GalleryControllerInteraction) -> Void)?
|
|
|
|
var setMain: (() -> Void)?
|
|
|
|
init(context: AccountContext, presentationData: PresentationData) {
|
|
self.context = context
|
|
self.presentationData = presentationData
|
|
self.strings = presentationData.strings
|
|
self.dateTimeFormat = presentationData.dateTimeFormat
|
|
|
|
self.deleteButton = UIButton()
|
|
self.deleteButton.isHidden = true
|
|
|
|
self.actionButton = UIButton()
|
|
|
|
self.deleteButton.setImage(deleteImage, for: [.normal])
|
|
self.actionButton.setImage(actionImage, for: [.normal])
|
|
|
|
self.nameNode = ASTextNode()
|
|
self.nameNode.maximumNumberOfLines = 1
|
|
self.nameNode.isUserInteractionEnabled = false
|
|
self.nameNode.displaysAsynchronously = false
|
|
|
|
self.dateNode = ASTextNode()
|
|
self.dateNode.maximumNumberOfLines = 1
|
|
self.dateNode.isUserInteractionEnabled = false
|
|
self.dateNode.displaysAsynchronously = false
|
|
|
|
self.setMainButton = HighlightableButtonNode()
|
|
self.setMainButton.isHidden = true
|
|
|
|
self.mainNode = ASTextNode()
|
|
self.mainNode.maximumNumberOfLines = 1
|
|
self.mainNode.isUserInteractionEnabled = false
|
|
self.mainNode.displaysAsynchronously = false
|
|
|
|
super.init()
|
|
|
|
self.view.addSubview(self.deleteButton)
|
|
self.view.addSubview(self.actionButton)
|
|
|
|
self.addSubnode(self.nameNode)
|
|
self.addSubnode(self.dateNode)
|
|
self.addSubnode(self.setMainButton)
|
|
self.addSubnode(self.mainNode)
|
|
|
|
self.deleteButton.addTarget(self, action: #selector(self.deleteButtonPressed), for: [.touchUpInside])
|
|
self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), for: [.touchUpInside])
|
|
self.setMainButton.addTarget(self, action: #selector(self.setMainButtonPressed), forControlEvents: .touchUpInside)
|
|
}
|
|
|
|
func setEntry(_ entry: AvatarGalleryEntry, content: AvatarGalleryItemFooterContent) {
|
|
var nameText: String?
|
|
var dateText: String?
|
|
var typeText: String?
|
|
var buttonText: String?
|
|
var canShare = true
|
|
switch entry {
|
|
case let .image(_, _, _, videoRepresentations, peer, date, _, _, _, _, isFallback, _):
|
|
if date != 0 || isFallback {
|
|
nameText = peer?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""
|
|
}
|
|
if let date = date, date != 0 {
|
|
dateText = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: date).string
|
|
} else if isFallback {
|
|
dateText = !videoRepresentations.isEmpty ? self.strings.ProfilePhoto_PublicVideo : self.strings.ProfilePhoto_PublicPhoto
|
|
}
|
|
|
|
if (!videoRepresentations.isEmpty) {
|
|
typeText = self.strings.ProfilePhoto_MainVideo
|
|
buttonText = self.strings.ProfilePhoto_SetMainVideo
|
|
} else {
|
|
typeText = self.strings.ProfilePhoto_MainPhoto
|
|
buttonText = self.strings.ProfilePhoto_SetMainPhoto
|
|
}
|
|
|
|
if let peer = peer {
|
|
canShare = !peer._asPeer().isCopyProtectionEnabled
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
|
|
if self.currentNameText != nameText || self.currentDateText != dateText {
|
|
self.currentNameText = nameText
|
|
self.currentDateText = dateText
|
|
|
|
if let nameText = nameText {
|
|
self.nameNode.attributedText = NSAttributedString(string: nameText, font: nameFont, textColor: .white)
|
|
} else {
|
|
self.nameNode.attributedText = nil
|
|
}
|
|
|
|
if let dateText = dateText {
|
|
self.dateNode.attributedText = NSAttributedString(string: dateText, font: dateFont, textColor: .white)
|
|
} else {
|
|
self.dateNode.attributedText = nil
|
|
}
|
|
}
|
|
|
|
if self.currentTypeText != typeText {
|
|
self.currentTypeText = typeText
|
|
|
|
self.mainNode.attributedText = NSAttributedString(string: typeText ?? "", font: Font.regular(17.0), textColor: UIColor(rgb: 0x808080))
|
|
self.setMainButton.setAttributedTitle(NSAttributedString(string: buttonText ?? "", font: Font.regular(17.0), textColor: .white), for: .normal)
|
|
|
|
if let validLayout = self.validLayout {
|
|
let _ = self.updateLayout(size: validLayout.0, metrics: validLayout.1, leftInset: validLayout.2, rightInset: validLayout.3, bottomInset: validLayout.4, contentInset: validLayout.5, transition: .immediate)
|
|
}
|
|
}
|
|
|
|
self.actionButton.isHidden = !canShare
|
|
|
|
switch content {
|
|
case .info:
|
|
self.nameNode.isHidden = false
|
|
self.dateNode.isHidden = false
|
|
self.mainNode.isHidden = true
|
|
self.setMainButton.isHidden = true
|
|
case let .own(isMainPhoto):
|
|
self.nameNode.isHidden = true
|
|
self.dateNode.isHidden = true
|
|
self.mainNode.isHidden = !isMainPhoto
|
|
self.setMainButton.isHidden = isMainPhoto
|
|
}
|
|
}
|
|
|
|
override func updateLayout(size: CGSize, metrics: LayoutMetrics, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, contentInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
|
|
self.validLayout = (size, metrics, leftInset, rightInset, bottomInset, contentInset)
|
|
|
|
let width = size.width
|
|
var panelHeight: CGFloat = 44.0 + bottomInset
|
|
panelHeight += contentInset
|
|
|
|
self.actionButton.frame = CGRect(origin: CGPoint(x: leftInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
|
self.deleteButton.frame = CGRect(origin: CGPoint(x: width - 44.0 - rightInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
|
|
|
|
let constrainedSize = CGSize(width: width - 44.0 * 2.0 - 8.0 * 2.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude)
|
|
let nameSize = self.nameNode.measure(constrainedSize)
|
|
let dateSize = self.dateNode.measure(constrainedSize)
|
|
|
|
if nameSize.height.isZero {
|
|
self.dateNode.frame = CGRect(origin: CGPoint(x: floor((width - dateSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height) / 2.0)), size: dateSize)
|
|
} else {
|
|
let labelsSpacing: CGFloat = 0.0
|
|
self.nameNode.frame = CGRect(origin: CGPoint(x: floor((width - nameSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height - nameSize.height - labelsSpacing) / 2.0)), size: nameSize)
|
|
self.dateNode.frame = CGRect(origin: CGPoint(x: floor((width - dateSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height - nameSize.height - labelsSpacing) / 2.0) + nameSize.height + labelsSpacing), size: dateSize)
|
|
}
|
|
|
|
let mainSize = self.mainNode.measure(constrainedSize)
|
|
self.mainNode.frame = CGRect(origin: CGPoint(x: floor((width - mainSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - mainSize.height) / 2.0)), size: mainSize)
|
|
|
|
let mainButtonSize = self.setMainButton.measure(constrainedSize)
|
|
self.setMainButton.frame = CGRect(origin: CGPoint(x: floor((width - mainButtonSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - mainButtonSize.height) / 2.0)), size: mainButtonSize)
|
|
|
|
return panelHeight
|
|
}
|
|
|
|
override func animateIn(fromHeight: CGFloat, previousContentNode: GalleryFooterContentNode, transition: ContainedViewLayoutTransition) {
|
|
self.deleteButton.alpha = 1.0
|
|
self.actionButton.alpha = 1.0
|
|
self.nameNode.alpha = 1.0
|
|
self.dateNode.alpha = 1.0
|
|
self.setMainButton.alpha = 1.0
|
|
}
|
|
|
|
override func animateOut(toHeight: CGFloat, nextContentNode: GalleryFooterContentNode, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
|
|
self.deleteButton.alpha = 0.0
|
|
self.actionButton.alpha = 0.0
|
|
self.nameNode.alpha = 0.0
|
|
self.dateNode.alpha = 0.0
|
|
self.setMainButton.alpha = 0.0
|
|
completion()
|
|
}
|
|
|
|
@objc private func deleteButtonPressed() {
|
|
self.delete?()
|
|
}
|
|
|
|
@objc private func actionButtonPressed() {
|
|
if let controllerInteraction = self.controllerInteraction {
|
|
self.share?(controllerInteraction)
|
|
}
|
|
}
|
|
|
|
@objc private func setMainButtonPressed() {
|
|
self.setMain?()
|
|
}
|
|
}
|