mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Refactoring
This commit is contained in:
@@ -367,6 +367,8 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode",
|
"//submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode",
|
||||||
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode",
|
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode",
|
||||||
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
|
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentButtonNode",
|
||||||
] + select({
|
] + select({
|
||||||
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
||||||
"//build-system:ios_sim_arm64": [],
|
"//build-system:ios_sim_arm64": [],
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "ChatMessageAttachedContentButtonNode",
|
||||||
|
module_name = "ChatMessageAttachedContentButtonNode",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/AsyncDisplayKit",
|
||||||
|
"//submodules/Display",
|
||||||
|
"//submodules/TelegramPresentationData",
|
||||||
|
"//submodules/ChatPresentationInterfaceState",
|
||||||
|
"//submodules/ShimmerEffect",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import TelegramPresentationData
|
||||||
|
import ChatPresentationInterfaceState
|
||||||
|
import ShimmerEffect
|
||||||
|
|
||||||
|
private let buttonFont = Font.semibold(13.0)
|
||||||
|
|
||||||
|
public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
|
||||||
|
private let textNode: TextNode
|
||||||
|
private let iconNode: ASImageNode
|
||||||
|
private let highlightedTextNode: TextNode
|
||||||
|
private let backgroundNode: ASImageNode
|
||||||
|
private let shimmerEffectNode: ShimmerEffectForegroundNode
|
||||||
|
|
||||||
|
private var regularImage: UIImage?
|
||||||
|
private var highlightedImage: UIImage?
|
||||||
|
private var regularIconImage: UIImage?
|
||||||
|
private var highlightedIconImage: UIImage?
|
||||||
|
|
||||||
|
public var pressed: (() -> Void)?
|
||||||
|
|
||||||
|
private var titleColor: UIColor?
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
self.textNode = TextNode()
|
||||||
|
self.textNode.isUserInteractionEnabled = false
|
||||||
|
self.highlightedTextNode = TextNode()
|
||||||
|
self.highlightedTextNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
self.shimmerEffectNode = ShimmerEffectForegroundNode()
|
||||||
|
self.shimmerEffectNode.cornerRadius = 5.0
|
||||||
|
|
||||||
|
self.backgroundNode = ASImageNode()
|
||||||
|
self.backgroundNode.isLayerBacked = true
|
||||||
|
self.backgroundNode.displayWithoutProcessing = true
|
||||||
|
self.backgroundNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
self.iconNode = ASImageNode()
|
||||||
|
self.iconNode.isLayerBacked = true
|
||||||
|
self.iconNode.displayWithoutProcessing = true
|
||||||
|
self.iconNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.shimmerEffectNode)
|
||||||
|
self.addSubnode(self.backgroundNode)
|
||||||
|
self.addSubnode(self.textNode)
|
||||||
|
self.addSubnode(self.highlightedTextNode)
|
||||||
|
self.highlightedTextNode.isHidden = true
|
||||||
|
|
||||||
|
self.highligthedChanged = { [weak self] highlighted in
|
||||||
|
if let strongSelf = self {
|
||||||
|
if highlighted {
|
||||||
|
strongSelf.backgroundNode.image = strongSelf.highlightedImage
|
||||||
|
strongSelf.iconNode.image = strongSelf.highlightedIconImage
|
||||||
|
strongSelf.textNode.isHidden = true
|
||||||
|
strongSelf.highlightedTextNode.isHidden = false
|
||||||
|
|
||||||
|
let scale = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
||||||
|
strongSelf.layer.animateScale(from: 1.0, to: scale, duration: 0.15, removeOnCompletion: false)
|
||||||
|
} else {
|
||||||
|
if let presentationLayer = strongSelf.layer.presentation() {
|
||||||
|
strongSelf.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
|
||||||
|
}
|
||||||
|
if let snapshot = strongSelf.view.snapshotView(afterScreenUpdates: false) {
|
||||||
|
strongSelf.view.addSubview(snapshot)
|
||||||
|
|
||||||
|
snapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||||
|
snapshot.removeFromSuperview()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.backgroundNode.image = strongSelf.regularImage
|
||||||
|
strongSelf.iconNode.image = strongSelf.regularIconImage
|
||||||
|
strongSelf.textNode.isHidden = false
|
||||||
|
strongSelf.highlightedTextNode.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func buttonPressed() {
|
||||||
|
self.pressed?()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func startShimmering() {
|
||||||
|
guard let titleColor = self.titleColor else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.shimmerEffectNode.isHidden = false
|
||||||
|
self.shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
|
||||||
|
let backgroundFrame = self.backgroundNode.frame
|
||||||
|
self.shimmerEffectNode.frame = backgroundFrame
|
||||||
|
self.shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
|
||||||
|
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: titleColor.withAlphaComponent(0.3), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func stopShimmering() {
|
||||||
|
self.shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||||
|
self?.shimmerEffectNode.isHidden = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func asyncLayout(_ current: ChatMessageAttachedContentButtonNode?) -> (_ width: CGFloat, _ regularImage: UIImage, _ highlightedImage: UIImage, _ iconImage: UIImage?, _ highlightedIconImage: UIImage?, _ cornerIcon: Bool, _ title: String, _ titleColor: UIColor, _ highlightedTitleColor: UIColor, _ inProgress: Bool) -> (CGFloat, (CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode)) {
|
||||||
|
let previousRegularImage = current?.regularImage
|
||||||
|
let previousHighlightedImage = current?.highlightedImage
|
||||||
|
let previousRegularIconImage = current?.regularIconImage
|
||||||
|
let previousHighlightedIconImage = current?.highlightedIconImage
|
||||||
|
|
||||||
|
let maybeMakeTextLayout = (current?.textNode).flatMap(TextNode.asyncLayout)
|
||||||
|
let maybeMakeHighlightedTextLayout = (current?.highlightedTextNode).flatMap(TextNode.asyncLayout)
|
||||||
|
|
||||||
|
return { width, regularImage, highlightedImage, iconImage, highlightedIconImage, cornerIcon, title, titleColor, highlightedTitleColor, inProgress in
|
||||||
|
let targetNode: ChatMessageAttachedContentButtonNode
|
||||||
|
if let current = current {
|
||||||
|
targetNode = current
|
||||||
|
} else {
|
||||||
|
targetNode = ChatMessageAttachedContentButtonNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
let makeTextLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)
|
||||||
|
if let maybeMakeTextLayout = maybeMakeTextLayout {
|
||||||
|
makeTextLayout = maybeMakeTextLayout
|
||||||
|
} else {
|
||||||
|
makeTextLayout = TextNode.asyncLayout(targetNode.textNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
let makeHighlightedTextLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)
|
||||||
|
if let maybeMakeHighlightedTextLayout = maybeMakeHighlightedTextLayout {
|
||||||
|
makeHighlightedTextLayout = maybeMakeHighlightedTextLayout
|
||||||
|
} else {
|
||||||
|
makeHighlightedTextLayout = TextNode.asyncLayout(targetNode.highlightedTextNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedRegularImage: UIImage?
|
||||||
|
if regularImage !== previousRegularImage {
|
||||||
|
updatedRegularImage = regularImage
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedHighlightedImage: UIImage?
|
||||||
|
if highlightedImage !== previousHighlightedImage {
|
||||||
|
updatedHighlightedImage = highlightedImage
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedRegularIconImage: UIImage?
|
||||||
|
if iconImage !== previousRegularIconImage {
|
||||||
|
updatedRegularIconImage = iconImage
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedHighlightedIconImage: UIImage?
|
||||||
|
if highlightedIconImage !== previousHighlightedIconImage {
|
||||||
|
updatedHighlightedIconImage = highlightedIconImage
|
||||||
|
}
|
||||||
|
|
||||||
|
var iconWidth: CGFloat = 0.0
|
||||||
|
if let iconImage = iconImage {
|
||||||
|
iconWidth = iconImage.size.width + 5.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let labelInset: CGFloat = 8.0
|
||||||
|
|
||||||
|
let (textSize, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: buttonFont, textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, width - labelInset * 2.0 - iconWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let (_, highlightedTextApply) = makeHighlightedTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: buttonFont, textColor: highlightedTitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, width - labelInset * 2.0), height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
return (textSize.size.width + labelInset * 2.0, { refinedWidth in
|
||||||
|
return (CGSize(width: refinedWidth, height: 33.0), {
|
||||||
|
targetNode.accessibilityLabel = title
|
||||||
|
|
||||||
|
targetNode.titleColor = titleColor
|
||||||
|
|
||||||
|
if let updatedRegularImage = updatedRegularImage {
|
||||||
|
targetNode.regularImage = updatedRegularImage
|
||||||
|
if !targetNode.textNode.isHidden {
|
||||||
|
targetNode.backgroundNode.image = updatedRegularImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let updatedHighlightedImage = updatedHighlightedImage {
|
||||||
|
targetNode.highlightedImage = updatedHighlightedImage
|
||||||
|
if targetNode.textNode.isHidden {
|
||||||
|
targetNode.backgroundNode.image = updatedHighlightedImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let updatedRegularIconImage = updatedRegularIconImage {
|
||||||
|
targetNode.regularIconImage = updatedRegularIconImage
|
||||||
|
if !targetNode.textNode.isHidden {
|
||||||
|
targetNode.iconNode.image = updatedRegularIconImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let updatedHighlightedIconImage = updatedHighlightedIconImage {
|
||||||
|
targetNode.highlightedIconImage = updatedHighlightedIconImage
|
||||||
|
if targetNode.iconNode.isHidden {
|
||||||
|
targetNode.iconNode.image = updatedHighlightedIconImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = textApply()
|
||||||
|
let _ = highlightedTextApply()
|
||||||
|
|
||||||
|
let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: refinedWidth, height: 33.0))
|
||||||
|
var textFrame = CGRect(origin: CGPoint(x: floor((refinedWidth - textSize.size.width) / 2.0), y: floor((34.0 - textSize.size.height) / 2.0)), size: textSize.size)
|
||||||
|
targetNode.backgroundNode.frame = backgroundFrame
|
||||||
|
if let image = targetNode.iconNode.image {
|
||||||
|
if cornerIcon {
|
||||||
|
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: backgroundFrame.maxX - image.size.width - 5.0, y: 5.0), size: image.size)
|
||||||
|
} else {
|
||||||
|
textFrame.origin.x += floor(image.size.width / 2.0)
|
||||||
|
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: textFrame.minX - image.size.width - 5.0, y: textFrame.minY + 2.0), size: image.size)
|
||||||
|
}
|
||||||
|
if targetNode.iconNode.supernode == nil {
|
||||||
|
targetNode.addSubnode(targetNode.iconNode)
|
||||||
|
}
|
||||||
|
} else if targetNode.iconNode.supernode != nil {
|
||||||
|
targetNode.iconNode.removeFromSupernode()
|
||||||
|
}
|
||||||
|
|
||||||
|
targetNode.textNode.frame = textFrame
|
||||||
|
targetNode.highlightedTextNode.frame = targetNode.textNode.frame
|
||||||
|
|
||||||
|
return targetNode
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "ChatMessageAttachedContentNode",
|
||||||
|
module_name = "ChatMessageAttachedContentNode",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/Postbox",
|
||||||
|
"//submodules/Display",
|
||||||
|
"//submodules/AsyncDisplayKit",
|
||||||
|
"//submodules/SSignalKit/SwiftSignalKit",
|
||||||
|
"//submodules/TelegramCore",
|
||||||
|
"//submodules/TelegramPresentationData",
|
||||||
|
"//submodules/TelegramUIPreferences",
|
||||||
|
"//submodules/TextFormat",
|
||||||
|
"//submodules/AccountContext",
|
||||||
|
"//submodules/UrlEscaping",
|
||||||
|
"//submodules/PhotoResources",
|
||||||
|
"//submodules/WebsiteType",
|
||||||
|
"//submodules/ChatMessageInteractiveMediaBadge",
|
||||||
|
"//submodules/GalleryData",
|
||||||
|
"//submodules/TelegramUI/Components/TextNodeWithEntities",
|
||||||
|
"//submodules/TelegramUI/Components/AnimationCache",
|
||||||
|
"//submodules/TelegramUI/Components/MultiAnimationRenderer",
|
||||||
|
"//submodules/TelegramUI/Components/ChatControllerInteraction",
|
||||||
|
"//submodules/ShimmerEffect",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatHistoryEntry",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveInstantVideoNode",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode",
|
||||||
|
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentButtonNode",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -27,254 +27,31 @@ import ChatMessageInteractiveInstantVideoNode
|
|||||||
import ChatMessageInteractiveFileNode
|
import ChatMessageInteractiveFileNode
|
||||||
import ChatMessageInteractiveMediaNode
|
import ChatMessageInteractiveMediaNode
|
||||||
import WallpaperPreviewMedia
|
import WallpaperPreviewMedia
|
||||||
|
import ChatMessageAttachedContentButtonNode
|
||||||
|
|
||||||
private let buttonFont = Font.semibold(13.0)
|
public enum ChatMessageAttachedContentActionIcon {
|
||||||
|
|
||||||
enum ChatMessageAttachedContentActionIcon {
|
|
||||||
case instant
|
case instant
|
||||||
case link
|
case link
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ChatMessageAttachedContentNodeMediaFlags: OptionSet {
|
public struct ChatMessageAttachedContentNodeMediaFlags: OptionSet {
|
||||||
var rawValue: Int32
|
public var rawValue: Int32
|
||||||
|
|
||||||
init(rawValue: Int32) {
|
public init(rawValue: Int32) {
|
||||||
self.rawValue = rawValue
|
self.rawValue = rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
public init() {
|
||||||
self.rawValue = 0
|
self.rawValue = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
static let preferMediaInline = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 0)
|
public static let preferMediaInline = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 0)
|
||||||
static let preferMediaBeforeText = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 1)
|
public static let preferMediaBeforeText = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 1)
|
||||||
static let preferMediaAspectFilled = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 2)
|
public static let preferMediaAspectFilled = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 2)
|
||||||
static let titleBeforeMedia = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 3)
|
public static let titleBeforeMedia = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
|
public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||||
private let textNode: TextNode
|
|
||||||
private let iconNode: ASImageNode
|
|
||||||
private let highlightedTextNode: TextNode
|
|
||||||
private let backgroundNode: ASImageNode
|
|
||||||
private let shimmerEffectNode: ShimmerEffectForegroundNode
|
|
||||||
|
|
||||||
private var regularImage: UIImage?
|
|
||||||
private var highlightedImage: UIImage?
|
|
||||||
private var regularIconImage: UIImage?
|
|
||||||
private var highlightedIconImage: UIImage?
|
|
||||||
|
|
||||||
var pressed: (() -> Void)?
|
|
||||||
|
|
||||||
private var titleColor: UIColor?
|
|
||||||
|
|
||||||
init() {
|
|
||||||
self.textNode = TextNode()
|
|
||||||
self.textNode.isUserInteractionEnabled = false
|
|
||||||
self.highlightedTextNode = TextNode()
|
|
||||||
self.highlightedTextNode.isUserInteractionEnabled = false
|
|
||||||
|
|
||||||
self.shimmerEffectNode = ShimmerEffectForegroundNode()
|
|
||||||
self.shimmerEffectNode.cornerRadius = 5.0
|
|
||||||
|
|
||||||
self.backgroundNode = ASImageNode()
|
|
||||||
self.backgroundNode.isLayerBacked = true
|
|
||||||
self.backgroundNode.displayWithoutProcessing = true
|
|
||||||
self.backgroundNode.displaysAsynchronously = false
|
|
||||||
|
|
||||||
self.iconNode = ASImageNode()
|
|
||||||
self.iconNode.isLayerBacked = true
|
|
||||||
self.iconNode.displayWithoutProcessing = true
|
|
||||||
self.iconNode.displaysAsynchronously = false
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
self.addSubnode(self.shimmerEffectNode)
|
|
||||||
self.addSubnode(self.backgroundNode)
|
|
||||||
self.addSubnode(self.textNode)
|
|
||||||
self.addSubnode(self.highlightedTextNode)
|
|
||||||
self.highlightedTextNode.isHidden = true
|
|
||||||
|
|
||||||
self.highligthedChanged = { [weak self] highlighted in
|
|
||||||
if let strongSelf = self {
|
|
||||||
if highlighted {
|
|
||||||
strongSelf.backgroundNode.image = strongSelf.highlightedImage
|
|
||||||
strongSelf.iconNode.image = strongSelf.highlightedIconImage
|
|
||||||
strongSelf.textNode.isHidden = true
|
|
||||||
strongSelf.highlightedTextNode.isHidden = false
|
|
||||||
|
|
||||||
let scale = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
|
||||||
strongSelf.layer.animateScale(from: 1.0, to: scale, duration: 0.15, removeOnCompletion: false)
|
|
||||||
} else {
|
|
||||||
if let presentationLayer = strongSelf.layer.presentation() {
|
|
||||||
strongSelf.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
|
|
||||||
}
|
|
||||||
if let snapshot = strongSelf.view.snapshotView(afterScreenUpdates: false) {
|
|
||||||
strongSelf.view.addSubview(snapshot)
|
|
||||||
|
|
||||||
snapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
|
||||||
snapshot.removeFromSuperview()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
strongSelf.backgroundNode.image = strongSelf.regularImage
|
|
||||||
strongSelf.iconNode.image = strongSelf.regularIconImage
|
|
||||||
strongSelf.textNode.isHidden = false
|
|
||||||
strongSelf.highlightedTextNode.isHidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func buttonPressed() {
|
|
||||||
self.pressed?()
|
|
||||||
}
|
|
||||||
|
|
||||||
func startShimmering() {
|
|
||||||
guard let titleColor = self.titleColor else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.shimmerEffectNode.isHidden = false
|
|
||||||
self.shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
|
||||||
|
|
||||||
let backgroundFrame = self.backgroundNode.frame
|
|
||||||
self.shimmerEffectNode.frame = backgroundFrame
|
|
||||||
self.shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
|
|
||||||
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: titleColor.withAlphaComponent(0.3), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopShimmering() {
|
|
||||||
self.shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
|
||||||
self?.shimmerEffectNode.isHidden = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static func asyncLayout(_ current: ChatMessageAttachedContentButtonNode?) -> (_ width: CGFloat, _ regularImage: UIImage, _ highlightedImage: UIImage, _ iconImage: UIImage?, _ highlightedIconImage: UIImage?, _ cornerIcon: Bool, _ title: String, _ titleColor: UIColor, _ highlightedTitleColor: UIColor, _ inProgress: Bool) -> (CGFloat, (CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode)) {
|
|
||||||
let previousRegularImage = current?.regularImage
|
|
||||||
let previousHighlightedImage = current?.highlightedImage
|
|
||||||
let previousRegularIconImage = current?.regularIconImage
|
|
||||||
let previousHighlightedIconImage = current?.highlightedIconImage
|
|
||||||
|
|
||||||
let maybeMakeTextLayout = (current?.textNode).flatMap(TextNode.asyncLayout)
|
|
||||||
let maybeMakeHighlightedTextLayout = (current?.highlightedTextNode).flatMap(TextNode.asyncLayout)
|
|
||||||
|
|
||||||
return { width, regularImage, highlightedImage, iconImage, highlightedIconImage, cornerIcon, title, titleColor, highlightedTitleColor, inProgress in
|
|
||||||
let targetNode: ChatMessageAttachedContentButtonNode
|
|
||||||
if let current = current {
|
|
||||||
targetNode = current
|
|
||||||
} else {
|
|
||||||
targetNode = ChatMessageAttachedContentButtonNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
let makeTextLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)
|
|
||||||
if let maybeMakeTextLayout = maybeMakeTextLayout {
|
|
||||||
makeTextLayout = maybeMakeTextLayout
|
|
||||||
} else {
|
|
||||||
makeTextLayout = TextNode.asyncLayout(targetNode.textNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
let makeHighlightedTextLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)
|
|
||||||
if let maybeMakeHighlightedTextLayout = maybeMakeHighlightedTextLayout {
|
|
||||||
makeHighlightedTextLayout = maybeMakeHighlightedTextLayout
|
|
||||||
} else {
|
|
||||||
makeHighlightedTextLayout = TextNode.asyncLayout(targetNode.highlightedTextNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
var updatedRegularImage: UIImage?
|
|
||||||
if regularImage !== previousRegularImage {
|
|
||||||
updatedRegularImage = regularImage
|
|
||||||
}
|
|
||||||
|
|
||||||
var updatedHighlightedImage: UIImage?
|
|
||||||
if highlightedImage !== previousHighlightedImage {
|
|
||||||
updatedHighlightedImage = highlightedImage
|
|
||||||
}
|
|
||||||
|
|
||||||
var updatedRegularIconImage: UIImage?
|
|
||||||
if iconImage !== previousRegularIconImage {
|
|
||||||
updatedRegularIconImage = iconImage
|
|
||||||
}
|
|
||||||
|
|
||||||
var updatedHighlightedIconImage: UIImage?
|
|
||||||
if highlightedIconImage !== previousHighlightedIconImage {
|
|
||||||
updatedHighlightedIconImage = highlightedIconImage
|
|
||||||
}
|
|
||||||
|
|
||||||
var iconWidth: CGFloat = 0.0
|
|
||||||
if let iconImage = iconImage {
|
|
||||||
iconWidth = iconImage.size.width + 5.0
|
|
||||||
}
|
|
||||||
|
|
||||||
let labelInset: CGFloat = 8.0
|
|
||||||
|
|
||||||
let (textSize, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: buttonFont, textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, width - labelInset * 2.0 - iconWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets()))
|
|
||||||
|
|
||||||
let (_, highlightedTextApply) = makeHighlightedTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: buttonFont, textColor: highlightedTitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, width - labelInset * 2.0), height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets()))
|
|
||||||
|
|
||||||
return (textSize.size.width + labelInset * 2.0, { refinedWidth in
|
|
||||||
return (CGSize(width: refinedWidth, height: 33.0), {
|
|
||||||
targetNode.accessibilityLabel = title
|
|
||||||
|
|
||||||
targetNode.titleColor = titleColor
|
|
||||||
|
|
||||||
if let updatedRegularImage = updatedRegularImage {
|
|
||||||
targetNode.regularImage = updatedRegularImage
|
|
||||||
if !targetNode.textNode.isHidden {
|
|
||||||
targetNode.backgroundNode.image = updatedRegularImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let updatedHighlightedImage = updatedHighlightedImage {
|
|
||||||
targetNode.highlightedImage = updatedHighlightedImage
|
|
||||||
if targetNode.textNode.isHidden {
|
|
||||||
targetNode.backgroundNode.image = updatedHighlightedImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let updatedRegularIconImage = updatedRegularIconImage {
|
|
||||||
targetNode.regularIconImage = updatedRegularIconImage
|
|
||||||
if !targetNode.textNode.isHidden {
|
|
||||||
targetNode.iconNode.image = updatedRegularIconImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let updatedHighlightedIconImage = updatedHighlightedIconImage {
|
|
||||||
targetNode.highlightedIconImage = updatedHighlightedIconImage
|
|
||||||
if targetNode.iconNode.isHidden {
|
|
||||||
targetNode.iconNode.image = updatedHighlightedIconImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = textApply()
|
|
||||||
let _ = highlightedTextApply()
|
|
||||||
|
|
||||||
let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: refinedWidth, height: 33.0))
|
|
||||||
var textFrame = CGRect(origin: CGPoint(x: floor((refinedWidth - textSize.size.width) / 2.0), y: floor((34.0 - textSize.size.height) / 2.0)), size: textSize.size)
|
|
||||||
targetNode.backgroundNode.frame = backgroundFrame
|
|
||||||
if let image = targetNode.iconNode.image {
|
|
||||||
if cornerIcon {
|
|
||||||
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: backgroundFrame.maxX - image.size.width - 5.0, y: 5.0), size: image.size)
|
|
||||||
} else {
|
|
||||||
textFrame.origin.x += floor(image.size.width / 2.0)
|
|
||||||
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: textFrame.minX - image.size.width - 5.0, y: textFrame.minY + 2.0), size: image.size)
|
|
||||||
}
|
|
||||||
if targetNode.iconNode.supernode == nil {
|
|
||||||
targetNode.addSubnode(targetNode.iconNode)
|
|
||||||
}
|
|
||||||
} else if targetNode.iconNode.supernode != nil {
|
|
||||||
targetNode.iconNode.removeFromSupernode()
|
|
||||||
}
|
|
||||||
|
|
||||||
targetNode.textNode.frame = textFrame
|
|
||||||
targetNode.highlightedTextNode.frame = targetNode.textNode.frame
|
|
||||||
|
|
||||||
return targetNode
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|
||||||
private var backgroundView: UIImageView?
|
private var backgroundView: UIImageView?
|
||||||
private let topTitleNode: TextNode
|
private let topTitleNode: TextNode
|
||||||
private let textNode: TextNodeWithEntities
|
private let textNode: TextNodeWithEntities
|
||||||
@@ -284,7 +61,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
private var contentFileNode: ChatMessageInteractiveFileNode?
|
private var contentFileNode: ChatMessageInteractiveFileNode?
|
||||||
private var buttonNode: ChatMessageAttachedContentButtonNode?
|
private var buttonNode: ChatMessageAttachedContentButtonNode?
|
||||||
|
|
||||||
let statusNode: ChatMessageDateAndStatusNode
|
public let statusNode: ChatMessageDateAndStatusNode
|
||||||
private var additionalImageBadgeNode: ChatMessageInteractiveMediaBadge?
|
private var additionalImageBadgeNode: ChatMessageInteractiveMediaBadge?
|
||||||
private var linkHighlightingNode: LinkHighlightingNode?
|
private var linkHighlightingNode: LinkHighlightingNode?
|
||||||
|
|
||||||
@@ -293,11 +70,11 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
private var media: Media?
|
private var media: Media?
|
||||||
private var theme: ChatPresentationThemeData?
|
private var theme: ChatPresentationThemeData?
|
||||||
|
|
||||||
var openMedia: ((InteractiveMediaNodeActivateContent) -> Void)?
|
public var openMedia: ((InteractiveMediaNodeActivateContent) -> Void)?
|
||||||
var activateAction: (() -> Void)?
|
public var activateAction: (() -> Void)?
|
||||||
var requestUpdateLayout: (() -> Void)?
|
public var requestUpdateLayout: (() -> Void)?
|
||||||
|
|
||||||
var visibility: ListViewItemNodeVisibility = .none {
|
public var visibility: ListViewItemNodeVisibility = .none {
|
||||||
didSet {
|
didSet {
|
||||||
if oldValue != self.visibility {
|
if oldValue != self.visibility {
|
||||||
self.contentImageNode?.visibility = self.visibility != .none
|
self.contentImageNode?.visibility = self.visibility != .none
|
||||||
@@ -316,7 +93,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override init() {
|
override public init() {
|
||||||
self.topTitleNode = TextNode()
|
self.topTitleNode = TextNode()
|
||||||
self.topTitleNode.isUserInteractionEnabled = false
|
self.topTitleNode.isUserInteractionEnabled = false
|
||||||
self.topTitleNode.displaysAsynchronously = false
|
self.topTitleNode.displaysAsynchronously = false
|
||||||
@@ -344,7 +121,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.statusNode)
|
self.addSubnode(self.statusNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ context: AccountContext, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ chatLocation: ChatLocation, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ constrainedSize: CGSize, _ animationCache: AnimationCache, _ animationRenderer: MultiAnimationRenderer) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
|
public func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ context: AccountContext, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ chatLocation: ChatLocation, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ constrainedSize: CGSize, _ animationCache: AnimationCache, _ animationRenderer: MultiAnimationRenderer) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
|
||||||
let topTitleAsyncLayout = TextNode.asyncLayout(self.topTitleNode)
|
let topTitleAsyncLayout = TextNode.asyncLayout(self.topTitleNode)
|
||||||
let textAsyncLayout = TextNodeWithEntities.asyncLayout(self.textNode)
|
let textAsyncLayout = TextNodeWithEntities.asyncLayout(self.textNode)
|
||||||
let currentImage = self.media as? TelegramMediaImage
|
let currentImage = self.media as? TelegramMediaImage
|
||||||
@@ -1248,7 +1025,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateHiddenMedia(_ media: [Media]?) -> Bool {
|
public func updateHiddenMedia(_ media: [Media]?) -> Bool {
|
||||||
if let currentMedia = self.media {
|
if let currentMedia = self.media {
|
||||||
if let media = media {
|
if let media = media {
|
||||||
var found = false
|
var found = false
|
||||||
@@ -1271,7 +1048,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func transitionNode(media: Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
public func transitionNode(media: Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
||||||
if let contentImageNode = self.contentImageNode, let image = self.media as? TelegramMediaImage, image.isEqual(to: media) {
|
if let contentImageNode = self.contentImageNode, let image = self.media as? TelegramMediaImage, image.isEqual(to: media) {
|
||||||
return (contentImageNode, contentImageNode.bounds, { [weak contentImageNode] in
|
return (contentImageNode, contentImageNode.bounds, { [weak contentImageNode] in
|
||||||
return (contentImageNode?.view.snapshotContentTree(unhide: true), nil)
|
return (contentImageNode?.view.snapshotContentTree(unhide: true), nil)
|
||||||
@@ -1288,14 +1065,14 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasActionAtPoint(_ point: CGPoint) -> Bool {
|
public func hasActionAtPoint(_ point: CGPoint) -> Bool {
|
||||||
if let buttonNode = self.buttonNode, buttonNode.frame.contains(point) {
|
if let buttonNode = self.buttonNode, buttonNode.frame.contains(point) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
|
public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
|
||||||
let textNodeFrame = self.textNode.textNode.frame
|
let textNodeFrame = self.textNode.textNode.frame
|
||||||
if let (index, attributes) = self.textNode.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) {
|
if let (index, attributes) = self.textNode.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) {
|
||||||
if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String {
|
if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String {
|
||||||
@@ -1320,7 +1097,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTouchesAtPoint(_ point: CGPoint?) {
|
public func updateTouchesAtPoint(_ point: CGPoint?) {
|
||||||
if let context = self.context, let message = self.message, let theme = self.theme {
|
if let context = self.context, let message = self.message, let theme = self.theme {
|
||||||
var rects: [CGRect]?
|
var rects: [CGRect]?
|
||||||
if let point = point {
|
if let point = point {
|
||||||
@@ -1363,7 +1140,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reactionTargetView(value: MessageReaction.Reaction) -> UIView? {
|
public func reactionTargetView(value: MessageReaction.Reaction) -> UIView? {
|
||||||
if !self.statusNode.isHidden {
|
if !self.statusNode.isHidden {
|
||||||
if let result = self.statusNode.reactionView(value: value) {
|
if let result = self.statusNode.reactionView(value: value) {
|
||||||
return result
|
return result
|
||||||
@@ -1381,7 +1158,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? {
|
public func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? {
|
||||||
return self.contentImageNode?.playMediaWithSound()
|
return self.contentImageNode?.playMediaWithSound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ import PhoneNumberFormat
|
|||||||
import ChatMessageDateAndStatusNode
|
import ChatMessageDateAndStatusNode
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentButtonNode
|
||||||
|
|
||||||
private let avatarFont = avatarPlaceholderFont(size: 16.0)
|
private let avatarFont = avatarPlaceholderFont(size: 16.0)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessageBubbleContentNode {
|
final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessageBubbleContentNode {
|
||||||
private let contentNode: ChatMessageAttachedContentNode
|
private let contentNode: ChatMessageAttachedContentNode
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubbleContentNode {
|
final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubbleContentNode {
|
||||||
private let contentNode: ChatMessageAttachedContentNode
|
private let contentNode: ChatMessageAttachedContentNode
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBubbleContentNode {
|
final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBubbleContentNode {
|
||||||
private let contentNode: ChatMessageAttachedContentNode
|
private let contentNode: ChatMessageAttachedContentNode
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNode {
|
final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNode {
|
||||||
private var game: TelegramMediaGame?
|
private var game: TelegramMediaGame?
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import AvatarNode
|
|||||||
import ChatMessageDateAndStatusNode
|
import ChatMessageDateAndStatusNode
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentButtonNode
|
||||||
|
|
||||||
private let titleFont = Font.medium(15.0)
|
private let titleFont = Font.medium(15.0)
|
||||||
private let textFont = Font.regular(13.0)
|
private let textFont = Font.regular(13.0)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import TelegramUIPreferences
|
|||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
private let titleFont: UIFont = Font.semibold(15.0)
|
private let titleFont: UIFont = Font.semibold(15.0)
|
||||||
private let textFont: UIFont = Font.regular(15.0)
|
private let textFont: UIFont = Font.regular(15.0)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import TelegramCore
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import ChatMessageBubbleContentNode
|
import ChatMessageBubbleContentNode
|
||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
|
import ChatMessageAttachedContentButtonNode
|
||||||
|
|
||||||
final class ChatMessageUnsupportedBubbleContentNode: ChatMessageBubbleContentNode {
|
final class ChatMessageUnsupportedBubbleContentNode: ChatMessageBubbleContentNode {
|
||||||
private var buttonNode: ChatMessageAttachedContentButtonNode
|
private var buttonNode: ChatMessageAttachedContentButtonNode
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import ChatMessageBubbleContentNode
|
|||||||
import ChatMessageItemCommon
|
import ChatMessageItemCommon
|
||||||
import WallpaperPreviewMedia
|
import WallpaperPreviewMedia
|
||||||
import ChatMessageInteractiveMediaNode
|
import ChatMessageInteractiveMediaNode
|
||||||
|
import ChatMessageAttachedContentNode
|
||||||
|
|
||||||
private let titleFont: UIFont = Font.semibold(15.0)
|
private let titleFont: UIFont = Font.semibold(15.0)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user